mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
feat: Ajout de la gestion des fichier d'inscription [#1]
This commit is contained in:
@ -28,5 +28,6 @@
|
||||
"lastUpdateDate":"Last update",
|
||||
"classe":"Class",
|
||||
"registrationFileStatus":"Registration file status",
|
||||
"files":"Files"
|
||||
"files":"Files",
|
||||
"subscribeFiles":"Subscribe files"
|
||||
}
|
||||
@ -28,5 +28,6 @@
|
||||
"lastUpdateDate":"Dernière mise à jour",
|
||||
"classe":"Classe",
|
||||
"registrationFileStatus":"État du dossier d'inscription",
|
||||
"files":"Fichiers"
|
||||
"files":"Fichiers",
|
||||
"subscribeFiles":"Fichiers d'inscription"
|
||||
}
|
||||
@ -63,7 +63,7 @@ export default function Layout({
|
||||
<Sidebar currentPage={currentPage} items={Object.values(sidebarItems)} className="h-full" />
|
||||
<div className="flex flex-col flex-1">
|
||||
{/* Header - h-16 = 64px */}
|
||||
<header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-10">
|
||||
<header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-9">
|
||||
<div className="text-xl font-semibold">{headerTitle}</div>
|
||||
<DropdownMenu
|
||||
buttonContent={<img src="https://i.pravatar.cc/32" alt="Profile" className="w-8 h-8 rounded-full cursor-pointer" />}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Upload } from 'lucide-react';
|
||||
|
||||
export default function FileUpload({ onFileUpload }) {
|
||||
const [dragActive, setDragActive] = useState(false);
|
||||
const [fileName, setFileName] = useState('');
|
||||
const [file, setFile] = useState(null);
|
||||
|
||||
const handleDragOver = (event) => {
|
||||
event.preventDefault();
|
||||
setDragActive(true);
|
||||
};
|
||||
|
||||
const handleDragLeave = () => {
|
||||
setDragActive(false);
|
||||
};
|
||||
|
||||
const handleDrop = (event) => {
|
||||
event.preventDefault();
|
||||
setDragActive(false);
|
||||
const droppedFile = event.dataTransfer.files[0];
|
||||
setFile(droppedFile);
|
||||
setFileName(droppedFile.name.replace(/\.[^/.]+$/, ""));
|
||||
};
|
||||
|
||||
const handleFileChange = (event) => {
|
||||
const selectedFile = event.target.files[0];
|
||||
setFile(selectedFile);
|
||||
setFileName(selectedFile.name.replace(/\.[^/.]+$/, ""));
|
||||
};
|
||||
|
||||
const handleFileNameChange = (event) => {
|
||||
setFileName(event.target.value);
|
||||
};
|
||||
|
||||
const handleUpload = () => {
|
||||
if (file) {
|
||||
onFileUpload(file, fileName);
|
||||
setFile(null);
|
||||
setFileName('');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
className={`border-2 border-dashed p-8 rounded-md ${dragActive ? 'border-blue-500' : 'border-gray-300'} flex flex-col items-center justify-center`}
|
||||
style={{ height: '200px' }}
|
||||
>
|
||||
<input type="file" onChange={handleFileChange} className="hidden" id="fileInput" />
|
||||
<label htmlFor="fileInput" className="cursor-pointer flex flex-col items-center">
|
||||
<Upload size={48} className="text-gray-400 mb-2" />
|
||||
<p className="text-center">{fileName || 'Glissez et déposez un fichier ici ou cliquez ici pour sélectionner un fichier'}</p>
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex mt-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Nom du fichier"
|
||||
value={fileName}
|
||||
onChange={handleFileNameChange}
|
||||
className="flex-grow p-2 border border-gray-200 rounded-md"
|
||||
/>
|
||||
<button
|
||||
onClick={handleUpload}
|
||||
className={`p-2 rounded-md shadow transition duration-200 ml-2 ${file ? 'bg-emerald-600 text-white hover:bg-emerald-900' : 'bg-gray-300 text-gray-500 cursor-not-allowed'}`}
|
||||
disabled={!file}
|
||||
>
|
||||
Ajouter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -13,17 +13,19 @@ import Button from '@/components/Button';
|
||||
import DropdownMenu from "@/components/DropdownMenu";
|
||||
import { swapFormatDate } from '@/utils/Date';
|
||||
import { formatPhoneNumber } from '@/utils/Telephone';
|
||||
import { MoreVertical, Send, Edit, Trash2, FileText, ChevronUp, UserPlus, CheckCircle, Plus} from 'lucide-react';
|
||||
import { MoreVertical, Send, Edit, Trash2, FileText, ChevronUp, UserPlus, CheckCircle, Plus, Download } from 'lucide-react';
|
||||
import Modal from '@/components/Modal';
|
||||
import InscriptionForm from '@/components/Inscription/InscriptionForm'
|
||||
import AffectationClasseForm from '@/components/AffectationClasseForm'
|
||||
import FileUpload from './components/FileUpload';
|
||||
|
||||
import { BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL,
|
||||
BK_GESTIONINSCRIPTION_SEND_URL,
|
||||
FR_ADMIN_SUBSCRIPTIONS_EDIT_URL,
|
||||
BK_GESTIONINSCRIPTION_ARCHIVE_URL,
|
||||
BK_GESTIONENSEIGNANTS_CLASSES_URL,
|
||||
import { BASE_URL, BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL,
|
||||
BK_GESTIONINSCRIPTION_SEND_URL,
|
||||
FR_ADMIN_SUBSCRIPTIONS_EDIT_URL,
|
||||
BK_GESTIONINSCRIPTION_ARCHIVE_URL,
|
||||
BK_GESTIONENSEIGNANTS_CLASSES_URL,
|
||||
BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL,
|
||||
BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL ,
|
||||
BK_GESTIONINSCRIPTION_ELEVES_URL,
|
||||
BK_PROFILE_URL } from '@/utils/Url';
|
||||
|
||||
@ -53,6 +55,10 @@ export default function Page({ params: { locale } }) {
|
||||
const [totalArchives, setTotalArchives] = useState(0);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(5); // Définir le nombre d'éléments par page
|
||||
|
||||
const [fichiers, setFichiers] = useState([]);
|
||||
const [nomFichier, setNomFichier] = useState('');
|
||||
const [fichier, setFichier] = useState(null);
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isOpenAffectationClasse, setIsOpenAffectationClasse] = useState(false);
|
||||
const [eleve, setEleve] = useState('');
|
||||
@ -180,6 +186,32 @@ export default function Page({ params: { locale } }) {
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchFichiers = () => {
|
||||
const request = new Request(
|
||||
`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}`,
|
||||
{
|
||||
method:'GET',
|
||||
headers: {
|
||||
'Content-Type':'application/json'
|
||||
},
|
||||
}
|
||||
);
|
||||
fetch(request).then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success FILES:', data);
|
||||
setFichiers(data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
error = error.message;
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
fetchFichiers();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
fetchClasses();
|
||||
fetchStudents();
|
||||
@ -326,7 +358,7 @@ export default function Page({ params: { locale } }) {
|
||||
{
|
||||
method:'POST',
|
||||
headers: {
|
||||
'Content-Type':'application/json',
|
||||
'Content-Type':'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
credentials: 'include',
|
||||
@ -371,7 +403,7 @@ export default function Page({ params: { locale } }) {
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
console.log('Success:', data);
|
||||
setFichesInscriptionsDataEnCours(prevState => {
|
||||
if (prevState && prevState.length > 0) {
|
||||
return [...prevState, data];
|
||||
@ -429,13 +461,11 @@ const columns = [
|
||||
)
|
||||
},
|
||||
{ name: t('files'), transform: (row) => (
|
||||
<ul>
|
||||
{row.fichiers?.map((fichier, fileIndex) => (
|
||||
<li key={fileIndex} className="flex items-center gap-2">
|
||||
<ul>
|
||||
<li className="flex items-center gap-2">
|
||||
<FileText size={16} />
|
||||
<a href={fichier.url}>{fichier.nom}</a>
|
||||
<a href={ `${BASE_URL}${row.fichierInscription}`} target='_blank'>{row.fichierInscription.split('/').pop()}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) },
|
||||
{ name: 'Actions', transform: (row) => (
|
||||
@ -509,14 +539,13 @@ const columnsSubscribed = [
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{ name: t('files'), transform: (row) => (
|
||||
{ name: t('files'), transform: (row) =>
|
||||
(
|
||||
<ul>
|
||||
{row.fichiers?.map((fichier, fileIndex) => (
|
||||
<li key={fileIndex} className="flex items-center gap-2">
|
||||
<li className="flex items-center gap-2">
|
||||
<FileText size={16} />
|
||||
<a href={fichier.url}>{fichier.nom}</a>
|
||||
<a href={ `${BASE_URL}${row.fichierInscription}`} target='_blank'>{row.fichierInscription.split('/').pop()}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) },
|
||||
{ name: 'Actions', transform: (row) => (
|
||||
@ -545,6 +574,98 @@ const columnsSubscribed = [
|
||||
|
||||
];
|
||||
|
||||
const handleFileDelete = (fileId) => {
|
||||
fetch(`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}/${fileId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'X-CSRFToken': csrfToken,
|
||||
},
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
setFichiers(fichiers.filter(fichier => fichier.id !== fileId));
|
||||
alert('Fichier supprimé avec succès.');
|
||||
} else {
|
||||
alert('Erreur lors de la suppression du fichier.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error deleting file:', error);
|
||||
alert('Erreur lors de la suppression du fichier.');
|
||||
});
|
||||
};
|
||||
|
||||
const columnsFiles = [
|
||||
{ name: 'Nom du fichier', transform: (row) => row.name },
|
||||
{ name: 'Date de création', transform: (row) => row.date_ajout },
|
||||
{ name: 'Actions', transform: (row) => (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<a href={`${BASE_URL}${row.file}`} target='_blank' className="text-blue-500 hover:text-blue-700">
|
||||
<Download size={16} />
|
||||
</a>
|
||||
<button onClick={() => handleFileDelete(row.id)} className="text-red-500 hover:text-red-700">
|
||||
<Trash2 size={16} />
|
||||
</button>
|
||||
</div>
|
||||
) },
|
||||
];
|
||||
|
||||
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
|
||||
const [uploadFile, setUploadFile] = useState(null);
|
||||
const [uploadFileName, setUploadFileName] = useState('');
|
||||
const [fileName, setFileName] = useState('');
|
||||
|
||||
const openUploadModal = () => {
|
||||
setIsUploadModalOpen(true);
|
||||
};
|
||||
|
||||
const closeUploadModal = () => {
|
||||
setIsUploadModalOpen(false);
|
||||
setUploadFile(null);
|
||||
setUploadFileName('');
|
||||
setFileName('');
|
||||
};
|
||||
|
||||
const handleFileChange = (event) => {
|
||||
const file = event.target.files[0];
|
||||
setUploadFile(file);
|
||||
setUploadFileName(file ? file.name : '');
|
||||
};
|
||||
|
||||
const handleFileNameChange = (event) => {
|
||||
setFileName(event.target.value);
|
||||
};
|
||||
|
||||
const handleFileUpload = (file, fileName) => {
|
||||
if (!file || !fileName) {
|
||||
alert('Veuillez sélectionner un fichier et entrer un nom de fichier.');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('name', fileName);
|
||||
|
||||
fetch(`${BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRFToken': csrfToken,
|
||||
},
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
setFichiers([...fichiers, data]);
|
||||
closeUploadModal();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error uploading file:', error);
|
||||
});
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />;
|
||||
} else {
|
||||
@ -593,16 +714,23 @@ const columnsSubscribed = [
|
||||
active={activeTab === 'archived'}
|
||||
onClick={() => setActiveTab('archived')}
|
||||
/>
|
||||
<Tab
|
||||
text={(
|
||||
<>
|
||||
{t('subscribeFiles')}
|
||||
<span className="ml-2 text-sm text-gray-400">({totalSubscribed})</span>
|
||||
</>
|
||||
)}
|
||||
active={activeTab === 'subscribeFiles'}
|
||||
onClick={() => setActiveTab('subscribeFiles')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-b border-gray-200 mb-6 w-full">
|
||||
{/*SI STATE == pending || subscribe || archived */}
|
||||
{activeTab === 'pending' || activeTab === 'subscribed' || activeTab === 'archived' ? (
|
||||
<React.Fragment>
|
||||
<div className="flex justify-between items-center mb-4 w-full">
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200 mr-4"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
<div className="relative flex-grow">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
||||
<input
|
||||
@ -613,7 +741,14 @@ const columnsSubscribed = [
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200 ml-4"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<DjangoCSRFToken csrfToken={csrfToken} />
|
||||
<Table
|
||||
@ -636,6 +771,25 @@ const columnsSubscribed = [
|
||||
onPageChange={handlePageChange}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
{/*SI STATE == subscribeFiles */}
|
||||
{activeTab === 'subscribeFiles' && (
|
||||
<div>
|
||||
<FileUpload onFileUpload={handleFileUpload} className="mb-4" />
|
||||
<div className="mt-8">
|
||||
<Table
|
||||
data={fichiers}
|
||||
columns={columnsFiles}
|
||||
itemsPerPage={itemsPerPage}
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
className="mt-8"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Popup
|
||||
visible={popup.visible}
|
||||
@ -654,10 +808,10 @@ const columnsSubscribed = [
|
||||
title={"Création d'un nouveau dossier d'inscription"}
|
||||
size='sm:w-1/4'
|
||||
ContentComponent={() => (
|
||||
<InscriptionForm eleves={eleves}
|
||||
onSubmit={createDI}
|
||||
/>
|
||||
)}
|
||||
<InscriptionForm eleves={eleves}
|
||||
onSubmit={createDI}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{isOpenAffectationClasse && (
|
||||
@ -674,6 +828,17 @@ const columnsSubscribed = [
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{isUploadModalOpen && (
|
||||
<Modal
|
||||
isOpen={isUploadModalOpen}
|
||||
setIsOpen={setIsUploadModalOpen}
|
||||
title="Uploader un nouveau fichier"
|
||||
size='sm:w-1/4'
|
||||
ContentComponent={() => (
|
||||
<FileUpload onFileUpload={handleFileUpload} />
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -70,21 +70,21 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
<div className="space-y-4 mt-8">
|
||||
{step === 1 && (
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-4">Nouvel élève</h2>
|
||||
<InputTextIcon
|
||||
name="eleveNom"
|
||||
type="text"
|
||||
<h2 className="text-l font-bold mb-4">Nouvel élève</h2>
|
||||
<InputTextIcon
|
||||
name="eleveNom"
|
||||
type="text"
|
||||
IconItem={User}
|
||||
placeholder="Nom de l'élève"
|
||||
placeholder="Nom de l'élève"
|
||||
value={formData.eleveNom}
|
||||
onChange={handleChange}
|
||||
className="w-full"
|
||||
/>
|
||||
<InputTextIcon
|
||||
name="elevePrenom"
|
||||
type="text"
|
||||
<InputTextIcon
|
||||
name="elevePrenom"
|
||||
type="text"
|
||||
IconItem={User}
|
||||
placeholder="Prénom de l'élève"
|
||||
placeholder="Prénom de l'élève"
|
||||
value={formData.elevePrenom}
|
||||
onChange={handleChange}
|
||||
className="w-full"
|
||||
@ -94,7 +94,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
|
||||
{step === 2 && (
|
||||
<div className="mt-6">
|
||||
<h2 className="text-2xl font-bold mb-4">Responsable(s)</h2>
|
||||
<h2 className="text-l font-bold mb-4">Responsable(s)</h2>
|
||||
<div className="flex flex-col space-y-4">
|
||||
<label className="flex items-center space-x-3">
|
||||
<input
|
||||
@ -120,17 +120,17 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
</label>
|
||||
</div>
|
||||
{formData.responsableType === 'new' && (
|
||||
<InputTextIcon
|
||||
name="responsableEmail"
|
||||
type="email"
|
||||
<InputTextIcon
|
||||
name="responsableEmail"
|
||||
type="email"
|
||||
IconItem={Mail}
|
||||
placeholder="Email du responsable"
|
||||
placeholder="Email du responsable"
|
||||
value={formData.responsableEmail}
|
||||
onChange={handleChange}
|
||||
className="w-full mt-4"
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
{formData.responsableType === 'existing' && (
|
||||
<div className="mt-4">
|
||||
<div className="mt-4" style={{ maxHeight: '300px', overflowY: 'auto' }}>
|
||||
@ -161,10 +161,10 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
{existingResponsables.map((responsable) => (
|
||||
<div key={responsable.id}>
|
||||
<label className="flex items-center space-x-3 mt-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={formData.selectedResponsables.includes(responsable.id)}
|
||||
className="form-checkbox h-5 w-5 text-emerald-600"
|
||||
className="form-checkbox h-5 w-5 text-emerald-600"
|
||||
onChange={() => handleResponsableSelection(responsable.id)}
|
||||
/>
|
||||
<span className="text-gray-900">
|
||||
@ -182,12 +182,12 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
|
||||
{step === 3 && (
|
||||
<div className="mt-6">
|
||||
<h2 className="text-2xl font-bold mb-4">Téléphone (optionnel)</h2>
|
||||
<InputTextIcon
|
||||
name="responsableTel"
|
||||
type="tel"
|
||||
<h2 className="text-l font-bold mb-4">Téléphone (optionnel)</h2>
|
||||
<InputTextIcon
|
||||
name="responsableTel"
|
||||
type="tel"
|
||||
IconItem={Phone}
|
||||
placeholder="Numéro de téléphone"
|
||||
placeholder="Numéro de téléphone"
|
||||
value={formData.responsableTel}
|
||||
onChange={handleChange}
|
||||
className="w-full mt-4"
|
||||
@ -197,45 +197,71 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
|
||||
{step === maxStep && (
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-4">Récapitulatif</h2>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="bg-gray-100 p-3 rounded-lg shadow-md flex items-center w-1/2 mb-4">
|
||||
<User className="w-10 h-10 text-gray-300 mr-4" />
|
||||
<div>
|
||||
<p className="italic text-gray-600">Élève</p>
|
||||
<p>Nom : {formData.eleveNom}</p>
|
||||
<p>Prénom : {formData.elevePrenom}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="bg-gray-100 p-3 rounded-lg shadow-md flex items-center w-1/2">
|
||||
<UserCheck className="w-10 h-10 text-gray-300 mr-4" />
|
||||
<h2 className="text-l font-bold mb-4">Récapitulatif</h2>
|
||||
<div className="space-y-4">
|
||||
<section>
|
||||
<h3 className="font-bold">Élève</h3>
|
||||
<table className="min-w-full bg-white border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border">Nom</th>
|
||||
<th className="px-4 py-2 border">Prénom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="px-4 py-2 border">{formData.eleveNom}</td>
|
||||
<td className="px-4 py-2 border">{formData.elevePrenom}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<h3 className="font-bold">Responsable(s)</h3>
|
||||
{formData.responsableType === 'new' && (
|
||||
<div>
|
||||
<p className="italic text-gray-600">Responsable</p>
|
||||
<p>Email : {formData.responsableEmail}</p>
|
||||
<p>Téléphone : {formData.responsableTel}</p>
|
||||
</div>
|
||||
<table className="min-w-full bg-white border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border">Email</th>
|
||||
<th className="px-4 py-2 border">Téléphone</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="px-4 py-2 border">{formData.responsableEmail}</td>
|
||||
<td className="px-4 py-2 border">{formData.responsableTel}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
{formData.responsableType === 'existing' && selectedEleve && (
|
||||
<div>
|
||||
<p className="italic text-gray-600">Responsable(s)</p>
|
||||
<p>Associé(s) à : {selectedEleve.nom} {selectedEleve.prenom}</p>
|
||||
<ul className="list-disc ml-6">
|
||||
{existingResponsables.filter(responsable => formData.selectedResponsables.includes(responsable.id)).map((responsable) => (
|
||||
<li key={responsable.id}>
|
||||
{responsable.nom && responsable.prenom ? `${responsable.nom} ${responsable.prenom}` : responsable.mail}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<table className="min-w-full bg-white border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border">Nom</th>
|
||||
<th className="px-4 py-2 border">Prénom</th>
|
||||
<th className="px-4 py-2 border">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{existingResponsables.filter(responsable => formData.selectedResponsables.includes(responsable.id)).map((responsable) => (
|
||||
<tr key={responsable.id}>
|
||||
<td className="px-4 py-2 border">{responsable.nom}</td>
|
||||
<td className="px-4 py-2 border">{responsable.prenom}</td>
|
||||
<td className="px-4 py-2 border">{responsable.mail}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div className='mt-4'>
|
||||
<ToggleSwitch
|
||||
label="Envoi automatique"
|
||||
<ToggleSwitch
|
||||
label="Envoi automatique"
|
||||
checked={formData.autoMail}
|
||||
onChange={handleToggleChange}
|
||||
/>
|
||||
@ -271,7 +297,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||
<Button text="Créer"
|
||||
onClick={submit}
|
||||
className="px-4 py-2 bg-emerald-500 text-white rounded-md shadow-sm hover:bg-emerald-600 focus:outline-none"
|
||||
primary
|
||||
primary
|
||||
name="Create" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -7,23 +7,26 @@ const Modal = ({ isOpen, setIsOpen, title, ContentComponent, size }) => {
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
||||
<Dialog.Content className="fixed inset-0 flex items-center justify-center">
|
||||
<div className={`inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:p-6 ${size ? size : 'sm:w-full' }`}>
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
<div className={`inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:p-6 ${size ? size : 'sm:w-full' }`} style={{ minWidth: '300px', width: 'auto' }}>
|
||||
<div className="flex justify-between items-start">
|
||||
<Dialog.Title className="text-xl font-medium text-gray-900">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
<Dialog.Close asChild>
|
||||
<button
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="text-gray-400 hover:text-gray-500 ml-4 focus:outline-none"
|
||||
>
|
||||
<span className="sr-only">Fermer</span>
|
||||
<svg className="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<ContentComponent />
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end space-x-4">
|
||||
<Dialog.Close asChild>
|
||||
<Button text="Fermer"
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="px-4 py-2 rounded-md shadow-sm focus:outline-none bg-gray-300 text-gray-700 hover:bg-gray-400"
|
||||
secondary
|
||||
type="submit"
|
||||
name="Create" />
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
|
||||
@ -4,12 +4,17 @@ export const BASE_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
|
||||
//URL-Back-End
|
||||
|
||||
|
||||
// GESTION LOGIN
|
||||
export const BK_NEW_PASSWORD_URL = `${BASE_URL}/GestionLogin/newPassword`
|
||||
export const BK_REGISTER_URL = `${BASE_URL}/GestionLogin/subscribe`
|
||||
export const BK_RESET_PASSWORD_URL = `${BASE_URL}/GestionLogin/resetPassword`
|
||||
export const BK_LOGIN_URL = `${BASE_URL}/GestionLogin/login`
|
||||
export const BK_LOGOUT_URL = `${BASE_URL}/GestionLogin/logout`
|
||||
export const BK_PROFILE_URL = `${BASE_URL}/GestionLogin/profil`
|
||||
export const BK_GET_CSRF = `${BASE_URL}/GestionLogin/csrf`
|
||||
|
||||
// GESTION INSCRIPTION
|
||||
export const BK_GESTIONINSCRIPTION_ELEVE_URL = `${BASE_URL}/GestionInscriptions/eleve`
|
||||
export const BK_GESTIONINSCRIPTION_ENFANTS_URL = `${BASE_URL}/GestionInscriptions/enfants` // Récupère la liste des élèves d'un profil
|
||||
export const BK_GESTIONINSCRIPTION_ELEVES_URL = `${BASE_URL}/GestionInscriptions/eleves` // Récupère la liste des élèves inscrits ou en cours d'inscriptions
|
||||
@ -17,8 +22,11 @@ export const BK_GESTIONINSCRIPTION_SEND_URL = `${BASE_URL}/GestionInscriptions/s
|
||||
export const BK_GESTIONINSCRIPTION_ARCHIVE_URL = `${BASE_URL}/GestionInscriptions/archive`
|
||||
export const BK_GESTIONINSCRIPTION_FICHESINSCRIPTION_URL = `${BASE_URL}/GestionInscriptions/fichesInscription`
|
||||
export const BK_GESTIONINSCRIPTION_FICHEINSCRIPTION_URL = `${BASE_URL}/GestionInscriptions/ficheInscription`
|
||||
export const BK_GESTIONINSCRIPTION_FICHERSINSCRIPTION_URL = `${BASE_URL}/GestionInscriptions/fichiersInscription`
|
||||
export const BK_GESTIONINSCRIPTION_RECUPEREDERNIER_RESPONSABLE_URL = `${BASE_URL}/GestionInscriptions/recupereDernierResponsable`
|
||||
export const BK_GESTIONINSCRIPTION_MESSAGES_URL = `${BASE_URL}/GestionMessagerie/messagerie`
|
||||
|
||||
//GESTION ENSEIGNANT
|
||||
export const BK_GESTIONENSEIGNANTS_SPECIALITES_URL = `${BASE_URL}/GestionEnseignants/specialites`
|
||||
export const BK_GESTIONENSEIGNANTS_SPECIALITE_URL = `${BASE_URL}//GestionEnseignants/specialite`
|
||||
export const BK_GESTIONENSEIGNANTS_CLASSES_URL = `${BASE_URL}/GestionEnseignants/classes`
|
||||
@ -28,7 +36,6 @@ export const BK_GESTIONENSEIGNANTS_TEACHER_URL = `${BASE_URL}/GestionEnseignants
|
||||
export const BK_GESTIONENSEIGNANTS_PLANNINGS_URL = `${BASE_URL}/GestionEnseignants/plannings`
|
||||
export const BK_GESTIONENSEIGNANTS_PLANNING_URL = `${BASE_URL}/GestionEnseignants/planning`
|
||||
|
||||
export const BK_GET_CSRF = `${BASE_URL}/GestionLogin/csrf`
|
||||
|
||||
|
||||
// URL FRONT-END
|
||||
|
||||
Reference in New Issue
Block a user