ultisuite-client/components/compte/sections/compte-security-section.tsx
R3D347HR4Y 3bbf3691b0
Some checks failed
E2E / Playwright e2e (push) Has been cancelled
bordel c'est beau
2026-06-11 10:10:39 +02:00

115 lines
3.3 KiB
TypeScript

"use client"
import { ExternalLink, KeyRound, LogOut, Smartphone } from "lucide-react"
import { SettingsSectionHeader } from "@/components/gmail/settings/settings-section-header"
import { Button } from "@/components/ui/button"
import { useAuthLogout } from "@/components/auth/auth-provider"
import { authentikUserSettingsUrl } from "@/lib/auth/authentik-user-url"
export function CompteSecuritySection() {
const signOut = useAuthLogout()
const idpUrl = authentikUserSettingsUrl()
return (
<>
<SettingsSectionHeader
title="Sécurité"
description="Paramètres de connexion et de protection de votre compte Ulti."
/>
<div className="space-y-4">
<SecurityCard
icon={<KeyRound className="size-5" aria-hidden />}
title="Mot de passe"
description="Modifiez votre mot de passe depuis le portail d'identité de votre organisation."
action={
idpUrl ? (
<ExternalAction href={idpUrl} label="Changer le mot de passe" />
) : (
<UnavailableNote />
)
}
/>
<SecurityCard
icon={<Smartphone className="size-5" aria-hidden />}
title="Validation en deux étapes"
description="Ajoutez ou gérez vos appareils de validation (application TOTP, WebAuthn, clés de sécurité)."
action={
idpUrl ? (
<ExternalAction href={idpUrl} label="Gérer la validation" />
) : (
<UnavailableNote />
)
}
/>
<SecurityCard
icon={<LogOut className="size-5" aria-hidden />}
title="Session sur cet appareil"
description="Met fin à votre session Ulti sur ce navigateur. Vous devrez vous reconnecter."
action={
<Button
type="button"
variant="outline"
className="h-9 rounded-full px-4 text-sm font-medium"
onClick={() => void signOut()}
>
Se déconnecter
</Button>
}
/>
</div>
</>
)
}
function SecurityCard({
icon,
title,
description,
action,
}: {
icon: React.ReactNode
title: string
description: string
action: React.ReactNode
}) {
return (
<div className="flex flex-col gap-3 rounded-2xl border border-border bg-background p-5 sm:flex-row sm:items-center sm:gap-4">
<span className="flex size-10 shrink-0 items-center justify-center rounded-full bg-accent text-muted-foreground">
{icon}
</span>
<div className="min-w-0 flex-1">
<h3 className="text-sm font-medium text-foreground">{title}</h3>
<p className="mt-0.5 text-sm text-muted-foreground">{description}</p>
</div>
<div className="shrink-0">{action}</div>
</div>
)
}
function ExternalAction({ href, label }: { href: string; label: string }) {
return (
<Button
type="button"
variant="outline"
className="h-9 rounded-full px-4 text-sm font-medium"
asChild
>
<a href={href} target="_blank" rel="noreferrer">
{label}
<ExternalLink className="size-3.5" aria-hidden />
</a>
</Button>
)
}
function UnavailableNote() {
return (
<span className="text-xs text-muted-foreground">
Portail d&apos;identité non configuré
</span>
)
}