refactor: refactoring du FRONT page subscribe

This commit is contained in:
Luc SORIGNET
2025-01-12 14:37:49 +01:00
parent 58fe509734
commit 427b6c7588
25 changed files with 671 additions and 652 deletions

View File

@ -4,20 +4,20 @@ import InputTextIcon from '@/components/InputTextIcon';
import ToggleSwitch from '@/components/ToggleSwitch';
import Button from '@/components/Button';
const InscriptionForm = ( { eleves, onSubmit }) => {
const InscriptionForm = ( { students, onSubmit }) => {
const [formData, setFormData] = useState({
eleveNom: '',
elevePrenom: '',
responsableEmail: '',
responsableTel: '',
selectedResponsables: [],
studentLastName: '',
studentFirstName: '',
guardianEmail: '',
guardianPhone: '',
selectedGuardians: [],
responsableType: 'new',
autoMail: false
});
const [step, setStep] = useState(1);
const [selectedEleve, setSelectedEleve] = useState('');
const [existingResponsables, setExistingResponsables] = useState([]);
const [selectedStudent, setSelectedEleve] = useState('');
const [existingGuardians, setExistingGuardians] = useState([]);
const maxStep = 4
const handleToggleChange = () => {
@ -44,21 +44,21 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
}
};
const handleEleveSelection = (eleve) => {
setSelectedEleve(eleve);
const handleEleveSelection = (student) => {
setSelectedEleve(student);
setFormData((prevData) => ({
...prevData,
selectedResponsables: []
selectedGuardians: []
}));
setExistingResponsables(eleve.responsables);
setExistingGuardians(student.guardians);
};
const handleResponsableSelection = (responsableId) => {
const handleResponsableSelection = (guardianId) => {
setFormData((prevData) => {
const selectedResponsables = prevData.selectedResponsables.includes(responsableId)
? prevData.selectedResponsables.filter(id => id !== responsableId)
: [...prevData.selectedResponsables, responsableId];
return { ...prevData, selectedResponsables };
const selectedGuardians = prevData.selectedGuardians.includes(guardianId)
? prevData.selectedGuardians.filter(id => id !== guardianId)
: [...prevData.selectedGuardians, guardianId];
return { ...prevData, selectedGuardians };
});
};
@ -72,20 +72,20 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
<div>
<h2 className="text-l font-bold mb-4">Nouvel élève</h2>
<InputTextIcon
name="eleveNom"
name="studentLastName"
type="text"
IconItem={User}
placeholder="Nom de l'élève"
value={formData.eleveNom}
value={formData.studentLastName}
onChange={handleChange}
className="w-full"
/>
<InputTextIcon
name="elevePrenom"
name="studentFirstName"
type="text"
IconItem={User}
placeholder="Prénom de l'élève"
value={formData.elevePrenom}
value={formData.studentFirstName}
onChange={handleChange}
className="w-full"
/>
@ -121,11 +121,11 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
</div>
{formData.responsableType === 'new' && (
<InputTextIcon
name="responsableEmail"
name="guardianEmail"
type="email"
IconItem={Mail}
placeholder="Email du responsable"
value={formData.responsableEmail}
value={formData.guardianEmail}
onChange={handleChange}
className="w-full mt-4"
/>
@ -142,33 +142,33 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
</tr>
</thead>
<tbody>
{eleves.map((eleve, index) => (
{students.map((student, index) => (
<tr
key={eleve.id}
className={`cursor-pointer ${selectedEleve && selectedEleve.id === eleve.id ? 'bg-emerald-600 text-white' : index % 2 === 0 ? 'bg-emerald-100' : ''}`}
onClick={() => handleEleveSelection(eleve)}
key={student.id}
className={`cursor-pointer ${selectedStudent && selectedStudent.id === student.id ? 'bg-emerald-600 text-white' : index % 2 === 0 ? 'bg-emerald-100' : ''}`}
onClick={() => handleEleveSelection(student)}
>
<td className="px-4 py-2 border">{eleve.nom}</td>
<td className="px-4 py-2 border">{eleve.prenom}</td>
<td className="px-4 py-2 border">{student.last_name}</td>
<td className="px-4 py-2 border">{student.first_name}</td>
</tr>
))}
</tbody>
</table>
</div>
{selectedEleve && (
{selectedStudent && (
<div className="mt-4">
<h3 className="font-bold">Responsables associés à {selectedEleve.nom} {selectedEleve.prenom} :</h3>
{existingResponsables.map((responsable) => (
<div key={responsable.id}>
<h3 className="font-bold">Responsables associés à {selectedStudent.last_name} {selectedStudent.first_name} :</h3>
{existingGuardians.map((guardian) => (
<div key={guardian.id}>
<label className="flex items-center space-x-3 mt-2">
<input
type="checkbox"
checked={formData.selectedResponsables.includes(responsable.id)}
checked={formData.selectedGuardians.includes(guardian.id)}
className="form-checkbox h-5 w-5 text-emerald-600"
onChange={() => handleResponsableSelection(responsable.id)}
onChange={() => handleResponsableSelection(guardian.id)}
/>
<span className="text-gray-900">
{responsable.nom && responsable.prenom ? `${responsable.nom} ${responsable.prenom}` : `${responsable.mail}`}
{guardian.last_name && guardian.first_name ? `${guardian.last_name} ${guardian.first_name}` : `${guardian.email}`}
</span>
</label>
</div>
@ -184,11 +184,11 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
<div className="mt-6">
<h2 className="text-l font-bold mb-4">Téléphone (optionnel)</h2>
<InputTextIcon
name="responsableTel"
name="guardianPhone"
type="tel"
IconItem={Phone}
placeholder="Numéro de téléphone"
value={formData.responsableTel}
value={formData.guardianPhone}
onChange={handleChange}
className="w-full mt-4"
/>
@ -210,8 +210,8 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
</thead>
<tbody>
<tr>
<td className="px-4 py-2 border">{formData.eleveNom}</td>
<td className="px-4 py-2 border">{formData.elevePrenom}</td>
<td className="px-4 py-2 border">{formData.studentLastName}</td>
<td className="px-4 py-2 border">{formData.studentFirstName}</td>
</tr>
</tbody>
</table>
@ -228,15 +228,15 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
</thead>
<tbody>
<tr>
<td className="px-4 py-2 border">{formData.responsableEmail}</td>
<td className="px-4 py-2 border">{formData.responsableTel}</td>
<td className="px-4 py-2 border">{formData.guardianEmail}</td>
<td className="px-4 py-2 border">{formData.guardianPhone}</td>
</tr>
</tbody>
</table>
)}
{formData.responsableType === 'existing' && selectedEleve && (
{formData.responsableType === 'existing' && selectedStudent && (
<div>
<p>Associé(s) à : {selectedEleve.nom} {selectedEleve.prenom}</p>
<p>Associé(s) à : {selectedStudent.nom} {selectedStudent.prenom}</p>
<table className="min-w-full bg-white border">
<thead>
<tr>
@ -246,11 +246,11 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
</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>
{existingGuardians.filter(guardian => formData.selectedGuardians.includes(guardian.id)).map((guardian) => (
<tr key={guardian.id}>
<td className="px-4 py-2 border">{guardian.last_name}</td>
<td className="px-4 py-2 border">{guardian.first_name}</td>
<td className="px-4 py-2 border">{guardian.email}</td>
</tr>
))}
</tbody>
@ -281,15 +281,15 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
<Button text="Suivant"
onClick={nextStep}
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
(step === 1 && (!formData.eleveNom || !formData.elevePrenom)) ||
(step === 2 && formData.responsableType === "new" && !formData.responsableEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedResponsables.length === 0)
(step === 1 && (!formData.studentLastName || !formData.studentFirstName)) ||
(step === 2 && formData.responsableType === "new" && !formData.guardianEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedGuardians.length === 0)
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
}`}
disabled={(step === 1 && (!formData.eleveNom || !formData.elevePrenom)) ||
(step === 2 && formData.responsableType === "new" && !formData.responsableEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedResponsables.length === 0)
disabled={(step === 1 && (!formData.studentLastName || !formData.studentFirstName)) ||
(step === 2 && formData.responsableType === "new" && !formData.guardianEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedGuardians.length === 0)
}
primary
name="Next" />

View File

@ -5,7 +5,8 @@ import ResponsableInputFields from '@/components/Inscription/ResponsableInputFie
import Loader from '@/components/Loader';
import Button from '@/components/Button';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import FileUpload from '@/app/[locale]/admin/subscriptions/components/FileUpload';
import Table from '@/components/Table';
const niveaux = [
{ value:'1', label: 'TPS - Très Petite Section'},
@ -39,6 +40,8 @@ export default function InscriptionFormShared({
initialData?.responsables || []
);
const [uploadedFiles, setUploadedFiles] = useState([]);
// Mettre à jour les données quand initialData change
useEffect(() => {
if (initialData) {
@ -62,6 +65,10 @@ export default function InscriptionFormShared({
setFormData(prev => ({...prev, [field]: value}));
};
const handleFileUpload = (file, fileName) => {
setUploadedFiles([...uploadedFiles, { file, fileName }]);
};
const handleSubmit = (e) => {
e.preventDefault();
onSubmit({
@ -72,6 +79,15 @@ export default function InscriptionFormShared({
});
};
const columns = [
{ name: 'Nom du fichier', transform: (row) => row.nom },
{ name: 'Actions', transform: (row) => (
<a href={URL.createObjectURL(row.fichier)} target='_blank' className="text-blue-500 hover:text-blue-700">
Télécharger
</a>
) },
];
if (isLoading) return <Loader />;
return (
@ -170,6 +186,20 @@ export default function InscriptionFormShared({
/>
</div>
{/* Section Fichiers d'inscription */}
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<h2 className="text-xl font-bold mb-4 text-gray-800">Fichiers à remplir</h2>
<Table
data={uploadedFiles}
columns={columns}
itemsPerPage={5}
currentPage={1}
totalPages={1}
onPageChange={() => {}}
/>
<FileUpload onFileUpload={handleFileUpload} />
</div>
{/* Boutons de contrôle */}
<div className="flex justify-end space-x-4">
<Button href={cancelUrl} text="Annuler" />