Fondation
This commit is contained in:
parent
1e00c2da4e
commit
32e757b3e7
@ -13,8 +13,8 @@ import { useWidgetNotification } from "@/hooks/use-widget-notification";
|
|||||||
type Event = {
|
type Event = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
start: Date;
|
start: string | Date;
|
||||||
end: Date;
|
end: string | Date;
|
||||||
isAllDay: boolean;
|
isAllDay: boolean;
|
||||||
calendarId: string;
|
calendarId: string;
|
||||||
calendarName?: string;
|
calendarName?: string;
|
||||||
@ -22,7 +22,7 @@ type Event = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function CalendarWidget() {
|
export function CalendarWidget() {
|
||||||
const { data: session, status: sessionStatus } = useSession();
|
const { data: session } = useSession();
|
||||||
const [events, setEvents] = useState<Event[]>([]);
|
const [events, setEvents] = useState<Event[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@ -30,52 +30,32 @@ export function CalendarWidget() {
|
|||||||
const lastEventCountRef = useRef<number>(-1);
|
const lastEventCountRef = useRef<number>(-1);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("Calendar Widget - Session Status:", sessionStatus);
|
// Ne charger les événements que si l'utilisateur est connecté
|
||||||
console.log("Calendar Widget - Session Data:", session);
|
if (!session) return;
|
||||||
|
|
||||||
if (sessionStatus === "loading") {
|
|
||||||
console.log("Calendar Widget - Session is loading");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionStatus !== "authenticated" || !session) {
|
|
||||||
console.log("Calendar Widget - Not authenticated, skipping fetch");
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchUpcomingEvents = async () => {
|
const fetchUpcomingEvents = async () => {
|
||||||
try {
|
try {
|
||||||
console.log("Calendar Widget - Starting to fetch events");
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
// Fetch calendars with events
|
|
||||||
console.log("Calendar Widget - Making API request to /api/calendars");
|
|
||||||
const response = await fetch('/api/calendars');
|
|
||||||
|
|
||||||
if (!response.ok) {
|
// Récupérer d'abord les calendriers de l'utilisateur
|
||||||
console.error("Calendar Widget - API response not OK:", response.status, response.statusText);
|
const calendarsRes = await fetch("/api/calendars");
|
||||||
throw new Error("Impossible de charger les événements");
|
|
||||||
|
if (!calendarsRes.ok) {
|
||||||
|
throw new Error("Impossible de charger les calendriers");
|
||||||
}
|
}
|
||||||
|
|
||||||
const calendarsData = await response.json();
|
const calendars = await calendarsRes.json();
|
||||||
console.log("Calendar Widget - Raw calendars data:", calendarsData);
|
|
||||||
console.log("Calendar Widget - Calendars count:", calendarsData.length);
|
if (calendars.length === 0) {
|
||||||
console.log("Calendar Widget - Events per calendar:", calendarsData.map((cal: any) => ({
|
setEvents([]);
|
||||||
name: cal.name,
|
setLoading(false);
|
||||||
eventCount: cal.events?.length || 0,
|
return;
|
||||||
events: cal.events?.map((e: any) => ({ id: e.id, title: e.title, start: e.start })) || []
|
|
||||||
})));
|
|
||||||
|
|
||||||
if (!Array.isArray(calendarsData)) {
|
|
||||||
console.error("Calendar Widget - Calendars data is not an array:", calendarsData);
|
|
||||||
throw new Error("Format de données invalide");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current date at the start of the day
|
// Date actuelle et date dans 7 jours
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
now.setHours(0, 0, 0, 0);
|
const nextWeek = addDays(now, 7);
|
||||||
|
|
||||||
// Helper function to get display name for calendar
|
// Helper function to get display name for calendar
|
||||||
const getCalendarDisplayName = (calendar: any) => {
|
const getCalendarDisplayName = (calendar: any) => {
|
||||||
// If calendar is synced to an external account, use the account name
|
// If calendar is synced to an external account, use the account name
|
||||||
@ -87,47 +67,57 @@ export function CalendarWidget() {
|
|||||||
return calendar.name;
|
return calendar.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract all events and add calendar info
|
// Récupérer les événements pour chaque calendrier
|
||||||
const allEvents = calendarsData.flatMap((calendar) => {
|
const allEventsPromises = calendars.map(async (calendar: any) => {
|
||||||
const displayName = getCalendarDisplayName(calendar);
|
const eventsRes = await fetch(
|
||||||
console.log("Calendar Widget - Processing calendar:", displayName, "Events:", calendar.events?.length || 0);
|
`/api/calendars/${
|
||||||
return (calendar.events || []).map((event: { id: string; title: string; start: string | Date; end: string | Date; isAllDay: boolean; calendarId: string }) => {
|
calendar.id
|
||||||
const startDate = new Date(event.start);
|
}/events?start=${now.toISOString()}&end=${nextWeek.toISOString()}`
|
||||||
const endDate = new Date(event.end);
|
);
|
||||||
return {
|
|
||||||
id: event.id,
|
if (!eventsRes.ok) {
|
||||||
title: event.title,
|
console.warn(
|
||||||
start: startDate,
|
`Impossible de charger les événements du calendrier ${calendar.id}`
|
||||||
end: endDate,
|
);
|
||||||
isAllDay: event.isAllDay,
|
return [];
|
||||||
calendarId: event.calendarId,
|
}
|
||||||
calendarColor: calendar.color,
|
|
||||||
calendarName: displayName
|
const events = await eventsRes.json();
|
||||||
};
|
|
||||||
});
|
// Ajouter les informations du calendrier à chaque événement
|
||||||
|
return events.map((event: any) => ({
|
||||||
|
...event,
|
||||||
|
calendarName: getCalendarDisplayName(calendar),
|
||||||
|
calendarColor: calendar.color,
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter for upcoming events (next 7 days, like the old widget)
|
// Attendre toutes les requêtes d'événements
|
||||||
const nextWeek = addDays(now, 7);
|
const allEventsArrays = await Promise.all(allEventsPromises);
|
||||||
const upcomingEvents = allEvents
|
|
||||||
.filter(event => event.start >= now && event.start <= nextWeek)
|
|
||||||
.sort((a, b) => a.start.getTime() - b.start.getTime())
|
|
||||||
.slice(0, 10);
|
|
||||||
|
|
||||||
console.log("Calendar Widget - Final upcoming events:", upcomingEvents);
|
// 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 pour l'affichage
|
||||||
|
const upcomingEvents = sortedEvents.slice(0, 5);
|
||||||
|
|
||||||
|
// Calculate current event count (all events, not just displayed)
|
||||||
|
const currentEventCount = sortedEvents.length;
|
||||||
|
|
||||||
// Calculate current event count
|
// Prepare notification items for all upcoming events
|
||||||
const currentEventCount = upcomingEvents.length;
|
const notificationItems = sortedEvents.map(event => ({
|
||||||
|
|
||||||
// Always prepare notification items
|
|
||||||
const notificationItems = upcomingEvents.map(event => ({
|
|
||||||
id: event.id,
|
id: event.id,
|
||||||
title: event.title,
|
title: event.title,
|
||||||
message: event.isAllDay
|
message: event.isAllDay
|
||||||
? `Aujourd'hui (toute la journée)`
|
? `Aujourd'hui (toute la journée)`
|
||||||
: `Le ${format(event.start, 'dd/MM à HH:mm', { locale: fr })}`,
|
: `Le ${format(new Date(event.start), 'dd/MM à HH:mm', { locale: fr })}`,
|
||||||
link: '/agenda',
|
link: '/agenda',
|
||||||
timestamp: event.start,
|
timestamp: new Date(event.start),
|
||||||
metadata: {
|
metadata: {
|
||||||
calendarId: event.calendarId,
|
calendarId: event.calendarId,
|
||||||
calendarName: event.calendarName,
|
calendarName: event.calendarName,
|
||||||
@ -136,7 +126,6 @@ export function CalendarWidget() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Always trigger notification update to keep count fresh in Redis
|
// Always trigger notification update to keep count fresh in Redis
|
||||||
// This ensures the count doesn't expire even if it hasn't changed
|
|
||||||
await triggerNotification({
|
await triggerNotification({
|
||||||
source: 'calendar',
|
source: 'calendar',
|
||||||
count: currentEventCount,
|
count: currentEventCount,
|
||||||
@ -148,39 +137,27 @@ export function CalendarWidget() {
|
|||||||
lastEventCountRef.current = currentEventCount;
|
lastEventCountRef.current = currentEventCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEvents(upcomingEvents.slice(0, 5)); // Keep only 5 for display
|
setEvents(upcomingEvents);
|
||||||
|
|
||||||
// Dispatch event for Outlook-style notifications (when events start)
|
// Dispatch event for Outlook-style notifications
|
||||||
// Always dispatch, not just when count changes, so the hook can track events
|
const eventsForNotification = sortedEvents.map(evt => ({
|
||||||
const eventsForNotification = upcomingEvents.map(evt => ({
|
|
||||||
id: evt.id,
|
id: evt.id,
|
||||||
title: evt.title,
|
title: evt.title,
|
||||||
start: evt.start instanceof Date ? evt.start : new Date(evt.start),
|
start: new Date(evt.start),
|
||||||
end: evt.end instanceof Date ? evt.end : new Date(evt.end),
|
end: new Date(evt.end),
|
||||||
isAllDay: evt.isAllDay,
|
isAllDay: evt.isAllDay,
|
||||||
calendarName: evt.calendarName,
|
calendarName: evt.calendarName,
|
||||||
calendarColor: evt.calendarColor,
|
calendarColor: evt.calendarColor,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log('[Calendar Widget] 📅 Dispatching calendar events update', {
|
|
||||||
eventsCount: eventsForNotification.length,
|
|
||||||
events: eventsForNotification.map(e => ({
|
|
||||||
id: e.id,
|
|
||||||
title: e.title,
|
|
||||||
start: e.start instanceof Date ? e.start.toISOString() : e.start,
|
|
||||||
isAllDay: e.isAllDay,
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
window.dispatchEvent(new CustomEvent('calendar-events-updated', {
|
window.dispatchEvent(new CustomEvent('calendar-events-updated', {
|
||||||
detail: {
|
detail: {
|
||||||
events: eventsForNotification,
|
events: eventsForNotification,
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
console.log('[Calendar Widget] ✅ Event dispatched successfully');
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Calendar Widget] ❌ Error dispatching event', error);
|
console.error('[Calendar Widget] Error dispatching event', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setError(null);
|
setError(null);
|
||||||
@ -192,30 +169,23 @@ export function CalendarWidget() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initial fetch
|
|
||||||
fetchUpcomingEvents();
|
fetchUpcomingEvents();
|
||||||
|
}, [session]);
|
||||||
|
|
||||||
// Set up an interval to refresh events every 5 minutes
|
const formatEventDate = (date: string | Date, isAllDay: boolean) => {
|
||||||
const intervalId = setInterval(() => {
|
const eventDate = new Date(date);
|
||||||
fetchUpcomingEvents();
|
|
||||||
}, 300000);
|
|
||||||
|
|
||||||
return () => clearInterval(intervalId);
|
|
||||||
}, [session, sessionStatus, triggerNotification]);
|
|
||||||
|
|
||||||
const formatEventDate = (date: Date, isAllDay: boolean) => {
|
|
||||||
let dateString = "";
|
let dateString = "";
|
||||||
|
if (isToday(eventDate)) {
|
||||||
if (isToday(date)) {
|
|
||||||
dateString = "Aujourd'hui";
|
dateString = "Aujourd'hui";
|
||||||
} else if (isTomorrow(date)) {
|
} else if (isTomorrow(eventDate)) {
|
||||||
dateString = "Demain";
|
dateString = "Demain";
|
||||||
} else {
|
} else {
|
||||||
dateString = format(date, "EEEE d MMMM", { locale: fr });
|
dateString = format(eventDate, "EEEE d MMMM", { locale: fr });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAllDay) {
|
if (!isAllDay) {
|
||||||
dateString += ` · ${format(date, "HH:mm", { locale: fr })}`;
|
dateString += ` · ${format(eventDate, "HH:mm", { locale: fr })}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dateString;
|
return dateString;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user