vision refactor
This commit is contained in:
parent
51f57417d6
commit
0a912b3ac9
@ -1,4 +1,5 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@ -57,6 +58,69 @@ export function EventDialog({
|
||||
const [allDay, setAllDay] = useState(event?.allDay || false);
|
||||
const [calendarId, setCalendarId] = useState(event?.calendarId || "");
|
||||
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||
const [isVideoConference, setIsVideoConference] = useState(!!event?.location?.includes('vision.slm-lab.net') || !!event?.location?.includes('jitsi'));
|
||||
const { data: session } = useSession();
|
||||
const [groups, setGroups] = useState<Array<{ id: string; name: string }>>([]);
|
||||
const [missions, setMissions] = useState<Array<{ id: string; name: string }>>([]);
|
||||
|
||||
// Reset form when event changes
|
||||
useEffect(() => {
|
||||
if (event) {
|
||||
setTitle(event.title || "");
|
||||
setDescription(event.description || "");
|
||||
setLocation(event.location || "");
|
||||
setStart(event.start || "");
|
||||
setEnd(event.end || "");
|
||||
setAllDay(event.allDay || false);
|
||||
setCalendarId(event.calendarId || "");
|
||||
setIsVideoConference(!!event.location?.includes('vision.slm-lab.net') || !!event.location?.includes('jitsi'));
|
||||
} else {
|
||||
// Reset form for new event
|
||||
setTitle("");
|
||||
setDescription("");
|
||||
setLocation("");
|
||||
setStart("");
|
||||
setEnd("");
|
||||
setAllDay(false);
|
||||
setCalendarId("");
|
||||
setIsVideoConference(false);
|
||||
}
|
||||
}, [event]);
|
||||
|
||||
// Fetch groups and missions when dialog opens
|
||||
useEffect(() => {
|
||||
if (open && session?.user?.id) {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Fetch groups
|
||||
const groupsRes = await fetch(`/api/users/${session.user.id}/groups`);
|
||||
if (groupsRes.ok) {
|
||||
const groupsData = await groupsRes.json();
|
||||
setGroups(Array.isArray(groupsData) ? groupsData : []);
|
||||
}
|
||||
|
||||
// Fetch missions
|
||||
const missionsRes = await fetch("/api/missions?limit=1000");
|
||||
if (missionsRes.ok) {
|
||||
const missionsData = await missionsRes.json();
|
||||
const allMissions = missionsData.missions || [];
|
||||
// Filter missions where user is creator or member
|
||||
const userMissions = allMissions.filter((mission: any) => {
|
||||
const isCreator = mission.creator?.id === session.user.id;
|
||||
const isMember = mission.missionUsers?.some(
|
||||
(mu: any) => mu.user?.id === session.user.id
|
||||
);
|
||||
return isCreator || isMember;
|
||||
});
|
||||
setMissions(userMissions);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching groups/missions:", error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}
|
||||
}, [open, session]);
|
||||
|
||||
// Formater les dates pour l'affichage
|
||||
const formatDate = (dateStr: string) => {
|
||||
@ -94,6 +158,93 @@ export function EventDialog({
|
||||
}
|
||||
};
|
||||
|
||||
// Generate Jitsi URL based on calendar type
|
||||
const generateJitsiUrl = (): string => {
|
||||
const selectedCalendar = calendars.find(cal => cal.id === calendarId);
|
||||
if (!selectedCalendar) return "";
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net';
|
||||
const calendarName = selectedCalendar.name || "";
|
||||
|
||||
// Check if it's a Group calendar
|
||||
if (calendarName.startsWith("Groupe:")) {
|
||||
const groupName = calendarName.replace("Groupe: ", "");
|
||||
// Find matching group by name to get the real ID
|
||||
const matchingGroup = groups.find((g: { id: string; name: string }) => g.name === groupName);
|
||||
if (matchingGroup) {
|
||||
return `${baseUrl}/Groupe-${matchingGroup.id}`;
|
||||
}
|
||||
// Fallback: use group name as ID (same as vision page fallback)
|
||||
const groupId = groupName.toLowerCase().replace(/\s+/g, '-');
|
||||
return `${baseUrl}/Groupe-${groupId}`;
|
||||
}
|
||||
|
||||
// Check if it's a Mission calendar
|
||||
if (calendarName.startsWith("Mission:")) {
|
||||
// Use missionId from calendar if available (most reliable)
|
||||
const missionId = (selectedCalendar as any).missionId;
|
||||
if (missionId) {
|
||||
return `${baseUrl}/${missionId}`;
|
||||
}
|
||||
// Fallback: find matching mission by name
|
||||
const missionName = calendarName.replace("Mission: ", "");
|
||||
const matchingMission = missions.find((m: { id: string; name: string }) => m.name === missionName);
|
||||
if (matchingMission) {
|
||||
return `${baseUrl}/${matchingMission.id}`;
|
||||
}
|
||||
// Last fallback: use mission name as ID
|
||||
const missionIdFromName = missionName.toLowerCase().replace(/\s+/g, '-');
|
||||
return `${baseUrl}/${missionIdFromName}`;
|
||||
}
|
||||
|
||||
// For "Mon Calendrier" or Microsoft calendars, generate a generic Jitsi room
|
||||
// Use a combination of user ID and timestamp for uniqueness
|
||||
const userId = session?.user?.id || 'user';
|
||||
const timestamp = Date.now();
|
||||
const randomId = Math.random().toString(36).substring(2, 9);
|
||||
return `${baseUrl}/${randomId}-${timestamp}`;
|
||||
};
|
||||
|
||||
// Handle video conference checkbox change
|
||||
const handleVideoConferenceChange = (checked: boolean) => {
|
||||
setIsVideoConference(checked);
|
||||
if (checked) {
|
||||
// Generate Jitsi URL and set it in location
|
||||
const jitsiUrl = generateJitsiUrl();
|
||||
setLocation(jitsiUrl);
|
||||
} else {
|
||||
// Clear location if unchecking
|
||||
setLocation("");
|
||||
}
|
||||
};
|
||||
|
||||
// Update location when calendar changes and video conference is checked
|
||||
useEffect(() => {
|
||||
if (isVideoConference && calendarId) {
|
||||
const jitsiUrl = generateJitsiUrl();
|
||||
setLocation(jitsiUrl);
|
||||
}
|
||||
}, [calendarId, isVideoConference]);
|
||||
|
||||
// Update location when groups/missions are loaded (to get correct IDs for groups/missions)
|
||||
useEffect(() => {
|
||||
if (isVideoConference && calendarId) {
|
||||
const selectedCalendar = calendars.find(cal => cal.id === calendarId);
|
||||
if (selectedCalendar) {
|
||||
const calendarName = selectedCalendar.name || "";
|
||||
const isGroup = calendarName.startsWith("Groupe:");
|
||||
const isMission = calendarName.startsWith("Mission:");
|
||||
|
||||
// Only update if it's a group/mission and we now have the data
|
||||
if ((isGroup && groups.length > 0) || (isMission && missions.length > 0)) {
|
||||
const jitsiUrl = generateJitsiUrl();
|
||||
setLocation(jitsiUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [groups.length, missions.length]);
|
||||
|
||||
// Enregistrer l'événement
|
||||
const handleSave = () => {
|
||||
onSave({
|
||||
@ -193,13 +344,24 @@ export function EventDialog({
|
||||
<Label htmlFor='all-day'>Toute la journée</Label>
|
||||
</div>
|
||||
|
||||
<div className='flex items-center gap-2'>
|
||||
<Checkbox
|
||||
id='video-conference'
|
||||
checked={isVideoConference}
|
||||
onCheckedChange={handleVideoConferenceChange}
|
||||
disabled={!calendarId}
|
||||
/>
|
||||
<Label htmlFor='video-conference'>Visioconférence</Label>
|
||||
</div>
|
||||
|
||||
<div className='grid gap-2'>
|
||||
<Label htmlFor='location'>Lieu (optionnel)</Label>
|
||||
<Input
|
||||
id='location'
|
||||
value={location}
|
||||
onChange={(e) => setLocation(e.target.value)}
|
||||
placeholder='Ajouter un lieu'
|
||||
placeholder={isVideoConference ? 'Lien Jitsi généré automatiquement' : 'Ajouter un lieu'}
|
||||
disabled={isVideoConference}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user