Working EditMobility

This commit is contained in:
Clayzxr
2025-01-27 11:11:44 +01:00
parent 9d828069a5
commit 37d2753c56
+121 -169
View File
@@ -1,117 +1,93 @@
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
interface Student {
id: string;
firstName: string;
lastName: string;
promotionId: number;
}
interface Promotion { interface Promotion {
id: number; id: number;
name: string; name: string;
} }
interface Mobility { interface MobilityData {
id: number | null; id: number | null; // null pour les nouvelles entrées
studentId: string; studentId: string;
firstName: string;
lastName: string;
startDate: string | null; startDate: string | null;
endDate: string | null; endDate: string | null;
weeksCount: number | null; weeksCount: number | null;
destinationCountry: string | null; destinationCountry: string | null;
destinationName: string | null; destinationName: string | null;
mobilityStatus: string; mobilityStatus: string;
promotionId: number;
promotionName: string;
} }
export default function EditMobility() { export default function EditMobility() {
const [data, setData] = useState< const [mobilityData, setMobilityData] = useState<MobilityData[]>([]);
| { const [promotions, setPromotions] = useState<Promotion[]>([]);
promotions?: Promotion[];
students?: Student[];
mobilities?: Mobility[];
}
| null
>(null);
const [error, setError] = useState<string | null>(null);
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
useEffect(() => { useEffect(() => {
const fetchData = async () => { async function fetchMobilityData() {
console.log("EditMobility: Fetching data from API..."); console.log("EditMobility: Fetching data from API...");
try { const response = await fetch("/mobility/api/insert_mobility");
const response = await fetch("/mobility/api/insert_mobility"); const data = await response.json();
console.log("EditMobility: API response status:", response.status); console.log("EditMobility: Data fetched successfully:", data);
if (!response.ok) { setPromotions(data.promotions);
throw new Error(`Error fetching data: ${response.statusText}`);
}
const result = await response.json(); const initializedData = data.students.map((student: any) => {
console.log("EditMobility: Data fetched successfully:", result); const existingMobility = data.mobilities.find(
setData(result); (mobility: any) => mobility.studentId === student.id
} catch (err) { );
console.error("EditMobility: Error fetching data:", err); return {
setError("Failed to load mobility data. Please try again later."); id: existingMobility ? existingMobility.id : null, // null si aucune mobilité existante
} studentId: student.id,
}; firstName: student.firstName,
lastName: student.lastName,
startDate: existingMobility?.startDate || null,
endDate: existingMobility?.endDate || null,
weeksCount: existingMobility?.weeksCount || null,
destinationCountry: existingMobility?.destinationCountry || null,
destinationName: existingMobility?.destinationName || null,
mobilityStatus: existingMobility?.mobilityStatus || "N/A",
promotionId: student.promotionId,
promotionName: student.promotionName,
};
});
setMobilityData(initializedData);
}
fetchData(); fetchMobilityData();
}, []); }, []);
const handleChange = ( const handleChange = (
studentId: string, studentId: string,
field: keyof Mobility, field: keyof MobilityData,
value: string | number | null, value: string | number | null
) => { ) => {
if (!data) return; setMobilityData((prev) =>
prev.map((entry) =>
setData((prevData) => { entry.studentId === studentId ? { ...entry, [field]: value } : entry
if (!prevData) return null; )
);
const updatedMobilities = prevData.mobilities?.map((mobility) => {
if (mobility.studentId === studentId) {
const updatedMobility = { ...mobility, [field]: value };
if (field === "startDate" || field === "endDate") {
const startDate = new Date(updatedMobility.startDate || "");
const endDate = new Date(updatedMobility.endDate || "");
if (startDate && endDate && startDate <= endDate) {
const weeks = Math.ceil(
(endDate.getTime() - startDate.getTime()) /
(7 * 24 * 60 * 60 * 1000),
);
updatedMobility.weeksCount = weeks;
} else {
updatedMobility.weeksCount = null;
}
}
return updatedMobility;
}
return mobility;
}) || [];
return { ...prevData, mobilities: updatedMobilities };
});
}; };
const handleSave = async () => { const handleSave = async () => {
setIsSaving(true); setIsSaving(true);
try { try {
console.log("EditMobility: Sending data to API...");
const response = await fetch("/mobility/api/insert_mobility", { const response = await fetch("/mobility/api/insert_mobility", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: data?.mobilities }), body: JSON.stringify({ data: mobilityData }),
}); });
console.log("EditMobility: Save response status:", response.status);
if (response.ok) { if (response.ok) {
alert("Data saved successfully!"); alert("Data saved successfully!");
globalThis.location.reload(); console.log("EditMobility: Save response status:", response.status);
} else { } else {
throw new Error(`Failed to save data: ${response.statusText}`); alert("Failed to save data.");
console.error("EditMobility: Save response status:", response.status);
} }
} catch (error) { } catch (error) {
console.error("EditMobility: Error saving data:", error); console.error("EditMobility: Error saving data:", error);
@@ -121,20 +97,20 @@ export default function EditMobility() {
} }
}; };
if (error) { // Grouper les données par promotion
return <p className="error">{error}</p>; const groupedData = promotions.map((promo) => ({
} promotion: promo.name,
students: mobilityData.filter(
if (!data?.promotions) { (entry) => entry.promotionId === promo.id
return <p>Loading data...</p>; ),
} }));
return ( return (
<section> <div>
<h2>Edit Mobility</h2> <h2>Edit Mobility</h2>
{data.promotions.map((promo) => ( {groupedData.map((group) => (
<div key={promo.id}> <div key={group.promotion}>
<h3>Promotion: {promo.name}</h3> <h3>Promotion: {group.promotion}</h3>
<table> <table>
<thead> <thead>
<tr> <tr>
@@ -150,92 +126,68 @@ export default function EditMobility() {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{data.students {group.students.map((entry) => (
?.filter((student) => student.promotionId === promo.id) <tr key={entry.studentId}>
.map((student) => { <td>{entry.studentId}</td>
const mobility = data.mobilities?.find((mob) => <td>{entry.firstName}</td>
mob.studentId === student.id <td>{entry.lastName}</td>
) || { <td>
id: null, <input
studentId: student.id, type="date"
startDate: null, value={entry.startDate || ""}
endDate: null, onChange={(e) =>
weeksCount: null, handleChange(entry.studentId, "startDate", e.target.value)
destinationCountry: null, }
destinationName: null, />
mobilityStatus: "N/A", </td>
}; <td>
<input
return ( type="date"
<tr key={student.id}> value={entry.endDate || ""}
<td>{student.id}</td> onChange={(e) =>
<td>{student.firstName}</td> handleChange(entry.studentId, "endDate", e.target.value)
<td>{student.lastName}</td> }
<td> />
<input </td>
type="date" <td>{entry.weeksCount || "N/A"}</td>
value={mobility.startDate || ""} <td>
onChange={(e) => <input
handleChange( type="text"
student.id, value={entry.destinationCountry || ""}
"startDate", onChange={(e) =>
e.target.value, handleChange(
)} entry.studentId,
/> "destinationCountry",
</td> e.target.value
<td> )
<input }
type="date" />
value={mobility.endDate || ""} </td>
onChange={(e) => <td>
handleChange(student.id, "endDate", e.target.value)} <input
/> type="text"
</td> value={entry.destinationName || ""}
<td>{mobility.weeksCount ?? "N/A"}</td> onChange={(e) =>
<td> handleChange(entry.studentId, "destinationName", e.target.value)
<input }
type="text" />
value={mobility.destinationCountry || ""} </td>
onChange={(e) => <td>
handleChange( <select
student.id, value={entry.mobilityStatus}
"destinationCountry", onChange={(e) =>
e.target.value, handleChange(entry.studentId, "mobilityStatus", e.target.value)
)} }
/> >
</td> <option value="N/A">N/A</option>
<td> <option value="Planned">Planned</option>
<input <option value="In Progress">In Progress</option>
type="text" <option value="Completed">Completed</option>
value={mobility.destinationName || ""} <option value="Validated">Validated</option>
onChange={(e) => </select>
handleChange( </td>
student.id, </tr>
"destinationName", ))}
e.target.value,
)}
/>
</td>
<td>
<select
value={mobility.mobilityStatus}
onChange={(e) =>
handleChange(
student.id,
"mobilityStatus",
e.target.value,
)}
>
<option value="N/A">N/A</option>
<option value="Planned">Planned</option>
<option value="In Progress">In Progress</option>
<option value="Completed">Completed</option>
<option value="Validated">Validated</option>
</select>
</td>
</tr>
);
})}
</tbody> </tbody>
</table> </table>
</div> </div>
@@ -243,6 +195,6 @@ export default function EditMobility() {
<button onClick={handleSave} disabled={isSaving}> <button onClick={handleSave} disabled={isSaving}>
{isSaving ? "Saving..." : "Confirm"} {isSaving ? "Saving..." : "Confirm"}
</button> </button>
</section> </div>
); );
} }