"use client" import { useRouter } from "next/navigation" import { toast } from "sonner" import { Icon } from "@iconify/react" import { Check, CircleHelp, Mail, MapPin, Pencil, Repeat, Trash2, Users, X, } from "lucide-react" import { AgendaFloatingCard, type AnchorRect } from "@/components/agenda/agenda-floating-card" import { ContactAvatar } from "@/components/gmail/contacts/contact-avatar" import { Button } from "@/components/ui/button" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { useDeleteAgendaEvent, useRespondAgendaInvitation, } from "@/lib/api/hooks/use-calendar-mutations" import { formatEventRange } from "@/lib/agenda/agenda-date" import { describeRRule } from "@/lib/agenda/agenda-recurrence" import { stashPendingCompose } from "@/lib/agenda/agenda-mail-compose" import type { AgendaCalendar, AgendaEvent } from "@/lib/agenda/agenda-types" import { cn } from "@/lib/utils" export interface AgendaEventPopoverState { event: AgendaEvent anchor: AnchorRect } const STATUS_LABELS: Record = { ACCEPTED: "accepté", DECLINED: "refusé", TENTATIVE: "peut-être", "NEEDS-ACTION": "en attente", } export function AgendaEventPopover({ state, calendars, userEmail, onClose, onEdit, }: { state: AgendaEventPopoverState | null calendars: AgendaCalendar[] userEmail?: string onClose: () => void onEdit: (event: AgendaEvent) => void }) { const router = useRouter() const deleteMutation = useDeleteAgendaEvent() const respondMutation = useRespondAgendaInvitation() if (!state) return null const { event, anchor } = state const calendar = calendars.find((c) => c.id === event.calendarId) const selfAttendee = userEmail ? event.attendees.find((a) => a.email.toLowerCase() === userEmail.toLowerCase()) : undefined const remove = async () => { try { await deleteMutation.mutateAsync({ path: event.path }) toast.success("Événement supprimé") onClose() } catch { toast.error("Impossible de supprimer l'événement") } } const respond = async (response: "accepted" | "declined" | "tentative") => { try { await respondMutation.mutateAsync({ path: event.path, response, etag: event.etag }) toast.success("Réponse enregistrée") onClose() } catch { toast.error("Impossible d'enregistrer la réponse") } } const emailGuests = () => { const recipients = event.attendees .filter((a) => a.email.toLowerCase() !== (userEmail ?? "").toLowerCase()) .map((a) => ({ name: a.name ?? a.email, email: a.email })) if (event.organizer && event.organizer.toLowerCase() !== (userEmail ?? "").toLowerCase()) { if (!recipients.some((r) => r.email.toLowerCase() === event.organizer.toLowerCase())) { recipients.push({ name: event.organizer, email: event.organizer }) } } stashPendingCompose({ to: recipients, subject: event.title }) router.push("/mail") } return ( {/* Barre d'actions */}
Modifier Supprimer {event.attendees.length > 0 && ( Envoyer un email aux invités )}
{/* Titre */}

{event.title}

{formatEventRange(event.start, event.end, event.allDay)}

{event.recurring && ( }> {describeRRule(event.rrule)} )} {event.meetUrl && ( } > )} {event.location && ( }> {event.location} )} {event.attendees.length > 0 && ( } alignTop>
{event.attendees.length} invité {event.attendees.length > 1 ? "s" : ""} {event.attendees.map((a) => (
{a.status === "ACCEPTED" && ( )} {a.status === "DECLINED" && ( )} {a.status === "TENTATIVE" && ( )}
{a.name || a.email} {event.organizer && a.email.toLowerCase() === event.organizer.toLowerCase() && ( — organisateur )} {STATUS_LABELS[a.status ?? "NEEDS-ACTION"] ?? a.status?.toLowerCase()}
))}
)} {event.description && ( } alignTop >

{event.description}

)} {calendar && ( } > {calendar.display_name} )} {/* RSVP */} {selfAttendee && (
Vous participez ?
{( [ ["accepted", "Oui", "ACCEPTED"], ["tentative", "Peut-être", "TENTATIVE"], ["declined", "Non", "DECLINED"], ] as const ).map(([value, label, partstat]) => ( ))}
)}
) } function Row({ icon, children, alignTop, }: { icon: React.ReactNode children: React.ReactNode alignTop?: boolean }) { return (
{icon}
{children}
) }