Skip to content
Snippets Groups Projects
Commit 782ab2e7 authored by Fatima Ezzahra Majidi's avatar Fatima Ezzahra Majidi
Browse files

Merge branch 'master' into 'main'

Format de tables et de navbar

See merge request !2
parents b6c0274d e84147e9
No related branches found
No related tags found
1 merge request!2Format de tables et de navbar
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"name": "gestion-stages-front", "name": "gestion-stages-front",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0", "@testing-library/react": "^16.2.0",
...@@ -2314,6 +2315,14 @@ ...@@ -2314,6 +2315,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@fortawesome/fontawesome-free": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
"integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==",
"engines": {
"node": ">=6"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
...@@ -17775,6 +17784,11 @@ ...@@ -17775,6 +17784,11 @@
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==" "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="
}, },
"@fortawesome/fontawesome-free": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
"integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA=="
},
"@humanwhocodes/config-array": { "@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0", "@testing-library/react": "^16.2.0",
......
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
const CandidacyList = () => { function CandidacyList() {
const [candidacies, setCandidacies] = useState([]); const [candidacies, setCandidacies] = useState([]);
const [error, setError] = useState(null);
useEffect(() => { useEffect(() => {
fetch("http://localhost:8080/api/candidacies") fetch("http://localhost:8080/api/candidacies")
.then((response) => { .then((response) => response.json())
if (!response.ok) {
throw new Error("Erreur lors de la récupération des candidatures !");
}
return response.json();
})
.then((data) => setCandidacies(data)) .then((data) => setCandidacies(data))
.catch((err) => setError(err.message)); .catch((error) => console.error("Error fetching candidacies:", error));
}, []); }, []);
return ( return (
<div> <div className="container mt-4">
<h2>Liste des Candidatures</h2> <h2 className="mb-4">Liste des Candidatures</h2>
{error && <p style={{ color: "red" }}>{error}</p>} <table className="table table-striped table-hover">
<ul> <thead className="table-warning">
{candidacies.length > 0 ? ( <tr>
candidacies.map((candidacy) => ( <th>ID</th>
<li key={candidacy.id}> <th>Étudiant</th>
Étudiant: {candidacy.student.firstname} {candidacy.student.lastname} - <th>Stage</th>
Stage: {candidacy.stage.name} - <th>Superviseur Universitaire</th>
Superviseur: {candidacy.univSupervisor.name} </tr>
</li> </thead>
)) <tbody>
) : ( {candidacies.map((candidacy) => (
<p>Aucune candidature trouvée.</p> <tr key={candidacy.id}>
)} <td>{candidacy.id}</td>
</ul> <td>{candidacy.student?.firstname} {candidacy.student?.lastname}</td>
<td>{candidacy.stage?.name}</td>
<td>{candidacy.univSupervisor?.name}</td>
</tr>
))}
</tbody>
</table>
</div> </div>
); );
}; }
export default CandidacyList; export default CandidacyList;
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
const EnterpriseList = () => { function EnterpriseList() {
const [enterprises, setEnterprises] = useState([]); const [enterprises, setEnterprises] = useState([]);
const [error, setError] = useState(null);
useEffect(() => { useEffect(() => {
fetch("http://localhost:8080/api/enterprises") fetch("http://localhost:8080/api/enterprises")
.then((response) => { .then((response) => response.json())
if (!response.ok) {
throw new Error("Erreur lors de la récupération des entreprises !");
}
return response.json();
})
.then((data) => setEnterprises(data)) .then((data) => setEnterprises(data))
.catch((err) => setError(err.message)); .catch((error) => console.error("Error fetching enterprises:", error));
}, []); }, []);
return ( return (
<div> <div className="container mt-4">
<h2>Liste des Entreprises</h2> <h2 className="mb-4">Liste des Entreprises</h2>
{error && <p style={{ color: "red" }}>{error}</p>} <table className="table table-striped table-hover">
<ul> <thead className="table-primary">
{enterprises.length > 0 ? ( <tr>
enterprises.map((enterprise) => ( <th>ID</th>
<li key={enterprise.id}> <th>Nom</th>
<strong>{enterprise.name}</strong> - {enterprise.address} <th>Adresse</th>
</li> </tr>
)) </thead>
) : ( <tbody>
<p>Aucune entreprise trouvée.</p> {enterprises.map((enterprise) => (
)} <tr key={enterprise.id}>
</ul> <td>{enterprise.id}</td>
<td>{enterprise.name}</td>
<td>{enterprise.address}</td>
</tr>
))}
</tbody>
</table>
</div> </div>
); );
}; }
export default EnterpriseList; export default EnterpriseList;
/* Navbar styling */
.navbar {
padding: 12px 20px;
font-size: 16px;
background: #ffffff;
border-bottom: 2px solid #007bff;
}
/* Brand */
.navbar-brand {
font-size: 20px;
font-weight: bold;
color: #007bff !important;
}
/* Navbar Links */
.navbar-nav .nav-link {
color: #333 !important;
font-weight: 500;
padding: 10px 15px;
transition: all 0.3s ease-in-out;
}
/* Highlight the active link */
.navbar-nav .nav-link:hover,
.navbar-nav .nav-link.active {
color: #007bff !important;
border-bottom: 2px solid #007bff;
}
/* Responsive styles */
@media (max-width: 992px) {
.navbar-nav {
text-align: center;
}
.navbar-nav .nav-item {
margin-bottom: 5px;
}
}
import React from "react"; import React from "react";
import { Link } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import "./Navbar.css"; // Optional: Add this for extra styling
function Navbar() { function Navbar() {
const location = useLocation();
return ( return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark"> <nav className="navbar navbar-expand-lg navbar-dark bg-primary shadow-sm">
<div className="container"> <div className="container">
<Link className="navbar-brand" to="/">Gestion Stages</Link> <Link className="navbar-brand fw-bold" to="/">
<i className="fas fa-graduation-cap"></i> Gestion Stages
</Link>
<button <button
className="navbar-toggler" className="navbar-toggler"
type="button" type="button"
...@@ -17,25 +22,56 @@ function Navbar() { ...@@ -17,25 +22,56 @@ function Navbar() {
> >
<span className="navbar-toggler-icon"></span> <span className="navbar-toggler-icon"></span>
</button> </button>
<div className="collapse navbar-collapse" id="navbarNav"> <div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav"> <ul className="navbar-nav ms-auto">
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/login">Login</Link> <Link
className={`nav-link ${location.pathname === "/login" ? "active" : ""}`}
to="/login"
>
<i className="fas fa-sign-in-alt"></i> Login
</Link>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/stages">Stages</Link> <Link
className={`nav-link ${location.pathname === "/stages" ? "active" : ""}`}
to="/stages"
>
<i className="fas fa-book"></i> Stages
</Link>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/etudiants">Étudiants</Link> <Link
className={`nav-link ${location.pathname === "/etudiants" ? "active" : ""}`}
to="/etudiants"
>
<i className="fas fa-user-graduate"></i> Étudiants
</Link>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/entreprises">Entreprises</Link> <Link
className={`nav-link ${location.pathname === "/entreprises" ? "active" : ""}`}
to="/entreprises"
>
<i className="fas fa-building"></i> Entreprises
</Link>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/candidatures">Candidatures</Link> <Link
className={`nav-link ${location.pathname === "/candidatures" ? "active" : ""}`}
to="/candidatures"
>
<i className="fas fa-file-alt"></i> Candidatures
</Link>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<Link className="nav-link" to="/superviseurs">Superviseurs</Link> <Link
className={`nav-link ${location.pathname === "/superviseurs" ? "active" : ""}`}
to="/superviseurs"
>
<i className="fas fa-chalkboard-teacher"></i> Superviseurs
</Link>
</li> </li>
</ul> </ul>
</div> </div>
......
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
const StageList = () => { function StageList() {
const [stages, setStages] = useState([]); // État pour stocker les stages const [stages, setStages] = useState([]);
const [error, setError] = useState(null); // État pour gérer les erreurs
useEffect(() => { useEffect(() => {
fetch("http://localhost:8080/api/stages") // Appel API fetch("http://localhost:8080/api/stages")
.then((response) => { .then((response) => response.json())
if (!response.ok) { .then((data) => setStages(data))
throw new Error("Erreur lors de la récupération des stages !"); .catch((error) => console.error("Error fetching stages:", error));
} }, []);
return response.json();
})
.then((data) => setStages(data)) // Mettre à jour l'état avec les données reçues
.catch((err) => setError(err.message)); // Gestion des erreurs
}, []); // Le tableau vide signifie que ça s'exécute une seule fois au chargement
return ( return (
<div> <div className="container mt-4">
<h2>Liste des Stages</h2> <h2 className="mb-4">Liste des Stages</h2>
{error && <p style={{ color: "red" }}>{error}</p>} {/* Affichage des erreurs */} <table className="table table-striped table-hover">
<thead className="table-success">
<ul> <tr>
{stages.length > 0 ? ( <th>ID</th>
stages.map((stage) => ( <th>Nom</th>
<li key={stage.id}> <th>Description</th>
<strong>{stage.name}</strong> - {stage.description} <th>Entreprise</th>
</li> </tr>
)) </thead>
) : ( <tbody>
<p>Aucun stage trouvé.</p> {stages.map((stage) => (
)} <tr key={stage.id}>
</ul> <td>{stage.id}</td>
<td>{stage.name}</td>
<td>{stage.description}</td>
<td>{stage.enterprise?.name}</td>
</tr>
))}
</tbody>
</table>
</div> </div>
); );
}; }
export default StageList; export default StageList;
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
const StudentList = () => { function StudentList() {
const [students, setStudents] = useState([]); const [students, setStudents] = useState([]);
const [error, setError] = useState(null);
useEffect(() => { useEffect(() => {
fetch("http://localhost:8080/api/students") fetch("http://localhost:8080/api/students")
.then((response) => { .then((response) => response.json())
if (!response.ok) {
throw new Error("Erreur lors de la récupération des étudiants !");
}
return response.json();
})
.then((data) => setStudents(data)) .then((data) => setStudents(data))
.catch((err) => setError(err.message)); .catch((error) => console.error("Error fetching students:", error));
}, []); }, []);
return ( return (
<div> <div className="container mt-4">
<h2>Liste des Étudiants</h2> <h2 className="mb-4">Liste des Étudiants</h2>
{error && <p style={{ color: "red" }}>{error}</p>} <table className="table table-striped table-hover">
<ul> <thead className="table-info">
{students.length > 0 ? ( <tr>
students.map((student) => ( <th>ID</th>
<li key={student.id}> <th>Prénom</th>
<strong>{student.firstname} {student.lastname}</strong> <th>Nom</th>
</li> </tr>
)) </thead>
) : ( <tbody>
<p>Aucun étudiant trouvé.</p> {students.map((student) => (
)} <tr key={student.id}>
</ul> <td>{student.id}</td>
<td>{student.firstname}</td>
<td>{student.lastname}</td>
</tr>
))}
</tbody>
</table>
</div> </div>
); );
}; }
export default StudentList; export default StudentList;
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
const UnivSupervisorList = () => { function UnivSupervisorList() {
const [supervisors, setSupervisors] = useState([]); const [univSupervisors, setUnivSupervisors] = useState([]);
const [error, setError] = useState(null);
useEffect(() => { useEffect(() => {
fetch("http://localhost:8080/api/univsupervisors") fetch("http://localhost:8080/api/univSupervisors")
.then((response) => { .then((response) => response.json())
if (!response.ok) { .then((data) => setUnivSupervisors(data))
throw new Error("Erreur lors de la récupération des superviseurs !"); .catch((error) => console.error("Error fetching university supervisors:", error));
}
return response.json();
})
.then((data) => setSupervisors(data))
.catch((err) => setError(err.message));
}, []); }, []);
return ( return (
<div> <div className="container mt-4">
<h2>Liste des Superviseurs</h2> <h2 className="mb-4">Liste des Superviseurs Universitaires</h2>
{error && <p style={{ color: "red" }}>{error}</p>} <table className="table table-striped table-hover">
<ul> <thead className="table-danger">
{supervisors.length > 0 ? ( <tr>
supervisors.map((supervisor) => ( <th>ID</th>
<li key={supervisor.id}> <th>Nom du Superviseur Universitaire</th>
<strong>{supervisor.name}</strong> </tr>
</li> </thead>
)) <tbody>
) : ( {univSupervisors.map((supervisor) => (
<p>Aucun superviseur trouvé.</p> <tr key={supervisor.id}>
)} <td>{supervisor.id}</td>
</ul> <td>{supervisor.name}</td>
</tr>
))}
</tbody>
</table>
</div> </div>
); );
}; }
export default UnivSupervisorList; export default UnivSupervisorList;
...@@ -3,6 +3,10 @@ import ReactDOM from 'react-dom/client'; ...@@ -3,6 +3,10 @@ import ReactDOM from 'react-dom/client';
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import "@fortawesome/fontawesome-free/css/all.min.css";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment