diff --git a/front/app/page.tsx b/front/app/page.tsx index 15ab3d3..97743b1 100644 --- a/front/app/page.tsx +++ b/front/app/page.tsx @@ -38,6 +38,7 @@ export default async function Page() {
+
diff --git a/front/components/calendar-widget.tsx b/front/components/calendar-widget.tsx index 9295a41..66fd357 100644 --- a/front/components/calendar-widget.tsx +++ b/front/components/calendar-widget.tsx @@ -1,17 +1,194 @@ -import { Card, CardContent, CardHeader } from "@/components/ui/card"; +"use client"; + +import { useState, useEffect } from "react"; +import { format, isToday, isTomorrow, addDays } from "date-fns"; +import { fr } from "date-fns/locale"; +import { CalendarIcon, ClockIcon, ChevronRight } from "lucide-react"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { useSession } from "next-auth/react"; + +type Event = { + id: string; + title: string; + start: string; + end: string; + isAllDay: boolean; + calendarId: string; + calendarName?: string; + calendarColor?: string; +}; export function CalendarWidget() { + const { data: session } = useSession(); + const [events, setEvents] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + // Ne charger les événements que si l'utilisateur est connecté + if (!session) return; + + const fetchUpcomingEvents = async () => { + try { + setLoading(true); + + // Récupérer d'abord les calendriers de l'utilisateur + const calendarsRes = await fetch("/api/calendars"); + + if (!calendarsRes.ok) { + throw new Error("Impossible de charger les calendriers"); + } + + const calendars = await calendarsRes.json(); + + if (calendars.length === 0) { + setEvents([]); + setLoading(false); + return; + } + + // Date actuelle et date dans 7 jours + const now = new Date(); + // @ts-ignore + const nextWeek = addDays(now, 7); + + // Récupérer les événements pour chaque calendrier + const allEventsPromises = calendars.map(async (calendar: any) => { + const eventsRes = await fetch( + `/api/calendars/${ + calendar.id + }/events?start=${now.toISOString()}&end=${nextWeek.toISOString()}` + ); + + if (!eventsRes.ok) { + console.warn( + `Impossible de charger les événements du calendrier ${calendar.id}` + ); + return []; + } + + const events = await eventsRes.json(); + + // Ajouter les informations du calendrier à chaque événement + return events.map((event: any) => ({ + ...event, + calendarName: calendar.name, + calendarColor: calendar.color, + })); + }); + + // Attendre toutes les requêtes d'événements + const allEventsArrays = await Promise.all(allEventsPromises); + + // Fusionner tous les événements en un seul tableau + const allEvents = allEventsArrays.flat(); + + // Trier par date de début + const sortedEvents = allEvents.sort( + (a, b) => new Date(a.start).getTime() - new Date(b.start).getTime() + ); + + // Limiter à 5 événements + setEvents(sortedEvents.slice(0, 5)); + } catch (err) { + console.error("Erreur lors du chargement des événements:", err); + setError("Impossible de charger les événements à venir"); + } finally { + setLoading(false); + } + }; + + fetchUpcomingEvents(); + }, [session]); + + // Formater la date d'un événement pour l'affichage + const formatEventDate = (date: string, isAllDay: boolean) => { + const eventDate = new Date(date); + + let dateString = ""; + // @ts-ignore + if (isToday(eventDate)) { + dateString = "Aujourd'hui"; + // @ts-ignore + } else if (isTomorrow(eventDate)) { + dateString = "Demain"; + } else { + // @ts-ignore + dateString = format(eventDate, "EEEE d MMMM", { locale: fr }); + } + + if (!isAllDay) { + // @ts-ignore + dateString += ` · ${format(eventDate, "HH:mm", { locale: fr })}`; + } + + return dateString; + }; + return ( - -
JEUDI
-
24
+ + + Événements à venir + + + + - -
-

Classe UX Design en visio conférence

-

Rappel : Examen dans 2 jours

-
+ + {loading ? ( +
+
+ + Chargement... + +
+ ) : error ? ( +

{error}

+ ) : events.length === 0 ? ( +

+ Aucun événement à venir cette semaine +

+ ) : ( +
+ {events.map((event) => ( +
+
+
+
+ {event.title} +
+
+ + {formatEventDate(event.start, event.isAllDay)} +
+
+
+ ))} + + + +
+ )} ); diff --git a/front/components/calendar/event-dialog.tsx b/front/components/calendar/event-dialog.tsx index a75745a..fa7561b 100644 --- a/front/components/calendar/event-dialog.tsx +++ b/front/components/calendar/event-dialog.tsx @@ -53,8 +53,11 @@ export function EventDialog({ const formatDate = (dateStr: string) => { if (!dateStr) return ""; try { + // @ts-ignore const date = parseISO(dateStr); + // @ts-ignore return format(date, allDay ? "yyyy-MM-dd" : "yyyy-MM-dd'T'HH:mm", { + // @ts-ignore locale: fr, }); } catch (e) { @@ -68,11 +71,15 @@ export function EventDialog({ // Ajuster les dates si nécessaire if (checked && start) { + // @ts-ignore const startDate = parseISO(start); + // @ts-ignore setStart(format(startDate, "yyyy-MM-dd")); if (end) { + // @ts-ignore const endDate = parseISO(end); + // @ts-ignore setEnd(format(endDate, "yyyy-MM-dd")); } }