From 5d3a1d984df4886e7f870f74ef53f18d8118828b Mon Sep 17 00:00:00 2001 From: PietroUniSa Date: Fri, 3 Jan 2025 17:38:08 +0100 Subject: [PATCH 1/2] feat:risolte le correzioni della code review, implementando un sistema per evitare che si possano schedulare meeting allo stesso orario --- .../components/pages/CalendarioIncontri.jsx | 11 +--- .../pages/CalendarioIncontriMentee.jsx | 2 - app/src/components/pages/meeting-summary.jsx | 4 +- .../components/pages/mentee-statistics.jsx | 3 +- app/src/dao/meetingsDAO.js | 65 ++++++++++++------- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/app/src/components/pages/CalendarioIncontri.jsx b/app/src/components/pages/CalendarioIncontri.jsx index 154de5c..08edc7b 100644 --- a/app/src/components/pages/CalendarioIncontri.jsx +++ b/app/src/components/pages/CalendarioIncontri.jsx @@ -4,7 +4,6 @@ import Header from "@/components/ui/header"; import { Link } from 'react-router-dom'; import { Button } from "@/components/ui/button"; import { fetchMeetingsForMentor, filterDaysWithMeetings, updateMeeting, deleteMeeting } from "@/dao/meetingsDAO" -import { useParams } from 'react-router-dom'; import { useAuth } from '@/auth/auth-context'; const CalendarioIncontri = () => { @@ -13,16 +12,13 @@ const CalendarioIncontri = () => { const [currentMonth, setCurrentMonth] = useState(new Date().getMonth()); const [currentYear, setCurrentYear] = useState(new Date().getFullYear()); const [editingMeeting, setEditingMeeting] = useState(null); - const { meetingId } = useParams(); const {userId} = useAuth(); const fetchMeetings = async () => { try { const fetchedMeetings = await fetchMeetingsForMentor(userId); - console.log('Incontri recuperati:', fetchedMeetings); setMeetings(fetchedMeetings); } catch (error) { alert("Errore durante il recupero degli incontri."); - console.error(error); } }; @@ -31,27 +27,22 @@ const CalendarioIncontri = () => { }; const handleSaveEdit = async (updatedMeeting) => { - console.log("Tentativo di aggiornamento:", updatedMeeting); try { await updateMeeting(updatedMeeting.id, updatedMeeting); setMeetings((prevMeetings) => prevMeetings.map((m) => (m.id === updatedMeeting.id ? updatedMeeting : m)) ); setEditingMeeting(null); - console.log("Incontro aggiornato con successo."); } catch (error) { - console.error("Errore:", error); } }; const handleDelete = async (meetingId) => { - console.log("Tentativo di eliminazione incontro con ID:", meetingId); try { await deleteMeeting(meetingId); - console.log("Incontro eliminato con successo."); setMeetings((prevMeetings) => prevMeetings.filter((m) => m.id !== meetingId)); } catch (error) { - console.error("Errore:", error); + alert("Errore durante ll'eliminazione dell'incontro."); } }; diff --git a/app/src/components/pages/CalendarioIncontriMentee.jsx b/app/src/components/pages/CalendarioIncontriMentee.jsx index 058ac8c..29b8984 100644 --- a/app/src/components/pages/CalendarioIncontriMentee.jsx +++ b/app/src/components/pages/CalendarioIncontriMentee.jsx @@ -14,11 +14,9 @@ const CalendarioIncontri = () => { try { // Recuperiamo i meeting per il mentee const fetchedMeetings = await fetchMeetingsForMentee(userId); - console.log("Dati recuperati:", fetchedMeetings); // 👀 Debug setMeetings(fetchedMeetings); } catch (error) { alert("Errore durante il recupero degli incontri."); - console.error(error); } }; diff --git a/app/src/components/pages/meeting-summary.jsx b/app/src/components/pages/meeting-summary.jsx index b3deb3f..07a089d 100644 --- a/app/src/components/pages/meeting-summary.jsx +++ b/app/src/components/pages/meeting-summary.jsx @@ -13,13 +13,11 @@ function MeetingSummary() { const [successMessage, setSuccessMessage] = useState(""); // Stato per il messaggio di successo const location = useLocation(); - console.log('Location:', location); // Stampa l'intero URL e il pathname useEffect(() => { const fetchMeeting = async () => { try { const meetingData = await fetchMeetingDetails(meetingid); // Recupera i dettagli del meeting - console.log("ID:" + meetingid) setMeeting(meetingData); // Aggiorna lo stato con i dati del meeting } catch (err) { setError(err.message); // Gestisce eventuali errori @@ -36,7 +34,7 @@ function MeetingSummary() { await updateMeetingMinutes(meetingid, minuta); // Aggiorna le note del meeting setSuccessMessage("Informazioni salvate con successo!"); } catch (err) { - console.error("Errore nel salvataggio delle note:", err); + alert("Errore nel salvataggio delle note."); } }; diff --git a/app/src/components/pages/mentee-statistics.jsx b/app/src/components/pages/mentee-statistics.jsx index 8bf43a4..6d63779 100644 --- a/app/src/components/pages/mentee-statistics.jsx +++ b/app/src/components/pages/mentee-statistics.jsx @@ -8,7 +8,6 @@ import { useAuth } from "@/auth/auth-context"; export default function Statistics() { const [user, setUser] = useState(null); const [meetingsCount, setMeetingsCount] = useState(0); - const navigate = useNavigate(); const { userId } = useAuth(); useEffect(() => { @@ -18,7 +17,7 @@ export default function Statistics() { setUser(userData); // Salva i dati dell'utente setMeetingsCount(userData.meetingsCount || 0); // Ottieni il meetingsCount (default a 0 se non esiste) } catch (error) { - console.error("Errore durante il recupero dei dati dell'utente:", error); + allert("Errore durante il recupero dei dati dell'utente:"); } }; diff --git a/app/src/dao/meetingsDAO.js b/app/src/dao/meetingsDAO.js index 7609c02..58c7352 100644 --- a/app/src/dao/meetingsDAO.js +++ b/app/src/dao/meetingsDAO.js @@ -1,5 +1,5 @@ import { db } from "@/firebase/firebase"; -import { getFirestore, collection, query, where, getDocs, doc, updateDoc, deleteDoc, addDoc , getDoc , increment} from 'firebase/firestore'; +import { getFirestore, collection, query, where, getDocs, doc, updateDoc, deleteDoc, addDoc , getDoc , increment,Timestamp } from 'firebase/firestore'; /** * Recupera tutti gli incontri di un mentor dal database. @@ -28,7 +28,6 @@ export const fetchMeetingsForMentor = async (mentorId) => { }; }); } catch (error) { - console.error("Errore durante il recupero degli incontri:", error); throw new Error("Impossibile recuperare gli incontri."); } }; @@ -56,7 +55,6 @@ export const fetchMeetingsForMentee = async (menteeId) => { }; }); } catch (error) { - console.error("Errore durante il recupero degli incontri:", error); throw new Error("Impossibile recuperare gli incontri."); } }; @@ -96,7 +94,6 @@ export const fetchMeetingDetails = async (meetingId) => { minuta: meetingData.minuta || null, // Valore predefinito se mancante }; } catch (error) { - console.error("Errore durante il recupero dei dettagli dell'incontro:", error); throw new Error("Impossibile recuperare i dettagli dell'incontro."); } }; @@ -113,7 +110,6 @@ export const updateMeetingMinutes = async (meetingId, minuta) => { const meetingRef = doc(db, 'meetings', meetingId); await updateDoc(meetingRef, { minuta: minuta }); // Aggiorna solo il campo MINUTA } catch (error) { - console.error('Errore durante l\'aggiornamento della minuta:', error); throw error; } }; @@ -126,13 +122,42 @@ export const updateMeetingMinutes = async (meetingId, minuta) => { export const createMeeting = async (meetingData) => { try { - // Verifica che userType sia mentee - if (meetingData.userType !== 'mentee') { - throw new Error('Il tipo di utente deve essere mentee'); + if (meetingData.userType !== "mentee") { + throw new Error("Il tipo di utente deve essere mentee"); } - // Recupera il riferimento al documento del mentee nella collezione utenti - const menteeRef = doc(db, 'utenti', meetingData.menteeId); + // Converte la data in Timestamp Firestore + const meetingDate = meetingData.date instanceof Timestamp + ? meetingData.date + : Timestamp.fromDate(new Date(meetingData.date)); + + // Converte l'orario in minuti per confrontarlo + const [hours, minutes] = meetingData.time.split(":").map(Number); + const meetingMinutes = hours * 60 + minutes; // Converti in minuti totali + + // Query per trovare incontri nello stesso giorno con il mentor + const meetingsRef = collection(db, "meetings"); + const existingMeetingsQuery = query( + meetingsRef, + where("mentorId", "==", meetingData.mentorId), + where("date", "==", meetingDate) + ); + + const existingMeetingsSnapshot = await getDocs(existingMeetingsQuery); + + for (const doc of existingMeetingsSnapshot.docs) { + const existingMeeting = doc.data(); + const [existingHours, existingMinutes] = existingMeeting.time.split(":").map(Number); + const existingMeetingMinutes = existingHours * 60 + existingMinutes; // Converti in minuti totali + + // Controllo intervallo di 10 minuti + if (Math.abs(meetingMinutes - existingMeetingMinutes) < 10) { + throw new Error("Non è possibile schedulare un meeting a meno di 10 minuti di distanza da un altro."); + } + } + + // Recupera il riferimento al documento del mentee + const menteeRef = doc(db, "utenti", meetingData.menteeId); const menteeSnap = await getDoc(menteeRef); if (!menteeSnap.exists()) { @@ -141,12 +166,10 @@ export const createMeeting = async (meetingData) => { const menteeData = menteeSnap.data(); - // Se il campo meetingsCount esiste, incrementalo, altrimenti crealo e impostalo a 1 - if (typeof menteeData.meetingsCount === 'number') { - // Incrementa meetingsCount + // Aggiorna il contatore di meeting + if (typeof menteeData.meetingsCount === "number") { await updateDoc(menteeRef, { meetingsCount: increment(1) }); } else { - // Crea meetingsCount e imposta a 1 await updateDoc(menteeRef, { meetingsCount: 1 }); } @@ -155,20 +178,19 @@ export const createMeeting = async (meetingData) => { mentorId: meetingData.mentorId, menteeId: meetingData.menteeId, mentorName: meetingData.mentorName, - date: meetingData.date, + date: meetingDate, time: meetingData.time, topic: meetingData.topic, description: meetingData.description, menteeName: meetingData.menteeName, menteeEmail: meetingData.menteeEmail, - minuta: null, // Il campo MINUTA inizialmente è null + minuta: null, }; - // Aggiungi il nuovo incontro al database - const docRef = await addDoc(collection(db, 'meetings'), newMeeting); - return docRef.id; // Restituisce l'ID del documento appena creato + // Aggiungi il meeting al database + const docRef = await addDoc(collection(db, "meetings"), newMeeting); + return docRef.id; } catch (error) { - console.error('Errore durante la creazione dell\'incontro:', error); throw error; } }; @@ -184,7 +206,6 @@ export const updateMeeting = async (meetingId, updatedData) => { const meetingRef = doc(db, 'meetings', meetingId); await updateDoc(meetingRef, updatedData); } catch (error) { - console.error('Errore durante la modifica dell\'incontro:', error); throw error; } }; @@ -199,7 +220,6 @@ export const deleteMeeting = async (meetingId) => { const meetingRef = doc(db, 'meetings', meetingId); await deleteDoc(meetingRef); } catch (error) { - console.error('Errore durante l\'eliminazione dell\'incontro:', error); throw error; } }; @@ -238,7 +258,6 @@ export const getMentees = async () => { ...doc.data(), })); } catch (error) { - console.error('Errore durante il recupero dei mentee:', error); throw error; } }; \ No newline at end of file From edc93dc6a67de422b378994020b428d5ed47ee79 Mon Sep 17 00:00:00 2001 From: PietroUniSa Date: Fri, 3 Jan 2025 17:52:37 +0100 Subject: [PATCH 2/2] Feat:fix vari --- .../components/pages/CalendarioIncontri.jsx | 15 ++--- app/src/components/pages/MeetingScheduler.jsx | 15 +---- app/src/components/pages/meeting-summary.jsx | 2 - .../pages/meeting-summaryformentee.jsx | 2 +- .../components/pages/mentee-statistics.jsx | 2 +- app/src/dao/meetingsDAO.js | 55 ++++++++++++------- 6 files changed, 47 insertions(+), 44 deletions(-) diff --git a/app/src/components/pages/CalendarioIncontri.jsx b/app/src/components/pages/CalendarioIncontri.jsx index 08edc7b..d7406b6 100644 --- a/app/src/components/pages/CalendarioIncontri.jsx +++ b/app/src/components/pages/CalendarioIncontri.jsx @@ -1,4 +1,3 @@ -// Updated CalendarioIncontri.js with Edit and Delete import React, { useState, useEffect } from 'react'; import Header from "@/components/ui/header"; import { Link } from 'react-router-dom'; @@ -12,13 +11,14 @@ const CalendarioIncontri = () => { const [currentMonth, setCurrentMonth] = useState(new Date().getMonth()); const [currentYear, setCurrentYear] = useState(new Date().getFullYear()); const [editingMeeting, setEditingMeeting] = useState(null); - const {userId} = useAuth(); + const {userId,nome,cognome} = useAuth(); const fetchMeetings = async () => { try { const fetchedMeetings = await fetchMeetingsForMentor(userId); setMeetings(fetchedMeetings); } catch (error) { alert("Errore durante il recupero degli incontri."); + console.error(error); } }; @@ -28,21 +28,22 @@ const CalendarioIncontri = () => { const handleSaveEdit = async (updatedMeeting) => { try { - await updateMeeting(updatedMeeting.id, updatedMeeting); + await updateMeeting(updatedMeeting, updatedMeeting.menteeId,userId,nome,cognome); setMeetings((prevMeetings) => prevMeetings.map((m) => (m.id === updatedMeeting.id ? updatedMeeting : m)) ); setEditingMeeting(null); } catch (error) { + alert("Errore durante la modifica degli incontri."); } }; - const handleDelete = async (meetingId) => { + const handleDelete = async (meetingId,menteeId) => { try { - await deleteMeeting(meetingId); + await deleteMeeting(meetingId,menteeId,userId,nome,cognome); setMeetings((prevMeetings) => prevMeetings.filter((m) => m.id !== meetingId)); } catch (error) { - alert("Errore durante ll'eliminazione dell'incontro."); + alert("Errore durante l'eliminazione degli incontri."); } }; @@ -253,7 +254,7 @@ const CalendarioIncontri = () => { Modifica