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
time: string; // HH:mm format
title?: string;
start: string; // ISO datetime string for start
end: string; // ISO datetime string for end
isAllDay?: boolean;
}
type ConferenceType = "group" | "mission" | null;
@ -131,6 +134,7 @@ export default function VisionPage() {
// Convert events to ScheduledMeeting format
(calendar.events || []).forEach((event: any) => {
const eventStart = new Date(event.start);
const eventEnd = new Date(event.end);
const dateStr = eventStart.toISOString().split('T')[0];
const timeStr = event.isAllDay ? "" : eventStart.toTimeString().slice(0, 5);
@ -142,6 +146,9 @@ export default function VisionPage() {
date: dateStr,
time: timeStr,
title: event.title,
start: event.start,
end: event.end,
isAllDay: event.isAllDay || false,
});
});
});
@ -259,6 +266,20 @@ export default function VisionPage() {
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
const getTodayMeetings = (): ScheduledMeeting[] => {
const today = new Date();
@ -465,7 +486,8 @@ export default function VisionPage() {
}
// 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) {
const calendarsData = await refreshCalendarsResponse.json();
const meetings = convertCalendarsToMeetings(calendarsData);
@ -585,22 +607,16 @@ export default function VisionPage() {
</div>
</div>
<div className="flex items-center gap-2">
<Button
size="sm"
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
</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>
{canJoinMeeting(meeting) && (
<Button
size="sm"
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
</Button>
)}
</div>
</div>
))}
@ -766,7 +782,7 @@ export default function VisionPage() {
</h4>
<p className="text-sm text-gray-500">{meeting.time}</p>
</div>
<div className="flex items-center gap-2">
{canJoinMeeting(meeting) && (
<Button
size="sm"
variant="outline"
@ -775,15 +791,7 @@ export default function VisionPage() {
<Video className="h-4 w-4 mr-1" />
Rejoindre
</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>