diff --git a/src/App.js b/src/App.js index 2fe0fce98378cb9e25a62d627a0a0a8c57065054..d40c68750439d282098bfafa9539b53f883430ad 100644 --- a/src/App.js +++ b/src/App.js @@ -7,12 +7,19 @@ import StudentList from "./components/StudentList"; import CandidacyList from "./components/CandidacyList"; import UnivSupervisorList from "./components/UnivSupervisorList"; -// Import the new forms +// Import the forms import StageForm from "./components/StageForm"; import EnterpriseForm from "./components/EnterpriseForm"; import StudentForm from "./components/StudentForm"; import CandidacyForm from "./components/CandidacyForm"; -import UnivSupervisorForm from "./components/UnivSupervisorForm.jsx"; +import UnivSupervisorForm from "./components/UnivSupervisorForm"; + +// Import the update form +import UpdateCandidacyForm from "./components/UpdateCandidacyForm"; +import UpdateEnterpriseForm from "./components/UpdateEnterpriseForm.jsx"; +import UpdateStageForm from "./components/UpdateStageForm.jsx"; +import UpdateStudentForm from "./components/UpdateStudentForm.jsx"; +import UpdateUnivSupervisorForm from "./components/UpdateUnivSupervisorForm.jsx"; function App() { return ( @@ -33,7 +40,12 @@ function App() { <Route path="/ajouter-candidature" element={<CandidacyForm />} /> <Route path="/ajouter-univsuperviseur" element={<UnivSupervisorForm />} /> - + {/* Routes for Updating */} + <Route path="/modifier-candidature/:id" element={<UpdateCandidacyForm />} /> + <Route path="/modifier-entreprise/:id" element={<UpdateEnterpriseForm />} /> + <Route path="/modifier-etudiant/:id" element={<UpdateStudentForm/>} /> + <Route path="/modifier-etudiant/:id" element={<UpdateStudentForm/>} /> + <Route path="/modifier-univsuperviseur/:id" element={<UpdateUnivSupervisorForm />} /> {/* Default Route */} <Route path="/" element={<h2>Bienvenue sur l'Application de Gestion des Stages</h2>} /> </Routes> diff --git a/src/components/CandidacyForm.jsx b/src/components/CandidacyForm.jsx index 80fd32fb34e3783f89c11efab36738d77dd452d4..6a7bb6a84ca71ff2669a878235e65a3ee0a9d4b1 100644 --- a/src/components/CandidacyForm.jsx +++ b/src/components/CandidacyForm.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import { Navigate } from "react-router-dom"; const CandidacyForm = () => { const [students, setStudents] = useState([]); @@ -48,6 +49,10 @@ const CandidacyForm = () => { }) .catch((err) => console.error("Error:", err)); }; + // Handle cancel button + const handleCancel = () => { + Navigate("/candidatures"); // Redirect back to candidacy list + }; return ( <div className="container mt-4"> @@ -111,9 +116,12 @@ const CandidacyForm = () => { </div> {/* Submit Button */} - <button type="submit" className="btn btn-primary"> - Ajouter Candidature - </button> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-primary"> + Ajouter Candidature + </button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> </form> </div> ); diff --git a/src/components/CandidacyList.jsx b/src/components/CandidacyList.jsx index 4a8cd8bfe486720b26b2c8c4117744d560a6f27d..cfc2733dc1b625606b67c0ea8a85e0fe64569e13 100644 --- a/src/components/CandidacyList.jsx +++ b/src/components/CandidacyList.jsx @@ -1,18 +1,38 @@ -import React, { useEffect, useState } from "react"; +import React, { useState, useEffect } from "react"; +import { Link, useNavigate } from "react-router-dom"; -const CandidacyList = () => { +function CandidacyList() { const [candidacies, setCandidacies] = useState([]); + const navigate = useNavigate(); useEffect(() => { fetch("http://localhost:8080/api/candidacies") .then((res) => res.json()) .then((data) => setCandidacies(data)) - .catch((err) => console.error("Erreur lors du chargement:", err)); + .catch((err) => console.error("Erreur lors de la récupération :", err)); }, []); + // Function to delete candidacy + const handleDelete = (id) => { + if (window.confirm("Êtes-vous sûr de vouloir supprimer cette candidature ?")) { + fetch(`http://localhost:8080/api/candidacies/${id}`, { method: "DELETE" }) + .then(() => { + alert("Candidature supprimée avec succès !"); + setCandidacies(candidacies.filter((candidacy) => candidacy.id !== id)); + }) + .catch((err) => console.error("Erreur lors de la suppression :", err)); + } + }; + return ( <div className="container mt-4"> <h2>Liste des Candidatures</h2> + <div> + <Link to="/ajouter-candidature" className="btn btn-success mt-3"> + Ajouter une candidature + </Link> + </div> + <br /> <table className="table table-striped"> <thead> <tr> @@ -20,24 +40,40 @@ const CandidacyList = () => { <th>Étudiant</th> <th>Stage</th> <th>Superviseur Universitaire</th> + <th>État de la Demande</th> + <th>Statut Accepté</th> + <th>Actions</th> {/* Added column for buttons */} </tr> </thead> <tbody> {candidacies.map((candidacy) => ( <tr key={candidacy.id}> <td>{candidacy.id}</td> + <td>{candidacy.student?.firstname} {candidacy.student?.lastname}</td> + <td>{candidacy.stage?.name}</td> + <td>{candidacy.univSupervisor?.name || "Non attribué"}</td> + <td>{candidacy.requestState}</td> + <td>{candidacy.acceptedState}</td> <td> - {candidacy.student.firstname} {candidacy.student.lastname} + <button + className="btn btn-warning btn-sm me-2" + onClick={() => navigate(`/modifier-candidature/${candidacy.id}`)} + > + Modifier + </button> + <button + className="btn btn-danger btn-sm" + onClick={() => handleDelete(candidacy.id)} + > + Supprimer + </button> </td> - <td>{candidacy.stage.name}</td> - - <td>{candidacy.univSupervisor.name}</td> </tr> ))} </tbody> </table> </div> ); -}; +} export default CandidacyList; diff --git a/src/components/EnterpriseForm.jsx b/src/components/EnterpriseForm.jsx index 1086700519988360ab0b7aa8fabd6f185c1eaf83..08249a253093980f0af14edf836a722b213c8105 100644 --- a/src/components/EnterpriseForm.jsx +++ b/src/components/EnterpriseForm.jsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { Navigate } from "react-router-dom"; function EnterpriseForm() { const [name, setName] = useState(""); @@ -22,7 +23,10 @@ function EnterpriseForm() { }) .catch((err) => console.error("Erreur lors de l'ajout de l'entreprise :", err)); }; - + // Handle cancel button + const handleCancel = () => { + Navigate("/entreprises"); // Redirect back to candidacy list + }; return ( <div className="container mt-4"> <h2>Ajouter une Entreprise</h2> @@ -35,7 +39,12 @@ function EnterpriseForm() { <label className="form-label">Adresse</label> <input type="text" className="form-control" value={address} onChange={(e) => setAddress(e.target.value)} required /> </div> - <button type="submit" className="btn btn-primary">Ajouter</button> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-primary"> + Ajouter + </button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> </form> </div> ); diff --git a/src/components/EnterpriseList.jsx b/src/components/EnterpriseList.jsx index d5b393c18132810a297dadd3c20be25a22f46fc2..3546fb2ed6b681c3b0e734a039a7f56b4964f6d2 100644 --- a/src/components/EnterpriseList.jsx +++ b/src/components/EnterpriseList.jsx @@ -1,24 +1,57 @@ import React, { useState, useEffect } from "react"; +import { Link, useNavigate } from "react-router-dom"; function EnterpriseList() { const [enterprises, setEnterprises] = useState([]); + const navigate = useNavigate(); + // Fetch Enterprises useEffect(() => { + fetchEnterprises(); + }, []); + + const fetchEnterprises = () => { fetch("http://localhost:8080/api/enterprises") .then((response) => response.json()) .then((data) => setEnterprises(data)) .catch((error) => console.error("Error fetching enterprises:", error)); - }, []); + }; + + // Handle Delete + const handleDelete = (id) => { + if (window.confirm("Voulez-vous vraiment supprimer cette entreprise ?")) { + fetch(`http://localhost:8080/api/enterprises/${id}`, { + method: "DELETE", + }) + .then(() => { + alert("Entreprise supprimée avec succès !"); + fetchEnterprises(); // Refresh list after delete + }) + .catch((error) => console.error("Error deleting enterprise:", error)); + } + }; + + // Handle Update + const handleUpdate = (id) => { + navigate(`/modifier-entreprise/${id}`); + }; return ( <div className="container mt-4"> <h2 className="mb-4">Liste des Entreprises</h2> + <div> + <Link to="/ajouter-entreprise" className="btn btn-success mt-3"> + Ajouter une entreprise + </Link> + </div> + <br /> <table className="table table-striped table-hover"> <thead className="table-primary"> <tr> <th>ID</th> <th>Nom</th> <th>Adresse</th> + <th>Actions</th> </tr> </thead> <tbody> @@ -27,6 +60,20 @@ function EnterpriseList() { <td>{enterprise.id}</td> <td>{enterprise.name}</td> <td>{enterprise.address}</td> + <td> + <button + className="btn btn-warning btn-sm me-2" + onClick={() => handleUpdate(enterprise.id)} + > + Modifier + </button> + <button + className="btn btn-danger btn-sm" + onClick={() => handleDelete(enterprise.id)} + > + Supprimer + </button> + </td> </tr> ))} </tbody> diff --git a/src/components/StageForm.jsx b/src/components/StageForm.jsx index ff8f36808c2e1bf35d5d2bc84577510e39b6a59c..07f669f9e0ab538ba39fd675a6bf0944fe8074df 100644 --- a/src/components/StageForm.jsx +++ b/src/components/StageForm.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import { Navigate } from "react-router-dom"; function StageForm() { const [name, setName] = useState(""); @@ -36,6 +37,10 @@ function StageForm() { }) .catch((err) => console.error("Error adding stage:", err)); }; + // Handle cancel button + const handleCancel = () => { + Navigate("/stages"); // Redirect back to candidacy list + }; return ( <div className="container mt-4"> @@ -58,8 +63,12 @@ function StageForm() { ))} </select> </div> - <button type="submit" className="btn btn-primary">Ajouter</button> - </form> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-primary"> + Ajouter + </button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> </form> </div> ); } diff --git a/src/components/StageList.jsx b/src/components/StageList.jsx index f1bcb1bf16fc14ab04b518a68f88c59b36c62bff..782e3ca27bf0837d7010867559100d476c80e1bf 100644 --- a/src/components/StageList.jsx +++ b/src/components/StageList.jsx @@ -1,18 +1,51 @@ import React, { useState, useEffect } from "react"; +import { Link, useNavigate } from "react-router-dom"; function StageList() { const [stages, setStages] = useState([]); + const navigate = useNavigate(); + // Fetch Stages useEffect(() => { + fetchStages(); + }, []); + + const fetchStages = () => { fetch("http://localhost:8080/api/stages") .then((response) => response.json()) .then((data) => setStages(data)) .catch((error) => console.error("Error fetching stages:", error)); - }, []); + }; + + // Handle Delete + const handleDelete = (id) => { + if (window.confirm("Voulez-vous vraiment supprimer ce stage ?")) { + fetch(`http://localhost:8080/api/stages/${id}`, { + method: "DELETE", + }) + .then(() => { + alert("Stage supprimé avec succès !"); + fetchStages(); // Refresh list after delete + }) + .catch((error) => console.error("Error deleting stage:", error)); + } + }; + + // Handle Update + const handleUpdate = (id) => { + navigate(`/modifier-stage/${id}`); + }; return ( <div className="container mt-4"> <h2 className="mb-4">Liste des Stages</h2> + <div> + <Link to="/ajouter-stage" className="btn btn-success mt-3"> + Ajouter un stage + </Link> + </div> + <br /> + <table className="table table-striped table-hover"> <thead className="table-success"> <tr> @@ -20,6 +53,7 @@ function StageList() { <th>Nom</th> <th>Description</th> <th>Entreprise</th> + <th>Actions</th> </tr> </thead> <tbody> @@ -28,7 +62,21 @@ function StageList() { <td>{stage.id}</td> <td>{stage.name}</td> <td>{stage.description}</td> - <td>{stage.enterprise?.name}</td> + <td>{stage.enterprise?.name || "Non attribué"}</td> + <td> + <button + className="btn btn-warning btn-sm me-2" + onClick={() => handleUpdate(stage.id)} + > + Modifier + </button> + <button + className="btn btn-danger btn-sm" + onClick={() => handleDelete(stage.id)} + > + Supprimer + </button> + </td> </tr> ))} </tbody> diff --git a/src/components/StudentForm.jsx b/src/components/StudentForm.jsx index cbfcea051c9c53d059df67c6f16df9bce30bcc45..1332107a1b3f49ea39a7b2885866799b1309af55 100644 --- a/src/components/StudentForm.jsx +++ b/src/components/StudentForm.jsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { Navigate } from "react-router-dom"; function StudentForm() { const [firstname, setFirstname] = useState(""); @@ -22,6 +23,10 @@ function StudentForm() { }) .catch((err) => console.error("Erreur lors de l'ajout de l'étudiant :", err)); }; + // Handle cancel button + const handleCancel = () => { + Navigate("/etudiants"); // Redirect back to candidacy list + }; return ( <div className="container mt-4"> @@ -35,8 +40,12 @@ function StudentForm() { <label className="form-label">Nom</label> <input type="text" className="form-control" value={lastname} onChange={(e) => setLastname(e.target.value)} required /> </div> - <button type="submit" className="btn btn-primary">Ajouter</button> - </form> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-primary"> + Ajouter + </button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> </form> </div> ); } diff --git a/src/components/StudentList.jsx b/src/components/StudentList.jsx index 359b0d1db2be44436f7c9ce30630b9db30788ec5..80266ec3034f00945d6c22c911b67883f640e09b 100644 --- a/src/components/StudentList.jsx +++ b/src/components/StudentList.jsx @@ -1,24 +1,57 @@ import React, { useState, useEffect } from "react"; +import { Link, useNavigate } from "react-router-dom"; function StudentList() { const [students, setStudents] = useState([]); + const navigate = useNavigate(); + // Fetch Students useEffect(() => { + fetchStudents(); + }, []); + + const fetchStudents = () => { fetch("http://localhost:8080/api/students") .then((response) => response.json()) .then((data) => setStudents(data)) .catch((error) => console.error("Error fetching students:", error)); - }, []); + }; + + // Handle Delete + const handleDelete = (id) => { + if (window.confirm("Voulez-vous vraiment supprimer cet étudiant ?")) { + fetch(`http://localhost:8080/api/students/${id}`, { + method: "DELETE", + }) + .then(() => { + alert("Étudiant supprimé avec succès !"); + fetchStudents(); // Refresh list after delete + }) + .catch((error) => console.error("Error deleting student:", error)); + } + }; + + // Handle Update + const handleUpdate = (id) => { + navigate(`/modifier-etudiant/${id}`); + }; return ( <div className="container mt-4"> <h2 className="mb-4">Liste des Étudiants</h2> + <div> + <Link to="/ajouter-etudiant" className="btn btn-success mt-3"> + Ajouter un(e) étudiant(e) + </Link> + </div> + <br /> <table className="table table-striped table-hover"> <thead className="table-info"> <tr> <th>ID</th> <th>Prénom</th> <th>Nom</th> + <th>Actions</th> </tr> </thead> <tbody> @@ -27,6 +60,20 @@ function StudentList() { <td>{student.id}</td> <td>{student.firstname}</td> <td>{student.lastname}</td> + <td> + <button + className="btn btn-warning btn-sm me-2" + onClick={() => handleUpdate(student.id)} + > + Modifier + </button> + <button + className="btn btn-danger btn-sm" + onClick={() => handleDelete(student.id)} + > + Supprimer + </button> + </td> </tr> ))} </tbody> diff --git a/src/components/UnivSupervisorForm.jsx b/src/components/UnivSupervisorForm.jsx index 3019495f1ad62780c6fdc1a8a6f13d390a488989..03c2fab8a5b4dc1f61c692ba47fab668438994c6 100644 --- a/src/components/UnivSupervisorForm.jsx +++ b/src/components/UnivSupervisorForm.jsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { Navigate } from "react-router-dom"; function UnivSupervisorForm() { const [name, setName] = useState(""); @@ -20,6 +21,10 @@ function UnivSupervisorForm() { }) .catch((err) => console.error("Erreur lors de l'ajout du superviseur :", err)); }; + // Handle cancel button + const handleCancel = () => { + Navigate("/superviseurs"); // Redirect back to candidacy list + }; return ( <div className="container mt-4"> @@ -35,8 +40,12 @@ function UnivSupervisorForm() { required /> </div> - <button type="submit" className="btn btn-primary">Ajouter</button> - </form> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-primary"> + Ajouter + </button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> </form> </div> ); } diff --git a/src/components/UnivSupervisorList.jsx b/src/components/UnivSupervisorList.jsx index 0b271d02451ac95b1e35c1f537995d45fed547af..80ef965c59785038e5fe2ddeff8cbb0f0be78faa 100644 --- a/src/components/UnivSupervisorList.jsx +++ b/src/components/UnivSupervisorList.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; function UnivSupervisorList() { const [univSupervisors, setUnivSupervisors] = useState([]); @@ -10,15 +11,35 @@ function UnivSupervisorList() { .catch((error) => console.error("Error fetching university supervisors:", error)); }, []); + const handleDelete = (id) => { + if (window.confirm("Voulez-vous vraiment supprimer ce superviseur universitaire ?")) { + fetch(`http://localhost:8080/api/univsupervisors/${id}`, { + method: "DELETE", + }) + .then(() => { + alert("Superviseur supprimé !"); + setUnivSupervisors(univSupervisors.filter((supervisor) => supervisor.id !== id)); + }) + .catch((error) => console.error("Erreur lors de la suppression :", error)); + } + }; + return ( <div className="container mt-4"> - <h2 className="mb-4">Liste des Superviseurs Universitaires</h2> + <div className="d-flex justify-content-between align-items-center mb-3"> + <h2>Liste des Superviseurs Universitaires</h2> + <Link to="/ajouter-univsuperviseur" className="btn btn-success"> + Ajouter un Superviseur + </Link> + </div> + <table className="table table-striped table-hover"> <thead className="table-primary"> <tr> <th>ID</th> <th>Nom</th> <th>Stages Supervisés</th> + <th>Actions</th> </tr> </thead> <tbody> @@ -28,14 +49,25 @@ function UnivSupervisorList() { <td>{supervisor.name}</td> <td> {supervisor.supervisedStages && supervisor.supervisedStages.length > 0 ? ( - <ul> - {supervisor.supervisedStages.map((stage) => ( - <li key={stage.id}>{stage.stage?.name}</li> + <ul className="list-unstyled"> + {supervisor.supervisedStages.map((candidacy) => ( + <li key={candidacy.id}> + {candidacy.stage?.name || "Nom du stage indisponible"} + </li> ))} - </ul> + </ul> ) : ( - "Aucun stage" + <span className="text-muted">Aucun stage</span> )} + </td> + + <td> + <Link to={`/modifier-univsuperviseur/${supervisor.id}`} className="btn btn-warning btn-sm me-2"> + Modifier + </Link> + <button onClick={() => handleDelete(supervisor.id)} className="btn btn-danger btn-sm"> + Supprimer + </button> </td> </tr> ))} diff --git a/src/components/UpdateCandidacyForm.jsx b/src/components/UpdateCandidacyForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..480df9e4284239ef33dc1c360c6a372fae4aba07 --- /dev/null +++ b/src/components/UpdateCandidacyForm.jsx @@ -0,0 +1,178 @@ +import React, { useState, useEffect } from "react"; +import { useParams, useNavigate } from "react-router-dom"; + +function UpdateCandidacyForm() { + const { id } = useParams(); + const navigate = useNavigate(); + + // State for candidacy + const [candidacy, setCandidacy] = useState({ + student: { id: "", firstname: "", lastname: "" }, + stage: { id: "", name: "" }, + univSupervisor: { id: "", name: "" }, + requestState: "", + acceptedState: "", + }); + + // State for dropdown lists + const [students, setStudents] = useState([]); + const [stages, setStages] = useState([]); + const [univSupervisors, setUnivSupervisors] = useState([]); + + // Fetch existing candidacy details + useEffect(() => { + fetch(`http://localhost:8080/api/candidacies/${id}`) + .then((res) => res.json()) + .then((data) => setCandidacy(data)) + .catch((err) => console.error("Erreur lors de la récupération :", err)); + + // Fetch dropdown options + fetch("http://localhost:8080/api/students") + .then((res) => res.json()) + .then((data) => setStudents(data)); + + fetch("http://localhost:8080/api/stages") + .then((res) => res.json()) + .then((data) => setStages(data)); + + fetch("http://localhost:8080/api/univsupervisors") + .then((res) => res.json()) + .then((data) => setUnivSupervisors(data)); + }, [id]); + + // Handle change for dropdowns + const handleChange = (e) => { + setCandidacy({ ...candidacy, [e.target.name]: e.target.value }); + }; + + // Handle dropdown selection + const handleSelectChange = (e) => { + const { name, value } = e.target; + setCandidacy({ + ...candidacy, + [name]: { id: value }, + }); + }; + + // Submit updated candidacy + const handleSubmit = (e) => { + e.preventDefault(); + + fetch(`http://localhost:8080/api/candidacies/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(candidacy), + }) + .then(() => { + alert("Candidature mise à jour avec succès !"); + navigate("/candidatures"); + }) + .catch((err) => console.error("Erreur lors de la mise à jour :", err)); + }; + + // Handle cancel button + const handleCancel = () => { + navigate("/candidatures"); // Redirect back to candidacy list + }; + + return ( + <div className="container mt-4"> + <h2>Modifier la Candidature</h2> + <form onSubmit={handleSubmit}> + + {/* Étudiant Dropdown */} + <div className="mb-3"> + <label className="form-label">Étudiant</label> + <select + className="form-control" + name="student" + value={candidacy.student?.id || ""} + onChange={handleSelectChange} + > + <option value="">Sélectionner un étudiant</option> + {students.map((student) => ( + <option key={student.id} value={student.id}> + {student.firstname} {student.lastname} + </option> + ))} + </select> + </div> + + {/* Stage Dropdown */} + <div className="mb-3"> + <label className="form-label">Stage</label> + <select + className="form-control" + name="stage" + value={candidacy.stage?.id || ""} + onChange={handleSelectChange} + > + <option value="">Sélectionner un stage</option> + {stages.map((stage) => ( + <option key={stage.id} value={stage.id}> + {stage.name} + </option> + ))} + </select> + </div> + + {/* Superviseur Universitaire Dropdown */} + <div className="mb-3"> + <label className="form-label">Superviseur Universitaire</label> + <select + className="form-control" + name="univSupervisor" + value={candidacy.univSupervisor?.id || ""} + onChange={handleSelectChange} + > + <option value="">Sélectionner un superviseur</option> + {univSupervisors.map((supervisor) => ( + <option key={supervisor.id} value={supervisor.id}> + {supervisor.name} + </option> + ))} + </select> + </div> + + {/* État de la Demande Dropdown */} + <div className="mb-3"> + <label className="form-label">État de la Demande</label> + <select + className="form-control" + name="requestState" + value={candidacy.requestState} + onChange={handleChange} + > + <option value="FirstRequest">Première Demande</option> + <option value="Accepted">Accepté</option> + <option value="Declined">Refusé</option> + </select> + </div> + + {/* Statut Accepté Dropdown */} + <div className="mb-3"> + <label className="form-label">Statut Accepté</label> + <select + className="form-control" + name="acceptedState" + value={candidacy.acceptedState} + onChange={handleChange} + > + <option value="wait">En attente</option> + <option value="inProgress">En cours</option> + <option value="terminated">Terminé</option> + </select> + </div> + + {/* Buttons: Update & Cancel */} + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-success">Mettre à jour</button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> + + </form> + </div> + ); +} + +export default UpdateCandidacyForm; diff --git a/src/components/UpdateEnterpriseForm.jsx b/src/components/UpdateEnterpriseForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..637901c45c6f9858756655a5d134cde0ef396ff8 --- /dev/null +++ b/src/components/UpdateEnterpriseForm.jsx @@ -0,0 +1,64 @@ +import React, { useState, useEffect } from "react"; +import { useParams, useNavigate } from "react-router-dom"; + +function UpdateEnterpriseForm() { + const { id } = useParams(); + const navigate = useNavigate(); + + const [enterprise, setEnterprise] = useState({ + name: "", + address: "", + }); + + useEffect(() => { + fetch(`http://localhost:8080/api/enterprises/${id}`) + .then((res) => res.json()) + .then((data) => setEnterprise(data)) + .catch((err) => console.error("Erreur:", err)); + }, [id]); + + const handleChange = (e) => { + setEnterprise({ ...enterprise, [e.target.name]: e.target.value }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + fetch(`http://localhost:8080/api/enterprises/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(enterprise), + }) + .then(() => { + alert("Entreprise mise à jour !"); + navigate("/entreprises"); + }) + .catch((err) => console.error("Erreur:", err)); + }; + // Handle cancel button + const handleCancel = () => { + navigate("/entreprises"); // Redirect back to candidacy list + }; + + return ( + <div className="container mt-4"> + <h2>Modifier une Entreprise</h2> + <form onSubmit={handleSubmit}> + <div className="mb-3"> + <label className="form-label">Nom</label> + <input type="text" className="form-control" name="name" value={enterprise.name} onChange={handleChange} required /> + </div> + <div className="mb-3"> + <label className="form-label">Adresse</label> + <input type="text" className="form-control" name="address" value={enterprise.address} onChange={handleChange} required /> + </div> + {/* Buttons: Update & Cancel */} + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-success">Mettre à jour</button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> + </form> + </div> + ); +} + +export default UpdateEnterpriseForm; diff --git a/src/components/UpdateStageForm.jsx b/src/components/UpdateStageForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c9931f33224923999e42f57eb5f8c7cebbb86eb9 --- /dev/null +++ b/src/components/UpdateStageForm.jsx @@ -0,0 +1,83 @@ +import React, { useState, useEffect } from "react"; +import { useParams, useNavigate } from "react-router-dom"; + +function UpdateStageForm() { + const { id } = useParams(); + const navigate = useNavigate(); + + const [stage, setStage] = useState({ + name: "", + description: "", + enterprise: null, // Stores selected enterprise + }); + + const [enterprises, setEnterprises] = useState([]); // Stores list of enterprises + + // Fetch stage details + useEffect(() => { + fetch(`http://localhost:8080/api/stages/${id}`) + .then((res) => res.json()) + .then((data) => setStage(data)) + .catch((err) => console.error("Erreur:", err)); + + // Fetch enterprises for the dropdown + fetch("http://localhost:8080/api/enterprises") + .then((res) => res.json()) + .then((data) => setEnterprises(data)) + .catch((err) => console.error("Erreur fetching enterprises:", err)); + }, [id]); + + const handleChange = (e) => { + setStage({ ...stage, [e.target.name]: e.target.value }); + }; + + const handleEnterpriseChange = (e) => { + const selectedEnterprise = enterprises.find((ent) => ent.id === parseInt(e.target.value)); + setStage({ ...stage, enterprise: selectedEnterprise }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + fetch(`http://localhost:8080/api/stages/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(stage), + }) + .then(() => { + alert("Stage mis à jour !"); + navigate("/stages"); + }) + .catch((err) => console.error("Erreur:", err)); + }; + + return ( + <div className="container mt-4"> + <h2>Modifier un Stage</h2> + <form onSubmit={handleSubmit}> + <div className="mb-3"> + <label className="form-label">Nom du stage</label> + <input type="text" className="form-control" name="name" value={stage.name} onChange={handleChange} required /> + </div> + <div className="mb-3"> + <label className="form-label">Description</label> + <textarea className="form-control" name="description" value={stage.description} onChange={handleChange} required /> + </div> + <div className="mb-3"> + <label className="form-label">Entreprise</label> + <select className="form-control" value={stage.enterprise?.id || ""} onChange={handleEnterpriseChange} required> + <option value="" disabled>-- Sélectionnez une entreprise --</option> + {enterprises.map((enterprise) => ( + <option key={enterprise.id} value={enterprise.id}> + {enterprise.name} + </option> + ))} + </select> + </div> + <button type="submit" className="btn btn-success me-2">Modifier</button> + <button type="button" className="btn btn-secondary" onClick={() => navigate("/stages")}>Annuler</button> + </form> + </div> + ); +} + +export default UpdateStageForm; diff --git a/src/components/UpdateStudentForm.jsx b/src/components/UpdateStudentForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..efa5cdb8a21dffc411d85cb53ffde189f5df0743 --- /dev/null +++ b/src/components/UpdateStudentForm.jsx @@ -0,0 +1,65 @@ +import React, { useState, useEffect } from "react"; +import { useParams, useNavigate } from "react-router-dom"; + +function UpdateStudentForm() { + const { id } = useParams(); + const navigate = useNavigate(); + + const [student, setStudent] = useState({ + firstname: "", + lastname: "", + }); + + useEffect(() => { + fetch(`http://localhost:8080/api/students/${id}`) + .then((res) => res.json()) + .then((data) => setStudent(data)) + .catch((err) => console.error("Erreur de chargement:", err)); + }, [id]); + + const handleChange = (e) => { + setStudent({ ...student, [e.target.name]: e.target.value }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + fetch(`http://localhost:8080/api/students/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(student), + }) + .then(() => { + alert("Étudiant mis à jour !"); + navigate("/etudiants"); + }) + .catch((err) => console.error("Erreur:", err)); + }; + + // Handle cancel button + const handleCancel = () => { + navigate("/entreprises"); // Redirect back to candidacy list + }; + + return ( + <div className="container mt-4"> + <h2>Modifier un Étudiant</h2> + <form onSubmit={handleSubmit}> + <div className="mb-3"> + <label className="form-label">Prénom</label> + <input type="text" className="form-control" name="firstname" value={student.firstname} onChange={handleChange} required /> + </div> + <div className="mb-3"> + <label className="form-label">Nom</label> + <input type="text" className="form-control" name="lastname" value={student.lastname} onChange={handleChange} required /> + </div> + {/* Buttons: Update & Cancel */} + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-success">Mettre à jour</button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> + </form> + </div> + ); +} + +export default UpdateStudentForm; diff --git a/src/components/UpdateUnivSupervisorForm.jsx b/src/components/UpdateUnivSupervisorForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..f86fb81d0da69948aa75368f4629112ef2d42ee3 --- /dev/null +++ b/src/components/UpdateUnivSupervisorForm.jsx @@ -0,0 +1,58 @@ +import React, { useState, useEffect } from "react"; +import { useParams, useNavigate } from "react-router-dom"; + +function UpdateUnivSupervisorForm() { + const { id } = useParams(); + const navigate = useNavigate(); + + const [supervisor, setSupervisor] = useState({ + name: "", + }); + + useEffect(() => { + fetch(`http://localhost:8080/api/univsupervisors/${id}`) + .then((res) => res.json()) + .then((data) => setSupervisor(data)) + .catch((err) => console.error("Erreur de chargement:", err)); + }, [id]); + + const handleChange = (e) => { + setSupervisor({ ...supervisor, [e.target.name]: e.target.value }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + fetch(`http://localhost:8080/api/univsupervisors/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(supervisor), + }) + .then(() => { + alert("Superviseur mis à jour !"); + navigate("/superviseurs"); + }) + .catch((err) => console.error("Erreur:", err)); + }; + + // Handle cancel button + const handleCancel = () => { + navigate("/superviseurs"); // Redirect back to candidacy list + }; + return ( + <div className="container mt-4"> + <h2>Modifier un Superviseur</h2> + <form onSubmit={handleSubmit}> + <div className="mb-3"> + <label className="form-label">Nom</label> + <input type="text" className="form-control" name="name" value={supervisor.name} onChange={handleChange} required /> + </div> + <div className="d-flex gap-2"> + <button type="submit" className="btn btn-success">Mettre à jour</button> + <button type="button" className="btn btn-secondary" onClick={handleCancel}>Annuler</button> + </div> + </form> + </div> + ); +} + +export default UpdateUnivSupervisorForm;