ultisuite-client/components/landing/product/product-demos/admin-policies-demo.tsx
R3D347HR4Y efaaf16f60
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: update metadata and layout for new product pages
- Refactored metadata for contacts, administration, and Ulticards pages to utilize dynamic app names and descriptions.
- Introduced new product pages for Ultiai, Ultical, Ulticards, Ultidrive, Ultimail, and Ultimeet with appropriate metadata.
- Enhanced layout components to ensure consistent styling and functionality across new product sections.
- Updated various components to replace hardcoded labels with dynamic references to improve maintainability and consistency.
2026-06-19 22:11:42 +02:00

87 lines
3.8 KiB
TypeScript

"use client"
import { Icon } from "@iconify/react"
const ACCENT = "#7C3AED"
type Policy = {
label: string
icon: string
enabled: boolean
}
const POLICIES: Policy[] = [
{ label: "2FA obligatoire (admins)", icon: "mdi:cellphone-key", enabled: true },
{ label: "Clés de sécurité WebAuthn", icon: "mdi:key-chain-variant", enabled: true },
{ label: "Partage externe restreint", icon: "mdi:link-lock", enabled: true },
{ label: "Analyse antivirus à l'upload", icon: "mdi:shield-bug-outline", enabled: true },
{ label: "Rétention corbeille 30 j", icon: "mdi:delete-clock-outline", enabled: false },
]
const AUDIT = [
{ actor: "alice@acme.com", action: "user.role.update", icon: "mdi:account-edit-outline" },
{ actor: "system", action: "migration.cutover", icon: "mdi:swap-horizontal" },
{ actor: "bob@acme.com", action: "share.link.create", icon: "mdi:link-variant" },
]
/** Aperçu statique des politiques de sécurité et du journal d'audit. */
export function AdminPoliciesDemo() {
return (
<div className="flex flex-col gap-3">
<div className="landing-glass-strong overflow-hidden rounded-2xl shadow-[0_32px_70px_-36px_rgba(30,40,90,0.45)]">
<div className="flex items-center gap-2.5 border-b border-[var(--landing-line)] px-4 py-3">
<Icon icon="mdi:shield-lock-outline" className="size-5" style={{ color: ACCENT }} aria-hidden />
<span className="text-sm font-semibold tracking-tight">Politiques de sécurité</span>
</div>
<ul className="divide-y divide-[var(--landing-line)]">
{POLICIES.map((p) => (
<li key={p.label} className="flex items-center gap-3 px-4 py-2.5">
<span
className="flex size-8 shrink-0 items-center justify-center rounded-lg"
style={{
backgroundColor: p.enabled ? `${ACCENT}1f` : "var(--landing-chip)",
color: p.enabled ? ACCENT : "var(--landing-muted)",
}}
>
<Icon icon={p.icon} className="size-4" aria-hidden />
</span>
<span className="min-w-0 flex-1 truncate text-sm font-medium text-[var(--landing-fg)]">
{p.label}
</span>
<Icon
icon={p.enabled ? "mdi:toggle-switch" : "mdi:toggle-switch-off-outline"}
className="size-6 shrink-0"
style={{ color: p.enabled ? ACCENT : "var(--landing-muted)" }}
aria-hidden
/>
</li>
))}
</ul>
<div className="border-t border-[var(--landing-line)] bg-[var(--landing-bg)]/60 p-4">
<p className="mb-2.5 flex items-center gap-1.5 text-[11px] font-medium uppercase tracking-wide text-[var(--landing-muted)]">
<Icon icon="mdi:clipboard-text-clock-outline" className="size-3.5" aria-hidden />
Journal d&apos;audit
</p>
<ul className="flex flex-col gap-1.5">
{AUDIT.map((a, i) => (
<li key={i} className="flex items-center gap-2.5 text-sm">
<Icon icon={a.icon} className="size-4 shrink-0 text-[var(--landing-muted)]" aria-hidden />
<code className="font-mono text-[13px] font-medium text-[var(--landing-fg)]">{a.action}</code>
<span className="ml-auto truncate font-mono text-[11px] text-[var(--landing-muted)]">
{a.actor}
</span>
</li>
))}
</ul>
</div>
</div>
<p className="flex items-start gap-2 text-sm text-[var(--landing-muted)]">
<Icon icon="mdi:incognito" className="mt-0.5 size-4 shrink-0" aria-hidden />
Aperçu statique 2FA, politiques fichiers et journal d&apos;audit exportable (CSV/NDJSON).
</p>
</div>
)
}