Initialize repo and add session changes (2025-09-08)
This commit is contained in:
89
resources/js/guest/components/Header.tsx
Normal file
89
resources/js/guest/components/Header.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';
|
||||
import AppearanceToggleDropdown from '@/components/appearance-dropdown';
|
||||
import { Settings } from 'lucide-react';
|
||||
|
||||
export default function Header({ title = '' }: { title?: string }) {
|
||||
return (
|
||||
<div className="sticky top-0 z-20 flex items-center justify-between border-b bg-white/70 px-4 py-2 backdrop-blur dark:bg-black/40">
|
||||
<div className="font-semibold">{title}</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<AppearanceToggleDropdown />
|
||||
<SettingsSheet />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsSheet() {
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="h-9 w-9 rounded-md">
|
||||
<Settings className="h-5 w-5" />
|
||||
<span className="sr-only">Einstellungen öffnen</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right" className="w-80 sm:w-96">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Einstellungen</SheetTitle>
|
||||
</SheetHeader>
|
||||
<div className="mt-4 space-y-4">
|
||||
<div>
|
||||
<div className="text-sm font-medium">Darstellung</div>
|
||||
<div className="text-sm text-muted-foreground">Hell, Dunkel oder System</div>
|
||||
<div className="mt-2">
|
||||
<AppearanceToggleDropdown />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm font-medium">Cache</div>
|
||||
<ClearCacheButton />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm font-medium">Rechtliches</div>
|
||||
<ul className="mt-2 list-disc pl-5 text-sm">
|
||||
<li><a href="/legal/imprint" className="underline">Impressum</a></li>
|
||||
<li><a href="/legal/privacy" className="underline">Datenschutz</a></li>
|
||||
<li><a href="/legal/terms" className="underline">AGB</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
|
||||
function ClearCacheButton() {
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const [done, setDone] = React.useState(false);
|
||||
|
||||
async function clearAll() {
|
||||
setBusy(true); setDone(false);
|
||||
try {
|
||||
// Clear CacheStorage
|
||||
if ('caches' in window) {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(keys.map((k) => caches.delete(k)));
|
||||
}
|
||||
// Clear known IndexedDB dbs (best-effort)
|
||||
if ('indexedDB' in window) {
|
||||
try { await new Promise((res, rej) => { const r = indexedDB.deleteDatabase('upload-queue'); r.onsuccess=()=>res(null); r.onerror=()=>res(null); }); } catch {}
|
||||
}
|
||||
setDone(true);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
setTimeout(() => setDone(false), 2500);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-2">
|
||||
<Button variant="secondary" onClick={clearAll} disabled={busy}>
|
||||
{busy ? 'Leere Cache…' : 'Cache leeren'}
|
||||
</Button>
|
||||
{done && <div className="mt-2 text-xs text-muted-foreground">Cache gelöscht.</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user