nsfwapp/frontend/src/components/ui/login/PasskeyPanel.tsx
2026-05-11 19:13:54 +02:00

86 lines
2.7 KiB
TypeScript

// frontend\src\components\ui\login\PasskeyPanel.tsx
import Button from '../Button'
function passkeyUnsupportedReason() {
if (typeof window === 'undefined') {
return 'Passkeys sind in dieser Umgebung nicht verfügbar.'
}
if (!window.isSecureContext) {
return (
'Passkeys sind nur über HTTPS oder über localhost verfügbar. ' +
'Wenn du die App per IP öffnest, z. B. http://10.0.1.25:9999, blockiert der Browser Passkeys.'
)
}
if (typeof window.PublicKeyCredential === 'undefined') {
return 'Dein Browser unterstützt Passkeys/WebAuthn aktuell nicht.'
}
return 'Passkeys sind aktuell nicht verfügbar.'
}
export default function PasskeyPanel(props: {
supported: boolean
busy: boolean
mode: 'login' | 'register'
onLogin?: () => void
onRegister?: () => void
}) {
if (props.mode === 'login') {
return (
<div className="space-y-2">
<div className="relative flex items-center py-1">
<div className="h-px flex-1 bg-gray-200 dark:bg-white/10" />
<span className="px-3 text-xs text-gray-500 dark:text-gray-400">oder</span>
<div className="h-px flex-1 bg-gray-200 dark:bg-white/10" />
</div>
{props.supported ? (
<Button
type="button"
variant="secondary"
className="w-full rounded-lg"
disabled={props.busy}
onClick={props.onLogin}
>
Mit Passkey anmelden
</Button>
) : (
<div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200">
{passkeyUnsupportedReason()}
</div>
)}
</div>
)
}
return (
<div className="rounded-lg border border-gray-200 bg-white/70 p-3 dark:border-white/10 dark:bg-white/5">
<div className="text-sm font-semibold text-gray-900 dark:text-white">
Optional: Passkey hinzufügen
</div>
<div className="mt-1 text-xs leading-relaxed text-gray-600 dark:text-gray-300">
Danach kannst du dich mit Fingerabdruck, Face ID, Windows Hello oder einem Sicherheitsschlüssel anmelden.
</div>
{props.supported ? (
<Button
type="button"
variant="secondary"
className="mt-3 w-full rounded-lg"
disabled={props.busy}
onClick={props.onRegister}
>
Passkey hinzufügen
</Button>
) : (
<div className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200">
{passkeyUnsupportedReason()}
</div>
)}
</div>
)
}