vision refactor

This commit is contained in:
alma 2026-01-15 19:43:43 +01:00
parent 22c944b17c
commit cc787e040b

View File

@ -47,6 +47,9 @@ interface ScheduledMeeting {
date: string; // ISO date string date: string; // ISO date string
time: string; // HH:mm format time: string; // HH:mm format
title?: string; title?: string;
start: string; // ISO datetime string for start
end: string; // ISO datetime string for end
isAllDay?: boolean;
} }
type ConferenceType = "group" | "mission" | null; type ConferenceType = "group" | "mission" | null;
@ -131,6 +134,7 @@ export default function VisionPage() {
// Convert events to ScheduledMeeting format // Convert events to ScheduledMeeting format
(calendar.events || []).forEach((event: any) => { (calendar.events || []).forEach((event: any) => {
const eventStart = new Date(event.start); const eventStart = new Date(event.start);
const eventEnd = new Date(event.end);
const dateStr = eventStart.toISOString().split('T')[0]; const dateStr = eventStart.toISOString().split('T')[0];
const timeStr = event.isAllDay ? "" : eventStart.toTimeString().slice(0, 5); const timeStr = event.isAllDay ? "" : eventStart.toTimeString().slice(0, 5);
@ -142,6 +146,9 @@ export default function VisionPage() {
date: dateStr, date: dateStr,
time: timeStr, time: timeStr,
title: event.title, title: event.title,
start: event.start,
end: event.end,
isAllDay: event.isAllDay || false,
}); });
}); });
}); });
@ -259,6 +266,20 @@ export default function VisionPage() {
setJitsiUrl(null); setJitsiUrl(null);
}; };
// Check if meeting can be joined (5 minutes before start until end)
const canJoinMeeting = (meeting: ScheduledMeeting): boolean => {
const now = new Date();
const start = new Date(meeting.start);
const end = new Date(meeting.end);
// Calculate 5 minutes before start
const fiveMinutesBeforeStart = new Date(start);
fiveMinutesBeforeStart.setMinutes(fiveMinutesBeforeStart.getMinutes() - 5);
// Can join if now is between 5 minutes before start and end
return now >= fiveMinutesBeforeStart && now <= end;
};
// Get today's meetings // Get today's meetings
const getTodayMeetings = (): ScheduledMeeting[] => { const getTodayMeetings = (): ScheduledMeeting[] => {
const today = new Date(); const today = new Date();
@ -465,7 +486,8 @@ export default function VisionPage() {
} }
// Refresh meetings from database after deletion // Refresh meetings from database after deletion
const refreshCalendarsResponse = await fetch("/api/calendars"); // Use refresh=true to bypass cache and ensure immediate update
const refreshCalendarsResponse = await fetch("/api/calendars?refresh=true");
if (refreshCalendarsResponse.ok) { if (refreshCalendarsResponse.ok) {
const calendarsData = await refreshCalendarsResponse.json(); const calendarsData = await refreshCalendarsResponse.json();
const meetings = convertCalendarsToMeetings(calendarsData); const meetings = convertCalendarsToMeetings(calendarsData);
@ -585,22 +607,16 @@ export default function VisionPage() {
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Button {canJoinMeeting(meeting) && (
size="sm" <Button
className="bg-blue-600 hover:bg-blue-700 text-white" size="sm"
onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName)} className="bg-blue-600 hover:bg-blue-700 text-white"
> onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName)}
<Video className="h-4 w-4 mr-1" /> >
Rejoindre <Video className="h-4 w-4 mr-1" />
</Button> Rejoindre
<Button </Button>
variant="ghost" )}
size="sm"
onClick={() => handleDeleteMeeting(meeting.id)}
className="text-red-600 hover:text-red-700 hover:bg-red-50"
>
<X className="h-4 w-4" />
</Button>
</div> </div>
</div> </div>
))} ))}
@ -766,7 +782,7 @@ export default function VisionPage() {
</h4> </h4>
<p className="text-sm text-gray-500">{meeting.time}</p> <p className="text-sm text-gray-500">{meeting.time}</p>
</div> </div>
<div className="flex items-center gap-2"> {canJoinMeeting(meeting) && (
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
@ -775,15 +791,7 @@ export default function VisionPage() {
<Video className="h-4 w-4 mr-1" /> <Video className="h-4 w-4 mr-1" />
Rejoindre Rejoindre
</Button> </Button>
<Button )}
variant="ghost"
size="sm"
onClick={() => handleDeleteMeeting(meeting.id)}
className="text-red-600 hover:text-red-700"
>
<X className="h-4 w-4" />
</Button>
</div>
</div> </div>
))} ))}
</div> </div>