ultisuite-client/components/gmail/quick-settings/quick-settings-panel.tsx
R3D347HR4Y 9266aa34cd huhu
2026-05-19 22:20:43 +02:00

242 lines
7.2 KiB
TypeScript

"use client"
import Link from "next/link"
import { X } from "lucide-react"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { useMailSettingsStore } from "@/lib/stores/mail-settings-store"
import type {
InboxSortMode,
MailDensity,
ReadingPaneMode,
} from "@/lib/mail-settings/types"
import {
QuickSettingsCheckbox,
QuickSettingsOption,
} from "@/components/gmail/quick-settings/quick-settings-option"
import {
DensityCompactIcon,
DensityDefaultIcon,
DensityNormalIcon,
InboxDefaultIcon,
InboxImportantIcon,
InboxStarredIcon,
InboxUnreadIcon,
ReadingPaneBelowIcon,
ReadingPaneNoneIcon,
ReadingPaneRightIcon,
ThemeThumbnailIcon,
} from "@/components/gmail/quick-settings/settings-preview-icons"
function SettingsSection({
title,
action,
children,
className,
}: {
title: string
action?: React.ReactNode
children: React.ReactNode
className?: string
}) {
return (
<section className={cn("border-b border-border px-4 py-4", className)}>
<div className="mb-2 flex items-center justify-between gap-2">
<h2 className="text-sm font-medium text-foreground">{title}</h2>
{action}
</div>
{children}
</section>
)
}
export function QuickSettingsPanel() {
const open = useMailSettingsStore((s) => s.quickSettingsOpen)
const themeDialogOpen = useMailSettingsStore((s) => s.themeDialogOpen)
const setOpen = useMailSettingsStore((s) => s.setQuickSettingsOpen)
const setThemeDialogOpen = useMailSettingsStore((s) => s.setThemeDialogOpen)
const density = useMailSettingsStore((s) => s.density)
const setDensity = useMailSettingsStore((s) => s.setDensity)
const inboxSort = useMailSettingsStore((s) => s.inboxSort)
const setInboxSort = useMailSettingsStore((s) => s.setInboxSort)
const readingPane = useMailSettingsStore((s) => s.readingPane)
const setReadingPane = useMailSettingsStore((s) => s.setReadingPane)
const conversationMode = useMailSettingsStore((s) => s.conversationMode)
const setConversationMode = useMailSettingsStore((s) => s.setConversationMode)
if (!open) return null
const densityOptions: {
id: MailDensity
label: string
icon: React.ReactNode
}[] = [
{ id: "default", label: "Par défaut", icon: <DensityDefaultIcon /> },
{ id: "normal", label: "Normal", icon: <DensityNormalIcon /> },
{ id: "compact", label: "Compact", icon: <DensityCompactIcon /> },
]
const inboxOptions: {
id: InboxSortMode
label: string
icon: React.ReactNode
}[] = [
{ id: "default", label: "Par défaut", icon: <InboxDefaultIcon /> },
{
id: "important",
label: "Importants d'abord",
icon: <InboxImportantIcon />,
},
{ id: "unread", label: "Non lus d'abord", icon: <InboxUnreadIcon /> },
{ id: "starred", label: "Suivis d'abord", icon: <InboxStarredIcon /> },
]
const readingPaneOptions: {
id: ReadingPaneMode
label: string
icon: React.ReactNode
disabled?: boolean
}[] = [
{
id: "none",
label: "Aucune séparation",
icon: <ReadingPaneNoneIcon />,
},
{
id: "right",
label: "À droite de la boîte de réception",
icon: <ReadingPaneRightIcon />,
},
{
id: "below",
label: "Sous la boîte de réception",
icon: <ReadingPaneBelowIcon />,
disabled: true,
},
]
return (
<>
{!themeDialogOpen && (
<button
type="button"
className="fixed inset-0 z-[60] bg-black/20"
aria-label="Fermer la configuration rapide"
onClick={() => setOpen(false)}
/>
)}
<aside
role="dialog"
aria-label="Configuration rapide"
className="fixed right-0 top-0 z-[61] flex h-full w-full max-w-[360px] flex-col border-l border-border bg-mail-surface shadow-lg"
>
<header className="flex shrink-0 items-center justify-between gap-2 px-4 pt-5 pb-3">
<h1 className="text-base font-normal text-foreground">
Configuration rapide
</h1>
<Button
type="button"
variant="ghost"
size="icon"
className="size-9 text-muted-foreground"
aria-label="Fermer"
onClick={() => setOpen(false)}
>
<X className="size-5" />
</Button>
</header>
<div className="min-h-0 flex-1 overflow-y-auto">
<div className="px-4 pb-4">
<Button
variant="outline"
className="h-10 w-full rounded-full border-[#1a73e8] text-[#1a73e8] hover:bg-[#e8f0fe]/50"
asChild
onClick={() => setOpen(false)}
>
<Link href="/mail/settings">Voir tous les paramètres</Link>
</Button>
</div>
<SettingsSection title="Densité">
{densityOptions.map((opt) => (
<QuickSettingsOption
key={opt.id}
name="density"
label={opt.label}
checked={density === opt.id}
onSelect={() => setDensity(opt.id)}
icon={opt.icon}
/>
))}
</SettingsSection>
<SettingsSection
title="Thème"
action={
<button
type="button"
className="text-sm text-[#1a73e8] hover:underline"
onClick={() => {
setThemeDialogOpen(true)
}}
>
Tout afficher
</button>
}
>
<button
type="button"
className="flex w-full items-center justify-end rounded-md py-1 hover:bg-accent"
onClick={() => setThemeDialogOpen(true)}
>
<ThemeThumbnailIcon />
</button>
</SettingsSection>
<SettingsSection title="Type de boîte de réception">
{inboxOptions.map((opt) => (
<QuickSettingsOption
key={opt.id}
name="inbox-sort"
label={opt.label}
checked={inboxSort === opt.id}
onSelect={() => setInboxSort(opt.id)}
icon={opt.icon}
/>
))}
</SettingsSection>
<SettingsSection title="Volet de lecture">
{readingPaneOptions.map((opt) => (
<QuickSettingsOption
key={opt.id}
name="reading-pane"
label={opt.label}
checked={readingPane === opt.id}
disabled={opt.disabled}
onSelect={() => {
if (!opt.disabled) setReadingPane(opt.id)
}}
icon={opt.icon}
/>
))}
</SettingsSection>
<section className="px-4 py-4">
<h2 className="mb-2 text-sm font-medium text-foreground">
Fils de discussion
</h2>
<QuickSettingsCheckbox
label="Mode Conversation"
checked={conversationMode}
onChange={setConversationMode}
helpLabel="Regrouper les messages d'une même conversation"
/>
</section>
</div>
</aside>
</>
)
}