Files
tessera-ctl/apps/web/src/components/bug-report/bug-report-button.tsx
T
schalli b80db49c5e style(web): dunkle App-Leiste und Fluent-Seitenleiste
Kopfzeile 48 px dunkel mit Seitentitel statt immer Startseite,
Dashboard-Reiter mit Akzent-Unterstrich; Seitenleiste mit
Auswahlpille, Modul-Kacheln, aufgeklappten Kategorien und gefuelltem
Suchfeld; eingeklappt nur Kacheln. Einheitlicher PageHeader.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 14:32:37 +02:00

77 lines
2.9 KiB
TypeScript

'use client';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { captureScreenshot } from '@/lib/bug-report-api';
import { useAuthStore } from '@/lib/stores/auth-store';
import { BugReportDialog } from './bug-report-dialog';
/**
* Fehler-melden-Knopf in der Kopfzeile (quick-260914-m97), Stil wie
* `ThemeToggle`. Kernanforderung: das Bild der Seite wird aufgenommen,
* BEVOR der Dialog erscheint — sonst waere der Dialog im Bild.
*/
export function BugReportButton() {
const t = useTranslations('bugReport');
const user = useAuthStore((s) => s.user);
const isAdmin = user?.role === 'ADMIN' || user?.role === 'SUPER_ADMIN';
const [capturing, setCapturing] = useState(false);
const [open, setOpen] = useState(false);
const [screenshot, setScreenshot] = useState<string | null>(null);
const handleClick = async () => {
if (capturing) return;
setCapturing(true);
// Reihenfolge ist die Kernanforderung: erst aufnehmen, dann oeffnen.
const shot = await captureScreenshot();
setScreenshot(shot);
setOpen(true);
setCapturing(false);
};
return (
<>
<button
type="button"
onClick={handleClick}
className="inline-flex h-8 w-8 items-center justify-center rounded-md text-appbar-muted hover:bg-appbar-hover hover:text-appbar-foreground transition-colors disabled:opacity-50 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-appbar-foreground"
aria-label={t('button')}
title={t('button')}
disabled={capturing}
data-bug-report-ignore="true"
>
{/* Kaefer-Symbol nach dem lucide-Symbol "bug" */}
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<path d="m8 2 1.88 1.88" />
<path d="M14.12 3.88 16 2" />
<path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" />
<path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" />
<path d="M12 20v-9" />
<path d="M6.53 9C4.6 8.8 3 7.1 3 5" />
<path d="M6 13H2" />
<path d="M3 21c0-2.1 1.7-3.9 3.8-4" />
<path d="M20.97 5c0 2.1-1.6 3.8-3.5 4" />
<path d="M22 13h-4" />
<path d="M17.2 17c2.1.1 3.8 1.9 3.8 4" />
</svg>
</button>
{/* Nur eingehaengt, solange offen (quick-260921-ldf): so startet jedes
Oeffnen mit frischem Zustand — Haekchen, Text und Status stimmen
schon im ersten Commit, statt einen Commit spaeter nachgezogen zu
werden. */}
{open && <BugReportDialog screenshot={screenshot} isAdmin={isAdmin} onClose={() => setOpen(false)} />}
</>
);
}