mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Gestion de la sauvegarde du fichier d'inscription / affichage du
fichier avec le bon nom / possibilité de refuser un DI
This commit is contained in:
@ -21,7 +21,7 @@ import DraggableFileUpload from '@/components/DraggableFileUpload';
|
||||
import Modal from '@/components/Modal';
|
||||
import FileStatusLabel from '@/components/FileStatusLabel';
|
||||
import logger from '@/utils/logger';
|
||||
import StudentInfoForm from '@/components/Inscription/StudentInfoForm';
|
||||
import StudentInfoForm, { validateStudentInfo } from '@/components/Inscription/StudentInfoForm';
|
||||
import FilesToSign from '@/components/Inscription/FilesToSign';
|
||||
import FilesToUpload from '@/components/Inscription/FilesToUpload';
|
||||
import { DocusealForm } from '@docuseal/react';
|
||||
@ -70,6 +70,14 @@ export default function InscriptionFormShared({
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
const isCurrentPageValid = () => {
|
||||
if (currentPage === 1) {
|
||||
const isValid = validateStudentInfo(formData);
|
||||
return isValid;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Chargement initial des données
|
||||
// Mettre à jour les données quand initialData change
|
||||
useEffect(() => {
|
||||
@ -178,12 +186,25 @@ export default function InscriptionFormShared({
|
||||
...formData,
|
||||
guardians
|
||||
},
|
||||
establishment: ESTABLISHMENT_ID,
|
||||
establishment: 1,
|
||||
status:3
|
||||
}
|
||||
onSubmit(data);
|
||||
};
|
||||
|
||||
// Soumission du formulaire
|
||||
const handleSave = (e) => {
|
||||
e.preventDefault();
|
||||
const data ={
|
||||
student: {
|
||||
...formData,
|
||||
guardians
|
||||
},
|
||||
establishment: 1
|
||||
}
|
||||
onSubmit(data);
|
||||
};
|
||||
|
||||
// Récupération des messages d'erreur
|
||||
const getError = (field) => {
|
||||
return errors?.student?.[field]?.[0];
|
||||
@ -276,31 +297,52 @@ export default function InscriptionFormShared({
|
||||
{/* Pages suivantes : Section Fichiers d'inscription */}
|
||||
{currentPage > 1 && currentPage <= requiredFileTemplates.length + 1 && (
|
||||
<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">{requiredFileTemplates[currentPage - 2].name}</h2>
|
||||
<DocusealForm
|
||||
id="docusealForm"
|
||||
src={"https://docuseal.com/s/"+requiredFileTemplates[currentPage - 2].slug}
|
||||
withDownloadButton={false}
|
||||
onComplete={() => {
|
||||
downloadTemplate(requiredFileTemplates[currentPage - 2].slug)
|
||||
.then((data) => fetch(data))
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const file = new File([blob], `${requiredFileTemplates[currentPage - 2].name}.pdf`, { type: blob.type });
|
||||
const updateData = new FormData();
|
||||
updateData.append('file', file);
|
||||
|
||||
return editRegistrationTemplates(requiredFileTemplates[currentPage - 2].id, updateData, csrfToken);
|
||||
})
|
||||
.then((data) => {
|
||||
logger.debug("EDIT TEMPLATE : ", data);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error("error editing template : ", error);
|
||||
});
|
||||
}}
|
||||
>
|
||||
</DocusealForm>
|
||||
{/* Titre du document */}
|
||||
<div className="mb-4">
|
||||
<h2 className="text-lg font-semibold text-gray-800">
|
||||
{requiredFileTemplates[currentPage - 2].name || "Document sans nom"}
|
||||
</h2>
|
||||
<p className="text-sm text-gray-500">
|
||||
{requiredFileTemplates[currentPage - 2].description || "Aucune description disponible pour ce document."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Affichage du formulaire ou du document */}
|
||||
{requiredFileTemplates[currentPage - 2].file === "" ? (
|
||||
<DocusealForm
|
||||
id="docusealForm"
|
||||
src={"https://docuseal.com/s/" + requiredFileTemplates[currentPage - 2].slug}
|
||||
withDownloadButton={false}
|
||||
onComplete={() => {
|
||||
downloadTemplate(requiredFileTemplates[currentPage - 2].slug)
|
||||
.then((data) => fetch(data))
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const file = new File([blob], `${requiredFileTemplates[currentPage - 2].name}.pdf`, { type: blob.type });
|
||||
const updateData = new FormData();
|
||||
updateData.append('file', file);
|
||||
|
||||
return editRegistrationTemplates(requiredFileTemplates[currentPage - 2].id, updateData, csrfToken);
|
||||
})
|
||||
.then((data) => {
|
||||
logger.debug("EDIT TEMPLATE : ", data);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error("error editing template : ", error);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<iframe
|
||||
src={`${BASE_URL}/${requiredFileTemplates[currentPage - 2].file}`}
|
||||
title="Document Viewer"
|
||||
className="w-full"
|
||||
style={{
|
||||
height: '75vh', // Ajuster la hauteur à 75% de la fenêtre
|
||||
border: 'none',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -316,11 +358,29 @@ export default function InscriptionFormShared({
|
||||
|
||||
{/* Boutons de contrôle */}
|
||||
<div className="flex justify-end space-x-4">
|
||||
<Button
|
||||
text="Sauvegarder"
|
||||
onClick={handleSave}
|
||||
className="px-4 py-2 rounded-md shadow-sm focus:outline-none bg-orange-500 text-white hover:bg-orange-600"
|
||||
primary
|
||||
name="Save"
|
||||
/>
|
||||
{currentPage > 1 && (
|
||||
<Button text="Précédent" onClick={(e) => { e.preventDefault(); handlePreviousPage(); }} />
|
||||
)}
|
||||
{currentPage < requiredFileTemplates.length + 2 && (
|
||||
<Button text="Suivant" onClick={(e) => { e.preventDefault(); handleNextPage(); }} />
|
||||
<Button
|
||||
text="Suivant"
|
||||
onClick={(e) => { e.preventDefault(); handleNextPage(); }}
|
||||
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
|
||||
!isCurrentPageValid()
|
||||
? "bg-gray-300 text-gray-700 cursor-not-allowed"
|
||||
: "bg-emerald-500 text-white hover:bg-emerald-600"
|
||||
}`}
|
||||
disabled={!isCurrentPageValid()}
|
||||
primary
|
||||
name="Next"
|
||||
/>
|
||||
)}
|
||||
{currentPage === requiredFileTemplates.length + 2 && (
|
||||
<Button type="submit" text="Valider" primary />
|
||||
|
||||
@ -56,8 +56,8 @@ export default function ResponsableInputFields({guardians, onGuardiansChange, ad
|
||||
name="mailResponsable"
|
||||
type="email"
|
||||
label={t('email')}
|
||||
value={item.email}
|
||||
onChange={(event) => {onGuardiansChange(item.id, "email", event.target.value)}}
|
||||
value={item.associated_profile_email}
|
||||
onChange={(event) => {onGuardiansChange(item.id, "associated_profile_email", event.target.value)}}
|
||||
required
|
||||
errorMsg={getError(index, 'email')}
|
||||
/>
|
||||
|
||||
@ -10,6 +10,28 @@ const levels = [
|
||||
{ value:'4', label: 'GS - Grande Section'},
|
||||
];
|
||||
|
||||
// Fonction de validation pour vérifier les champs requis
|
||||
export function validateStudentInfo(formData) {
|
||||
const requiredFields = [
|
||||
'last_name',
|
||||
'first_name',
|
||||
'nationality',
|
||||
'birth_date',
|
||||
'birth_place',
|
||||
'birth_postal_code',
|
||||
'address',
|
||||
'attending_physician',
|
||||
'level',
|
||||
];
|
||||
|
||||
const isValid = requiredFields.every((field) => {
|
||||
const value = formData[field];
|
||||
return typeof value === 'string' ? value.trim() !== '' : Boolean(value);
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
export default function StudentInfoForm({ formData, updateFormField, guardians, setGuardians, errors }) {
|
||||
const getError = (field) => {
|
||||
return errors?.student?.[field]?.[0];
|
||||
|
||||
Reference in New Issue
Block a user