"use client" import type { ReactNode } from "react" import { Label } from "@/components/ui/label" import { Switch } from "@/components/ui/switch" import { Checkbox } from "@/components/ui/checkbox" import { cn } from "@/lib/utils" /** * Settings UI kit — composants unifiés pour les interfaces de réglages * (/admin/* et /mail/settings). Centralise cards, champs, lignes à bascule, * grilles et hints afin d'homogénéiser typographies, paddings et alignements. */ /** Surface card commune (réglages admin + mail) — alignée sur la card mail. */ export const SETTINGS_CARD_SURFACE_CLASS = cn( "rounded-xl border border-mail-border bg-mail-surface shadow-sm", "dark:bg-mail-surface-elevated dark:shadow-[0_1px_4px_rgba(0,0,0,0.35)]", ) export const SETTINGS_CARD_TITLE_CLASS = "text-sm font-semibold text-foreground" export const SETTINGS_CARD_DESCRIPTION_CLASS = "text-[13px] leading-relaxed text-muted-foreground" export const SETTINGS_FIELD_LABEL_CLASS = "text-xs font-medium text-muted-foreground" /** Carte de réglages : en-tête (titre + description + action) puis corps. */ export function SettingsCard({ title, description, hint, action, badges, footer, children, className, bodyClassName, contentClassName, divider = true, }: { title?: ReactNode description?: ReactNode /** Élément aligné à droite de l'en-tête (Switch, bouton, badge…). */ action?: ReactNode /** Ligne d'indications/badges sous la description. */ badges?: ReactNode hint?: ReactNode footer?: ReactNode children?: ReactNode className?: string /** Classe sur le wrapper interne (padding). */ bodyClassName?: string /** Classe sur le conteneur du corps (children). */ contentClassName?: string /** Séparateur entre en-tête et corps. */ divider?: boolean }) { const hasHeader = Boolean(title || description || action || badges || hint) return (
{hasHeader ? (
{title ?

{title}

: null} {description ? (

{description}

) : null} {badges ?
{badges}
: null} {hint ?
{hint}
: null}
{action ?
{action}
: null}
) : null} {children ? (
{children}
) : null} {footer ?
{footer}
: null}
) } /** Champ de formulaire : label + contrôle + hint/erreur. */ export function SettingsField({ label, htmlFor, hint, error, required, children, className, labelClassName, labelAction, }: { label?: ReactNode htmlFor?: string hint?: ReactNode error?: ReactNode required?: boolean children: ReactNode className?: string labelClassName?: string /** Élément aligné à droite du label (lien, bouton…). */ labelAction?: ReactNode }) { return (
{label ? (
{labelAction}
) : null} {children} {hint ? (
{hint}
) : null} {error ? (
{error}
) : null}
) } /** Ligne à bascule : titre + description + Switch. */ export function SettingsToggleRow({ title, description, checked, onCheckedChange, disabled, hint, variant = "bordered", className, }: { title: ReactNode description?: ReactNode checked: boolean onCheckedChange: (checked: boolean) => void disabled?: boolean /** Indication sous la ligne (ex. verrou déploiement). */ hint?: ReactNode variant?: "bordered" | "plain" className?: string }) { const row = ( ) if (!hint) return row return (
{row} {hint}
) } /** Ligne à cocher : titre + description + Checkbox. */ export function SettingsCheckboxRow({ title, description, checked, onCheckedChange, disabled, variant = "plain", className, }: { title: ReactNode description?: ReactNode checked: boolean onCheckedChange: (checked: boolean) => void disabled?: boolean variant?: "bordered" | "plain" className?: string }) { return ( ) } /** Grille de champs responsive (1 ou 2 colonnes). */ export function SettingsGrid({ columns = 2, children, className, }: { columns?: 1 | 2 children: ReactNode className?: string }) { return (
{children}
) } /** Indication brève (texte muted) sous un champ ou une carte. */ export function SettingsHint({ children, tone = "muted", className, }: { children: ReactNode tone?: "muted" | "warning" | "danger" className?: string }) { return (

{children}

) }