Files
ApiCore/ApiCore-Frontend/src/components/voice/voice-entry-link.tsx
T
Nick SzaunigandClaude Opus 5.5 e0be687b7c feat: Aufnahmeseite und Liste der Sprachnotizen (T7 L5 Task 19)
/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]>
2026-10-16 11:49:56 +02:00

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>
);
}