ultisuite-client/components/agenda/agenda-calendar-dialog.tsx
R3D347HR4Y ad1370ea7e
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: enhance configuration and add new demo layouts
- Introduced turbopack alias for canvas in next.config.mjs.
- Updated package.json scripts for development and branding tasks.
- Added new dependencies for Tiptap extensions.
- Implemented new demo layouts for agenda, contacts, drive, and mail applications.
- Enhanced globals.css for improved theming and splash screen animations.
- Added OAuth callback handling for drive mounts.
- Updated layout components to integrate new demo shells and improve structure.
2026-06-12 19:10:24 +02:00

136 lines
4.4 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import { toast } from "sonner"
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
useCreateAgendaCalendar,
useUpdateAgendaCalendar,
} from "@/lib/api/hooks/use-calendar-mutations"
import { AGENDA_COLOR_PALETTE } from "@/lib/agenda/agenda-colors"
import { calendarColor } from "@/lib/agenda/agenda-events"
import type { AgendaCalendar } from "@/lib/agenda/agenda-types"
import { cn } from "@/lib/utils"
export function AgendaCalendarDialog({
open,
onOpenChange,
calendar,
onAddExternalICal,
}: {
open: boolean
onOpenChange: (open: boolean) => void
/** Agenda à modifier — absent en création. */
calendar?: AgendaCalendar | null
/** Création uniquement — ouvre la modale iCal externe. */
onAddExternalICal?: () => void
}) {
const [name, setName] = useState("")
const [color, setColor] = useState(AGENDA_COLOR_PALETTE[0].value)
const createMutation = useCreateAgendaCalendar()
const updateMutation = useUpdateAgendaCalendar()
const pending = createMutation.isPending || updateMutation.isPending
useEffect(() => {
if (!open) return
setName(calendar?.display_name ?? "")
setColor(calendar ? calendarColor(calendar) : AGENDA_COLOR_PALETTE[0].value)
}, [open, calendar])
const submit = async () => {
const displayName = name.trim()
if (!displayName) return
try {
if (calendar) {
await updateMutation.mutateAsync({
id: calendar.id,
display_name: displayName,
color,
})
toast.success("Agenda mis à jour")
} else {
await createMutation.mutateAsync({ display_name: displayName, color })
toast.success(`Agenda « ${displayName} » créé`)
}
onOpenChange(false)
} catch {
toast.error("Impossible d'enregistrer l'agenda")
}
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-md" aria-describedby={undefined}>
<DialogHeader>
<DialogTitle>
{calendar ? "Modifier l'agenda" : "Nouvel agenda"}
</DialogTitle>
</DialogHeader>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="agenda-cal-name">Nom</Label>
<Input
id="agenda-cal-name"
value={name}
autoFocus
placeholder="Mon agenda"
onChange={(e) => setName(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") void submit()
}}
/>
</div>
<div className="flex flex-col gap-2">
<Label>Couleur</Label>
<div className="flex flex-wrap gap-2">
{AGENDA_COLOR_PALETTE.map((c) => (
<button
key={c.value}
type="button"
title={c.label}
aria-label={c.label}
onClick={() => setColor(c.value)}
className={cn(
"size-7 rounded-full transition-transform hover:scale-110",
color === c.value &&
"ring-2 ring-foreground/70 ring-offset-2 ring-offset-background",
)}
style={{ backgroundColor: c.value }}
/>
))}
</div>
</div>
</div>
<DialogFooter className={!calendar && onAddExternalICal ? "sm:justify-between" : undefined}>
{!calendar && onAddExternalICal ? (
<button
type="button"
className="text-xs text-[#1a73e8] hover:underline"
onClick={onAddExternalICal}
>
Ajouter un agenda externe iCal
</button>
) : null}
<div className="flex gap-2">
<Button variant="ghost" onClick={() => onOpenChange(false)}>
Annuler
</Button>
<Button onClick={() => void submit()} disabled={!name.trim() || pending}>
{calendar ? "Enregistrer" : "Créer"}
</Button>
</div>
</DialogFooter>
</DialogContent>
</Dialog>
)
}