diff --git a/components/calendar/event-dialog.tsx b/components/calendar/event-dialog.tsx index b0bb292..dfe3a37 100644 --- a/components/calendar/event-dialog.tsx +++ b/components/calendar/event-dialog.tsx @@ -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>([]); + const [missions, setMissions] = useState>([]); + + // 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({ +
+ + +
+
setLocation(e.target.value)} - placeholder='Ajouter un lieu' + placeholder={isVideoConference ? 'Lien Jitsi généré automatiquement' : 'Ajouter un lieu'} + disabled={isVideoConference} />