/voice/new: großer Aufnahmeknopf mit Zeit, Hinweis bei 150 s, Stopp bei 180 s; eine automatisch beendete Aufnahme liegt sofort in der Warteschlange des Geräts (Ruling 13); Abbrechen und Neu aufnehmen fragen nach; Hilfe bei gesperrtem Mikrofon; Fokus bleibt bei jedem Zustandswechsel an einem Bedienelement; Volk und Datum während der Aufnahme gesperrt, ?date= auf die letzten 7 Tage begrenzt. /voice: wartende Notizen des Geräts zuerst, dann die des Servers mit Status, „Prüfen“ nur bei fertigen, Verwerfen mit Rückfrage. Einstiege über Schnellanlage, Menü (nur mit voice-captures:use und inspections:create), Volksseite und Durchsicht. Bei ausgeschalteter Aufnahme verschwinden die Einstiege; jeder HTTP-Fehler der Konfiguration zählt als aus, nur fehlendes Netz als unbekannt. Fehlertexte gleich mit dem Backend (Test). Gates: Frontend lint, typecheck, 2979 Tests, build. Refs #27 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { Mic } from "lucide-react";
|
|
import { useAuth } from "@/lib/auth/auth-context";
|
|
import { offersRecording, useVoiceRecordingSwitch } from "@/lib/voice/use-voice-recording-switch";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
interface VoiceEntryLinkProps {
|
|
colonyId: string;
|
|
/** The stand round the note belongs to; keeps the round going afterwards. */
|
|
roundApiaryId?: string | null;
|
|
}
|
|
|
|
/**
|
|
* „Sprachnotiz aufnehmen“ next to „Durchsicht erfassen“. Not there without the
|
|
* rights or while the operator has recording switched off - no dead button.
|
|
*/
|
|
export function VoiceEntryLink({ colonyId, roundApiaryId }: VoiceEntryLinkProps) {
|
|
const { hasPermission } = useAuth();
|
|
const allowed = hasPermission("voice-captures:use") && hasPermission("inspections:create");
|
|
const recordingSwitch = useVoiceRecordingSwitch(allowed);
|
|
if (!allowed || !offersRecording(recordingSwitch)) {
|
|
return null;
|
|
}
|
|
const params = new URLSearchParams({ colonyId });
|
|
if (roundApiaryId) {
|
|
params.set("round", roundApiaryId);
|
|
}
|
|
return (
|
|
<Button
|
|
size="touch"
|
|
variant="outline"
|
|
className="min-h-14"
|
|
nativeButton={false}
|
|
render={<Link href={`/voice/new?${params.toString()}`} />}
|
|
>
|
|
<Mic aria-hidden />
|
|
Sprachnotiz aufnehmen
|
|
</Button>
|
|
);
|
|
}
|