vision refactor
This commit is contained in:
parent
22c944b17c
commit
cc787e040b
@ -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>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user