vision refactor
This commit is contained in:
parent
cc787e040b
commit
0ef38dc5dd
@ -50,6 +50,7 @@ interface ScheduledMeeting {
|
|||||||
start: string; // ISO datetime string for start
|
start: string; // ISO datetime string for start
|
||||||
end: string; // ISO datetime string for end
|
end: string; // ISO datetime string for end
|
||||||
isAllDay?: boolean;
|
isAllDay?: boolean;
|
||||||
|
location?: string; // Jitsi URL for Vision meetings
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConferenceType = "group" | "mission" | null;
|
type ConferenceType = "group" | "mission" | null;
|
||||||
@ -81,6 +82,7 @@ export default function VisionPage() {
|
|||||||
location: string;
|
location: string;
|
||||||
description: string;
|
description: string;
|
||||||
recurrence: "none" | "daily" | "weekly" | "monthly";
|
recurrence: "none" | "daily" | "weekly" | "monthly";
|
||||||
|
isVideoConference: boolean;
|
||||||
}>({
|
}>({
|
||||||
type: "",
|
type: "",
|
||||||
entityId: "",
|
entityId: "",
|
||||||
@ -92,6 +94,7 @@ export default function VisionPage() {
|
|||||||
location: "",
|
location: "",
|
||||||
description: "",
|
description: "",
|
||||||
recurrence: "none",
|
recurrence: "none",
|
||||||
|
isVideoConference: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Redirect if not authenticated
|
// Redirect if not authenticated
|
||||||
@ -149,6 +152,7 @@ export default function VisionPage() {
|
|||||||
start: event.start,
|
start: event.start,
|
||||||
end: event.end,
|
end: event.end,
|
||||||
isAllDay: event.isAllDay || false,
|
isAllDay: event.isAllDay || false,
|
||||||
|
location: event.location || undefined, // Include Jitsi URL if available
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -243,18 +247,29 @@ export default function VisionPage() {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, [session, status, toast]);
|
}, [session, status, toast]);
|
||||||
|
|
||||||
// Handle conference selection
|
// Generate Jitsi URL (shared function used by both handleConferenceClick and form)
|
||||||
const handleConferenceClick = (type: ConferenceType, id: string, name: string) => {
|
const generateJitsiUrl = (type: "group" | "mission", id: string): string => {
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net';
|
const baseUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net';
|
||||||
|
|
||||||
let url: string;
|
|
||||||
if (type === "group") {
|
if (type === "group") {
|
||||||
// URL format: https://vision.slm-lab.net/Groupe-{groupId}
|
// URL format: https://vision.slm-lab.net/Groupe-{groupId}
|
||||||
url = `${baseUrl}/Groupe-${id}`;
|
return `${baseUrl}/Groupe-${id}`;
|
||||||
} else {
|
} else {
|
||||||
// URL format: https://vision.slm-lab.net/{missionId}
|
// URL format: https://vision.slm-lab.net/{missionId}
|
||||||
url = `${baseUrl}/${id}`;
|
return `${baseUrl}/${id}`;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle conference selection
|
||||||
|
const handleConferenceClick = (type: ConferenceType, id: string, name: string, jitsiUrl?: string) => {
|
||||||
|
// If Jitsi URL is provided (from meeting location), use it directly
|
||||||
|
if (jitsiUrl) {
|
||||||
|
setSelectedConference({ type, id, name });
|
||||||
|
setJitsiUrl(jitsiUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, generate URL from type and id using shared function
|
||||||
|
const url = generateJitsiUrl(type, id);
|
||||||
|
|
||||||
setSelectedConference({ type, id, name });
|
setSelectedConference({ type, id, name });
|
||||||
setJitsiUrl(url);
|
setJitsiUrl(url);
|
||||||
@ -322,10 +337,17 @@ export default function VisionPage() {
|
|||||||
location: "",
|
location: "",
|
||||||
description: "",
|
description: "",
|
||||||
recurrence: "none",
|
recurrence: "none",
|
||||||
|
isVideoConference: false,
|
||||||
});
|
});
|
||||||
setShowMeetingDialog(true);
|
setShowMeetingDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generate Jitsi URL based on meeting form (uses shared function)
|
||||||
|
const getJitsiUrl = (): string => {
|
||||||
|
if (!meetingForm.type || !meetingForm.entityId) return "";
|
||||||
|
return generateJitsiUrl(meetingForm.type, meetingForm.entityId);
|
||||||
|
};
|
||||||
|
|
||||||
// Handle save meeting
|
// Handle save meeting
|
||||||
const handleSaveMeeting = async () => {
|
const handleSaveMeeting = async () => {
|
||||||
if (!meetingForm.type || !meetingForm.entityId || !meetingForm.start || !meetingForm.end) {
|
if (!meetingForm.type || !meetingForm.entityId || !meetingForm.start || !meetingForm.end) {
|
||||||
@ -411,6 +433,9 @@ export default function VisionPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine location: use Jitsi URL if video conference is enabled, otherwise use manual location
|
||||||
|
const locationToSave = meetingForm.isVideoConference ? getJitsiUrl() : (meetingForm.location || null);
|
||||||
|
|
||||||
// Create all events via API
|
// Create all events via API
|
||||||
const eventPromises = eventsToCreate.map(async ({ start, end }) => {
|
const eventPromises = eventsToCreate.map(async ({ start, end }) => {
|
||||||
const response = await fetch("/api/events", {
|
const response = await fetch("/api/events", {
|
||||||
@ -424,7 +449,7 @@ export default function VisionPage() {
|
|||||||
start: start.toISOString(),
|
start: start.toISOString(),
|
||||||
end: end.toISOString(),
|
end: end.toISOString(),
|
||||||
allDay: meetingForm.allDay,
|
allDay: meetingForm.allDay,
|
||||||
location: meetingForm.location || null,
|
location: locationToSave,
|
||||||
calendarId: targetCalendar.id,
|
calendarId: targetCalendar.id,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@ -458,6 +483,7 @@ export default function VisionPage() {
|
|||||||
location: "",
|
location: "",
|
||||||
description: "",
|
description: "",
|
||||||
recurrence: "none",
|
recurrence: "none",
|
||||||
|
isVideoConference: false,
|
||||||
});
|
});
|
||||||
toast({
|
toast({
|
||||||
title: "Succès",
|
title: "Succès",
|
||||||
@ -611,7 +637,7 @@ export default function VisionPage() {
|
|||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
className="bg-blue-600 hover:bg-blue-700 text-white"
|
className="bg-blue-600 hover:bg-blue-700 text-white"
|
||||||
onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName)}
|
onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName, meeting.location)}
|
||||||
>
|
>
|
||||||
<Video className="h-4 w-4 mr-1" />
|
<Video className="h-4 w-4 mr-1" />
|
||||||
Rejoindre
|
Rejoindre
|
||||||
@ -786,7 +812,7 @@ export default function VisionPage() {
|
|||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName)}
|
onClick={() => handleConferenceClick(meeting.type, meeting.entityId, meeting.entityName, meeting.location)}
|
||||||
>
|
>
|
||||||
<Video className="h-4 w-4 mr-1" />
|
<Video className="h-4 w-4 mr-1" />
|
||||||
Rejoindre
|
Rejoindre
|
||||||
@ -1081,16 +1107,56 @@ export default function VisionPage() {
|
|||||||
<Label htmlFor="allDay" className="text-gray-800">Toute la journée</Label>
|
<Label htmlFor="allDay" className="text-gray-800">Toute la journée</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="grid gap-2">
|
||||||
<Label className="text-gray-800">Lieu</Label>
|
<div className="flex items-center space-x-2 mb-2">
|
||||||
<Input
|
<Checkbox
|
||||||
value={meetingForm.location}
|
id="isVideoConference"
|
||||||
onChange={(e) =>
|
checked={meetingForm.isVideoConference}
|
||||||
setMeetingForm({ ...meetingForm, location: e.target.value })
|
onCheckedChange={(checked) => {
|
||||||
}
|
const isChecked = checked as boolean;
|
||||||
placeholder="Ajouter un lieu"
|
setMeetingForm({
|
||||||
className="bg-white text-gray-900"
|
...meetingForm,
|
||||||
/>
|
isVideoConference: isChecked,
|
||||||
|
// If enabling video conference, generate Jitsi URL
|
||||||
|
// If disabling, clear location
|
||||||
|
location: isChecked ? getJitsiUrl() : ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
htmlFor="isVideoConference"
|
||||||
|
className="text-base font-semibold text-gray-800 cursor-pointer"
|
||||||
|
>
|
||||||
|
Visioconférence
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
{meetingForm.isVideoConference ? (
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Input
|
||||||
|
id="meeting-location"
|
||||||
|
value={getJitsiUrl()}
|
||||||
|
disabled
|
||||||
|
className="bg-gray-100 text-gray-600 cursor-not-allowed"
|
||||||
|
placeholder="Lien Jitsi généré automatiquement"
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-gray-500">
|
||||||
|
Le lien Jitsi sera généré automatiquement pour cette réunion
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label htmlFor="meeting-location" className="text-gray-800">Lieu</Label>
|
||||||
|
<Input
|
||||||
|
id="meeting-location"
|
||||||
|
value={meetingForm.location}
|
||||||
|
onChange={(e) =>
|
||||||
|
setMeetingForm({ ...meetingForm, location: e.target.value })
|
||||||
|
}
|
||||||
|
placeholder="Ajouter un lieu"
|
||||||
|
className="bg-white text-gray-900"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@ -1148,6 +1214,7 @@ export default function VisionPage() {
|
|||||||
location: "",
|
location: "",
|
||||||
description: "",
|
description: "",
|
||||||
recurrence: "none",
|
recurrence: "none",
|
||||||
|
isVideoConference: false,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="bg-white hover:bg-gray-50 text-gray-900 border-gray-200"
|
className="bg-white hover:bg-gray-50 text-gray-900 border-gray-200"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user