feat: Signatures électroniques docuseal [#22]

This commit is contained in:
N3WT DE COMPET
2025-02-28 18:30:18 +01:00
parent 8897d523dc
commit c8c8941ec8
41 changed files with 984 additions and 549 deletions

View File

@ -0,0 +1,18 @@
import React from 'react';
import Table from '@/components/Table';
export default function FilesToSign({ fileTemplates, columns }) {
return (
<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={fileTemplates}
columns={columns}
itemsPerPage={5}
currentPage={1}
totalPages={1}
onPageChange={() => {}}
/>
</div>
);
}

View File

@ -0,0 +1,18 @@
import React from 'react';
import Table from '@/components/Table';
export default function FilesToUpload({ fileTemplates, columns }) {
return (
<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 à uploader</h2>
<Table
data={fileTemplates}
columns={columns}
itemsPerPage={5}
currentPage={1}
totalPages={1}
onPageChange={() => {}}
/>
</div>
);
}

View File

@ -7,7 +7,7 @@ import Loader from '@/components/Loader';
import Button from '@/components/Button';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Table from '@/components/Table';
import { fetchRegisterFormFileTemplate, createRegistrationFormFile, fetchRegisterForm, deleteRegisterFormFile } from '@/app/actions/subscriptionAction';
import { fetchRegistrationTemplateMaster, createRegistrationTemplates, fetchRegisterForm, deleteRegistrationTemplates } from '@/app/actions/subscriptionAction';
import { fetchRegistrationFileFromGroup } from '@/app/actions/registerFileGroupAction';
import { Download, Upload, Trash2, Eye } from 'lucide-react';
import { BASE_URL } from '@/utils/Url';
@ -117,7 +117,7 @@ export default function InscriptionFormShared({
data.append('register_form', formData.id);
try {
const response = await createRegistrationFormFile(data, csrfToken);
const response = await createRegistrationTemplates(data, csrfToken);
if (response) {
setUploadedFiles(prev => {
const newFiles = prev.filter(f => parseInt(f.template) !== currentTemplateId);
@ -158,7 +158,7 @@ export default function InscriptionFormShared({
if (!fileToDelete) return;
try {
await deleteRegisterFormFile(fileToDelete.id, csrfToken);
await deleteRegistrationTemplates(fileToDelete.id, csrfToken);
setUploadedFiles(prev => prev.filter(f => parseInt(f.template) !== templateId));
} catch (error) {
logger.error('Error deleting file:', error);
@ -276,7 +276,7 @@ export default function InscriptionFormShared({
<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>
<iframe
src={`${BASE_URL}/data/${requiredFileTemplates[currentPage - 2].file}?signature=true`}
src={`${BASE_URL}/data/${requiredFileTemplates[currentPage - 2].file}`}
width="100%"
height="800px"
className="w-full" // Utiliser la classe CSS pour la largeur

View File

@ -0,0 +1,126 @@
import React from 'react';
import InputText from '@/components/InputText';
import SelectChoice from '@/components/SelectChoice';
import ResponsableInputFields from '@/components/Inscription/ResponsableInputFields';
const levels = [
{ value:'1', label: 'TPS - Très Petite Section'},
{ value:'2', label: 'PS - Petite Section'},
{ value:'3', label: 'MS - Moyenne Section'},
{ value:'4', label: 'GS - Grande Section'},
];
export default function StudentInfoForm({ formData, updateFormField, guardians, setGuardians, errors }) {
const getError = (field) => {
return errors?.student?.[field]?.[0];
};
return (
<>
<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">Informations de l&apos;élève</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<InputText
name="last_name"
label="Nom"
value={formData.last_name}
onChange={(e) => updateFormField('last_name', e.target.value)}
required
errorMsg={getError('last_name')}
/>
<InputText
name="first_name"
label="Prénom"
value={formData.first_name}
onChange={(e) => updateFormField('first_name', e.target.value)}
errorMsg={getError('first_name')}
required
/>
<InputText
name="nationality"
label="Nationalité"
value={formData.nationality}
required
onChange={(e) => updateFormField('nationality', e.target.value)}
/>
<InputText
name="birth_date"
type="date"
label="Date de Naissance"
value={formData.birth_date}
onChange={(e) => updateFormField('birth_date', e.target.value)}
required
errorMsg={getError('birth_date')}
/>
<InputText
name="birth_place"
label="Lieu de Naissance"
value={formData.birth_place}
onChange={(e) => updateFormField('birth_place', e.target.value)}
required
errorMsg={getError('birth_place')}
/>
<InputText
name="birth_postal_code"
label="Code Postal de Naissance"
value={formData.birth_postal_code}
onChange={(e) => updateFormField('birth_postal_code', e.target.value)}
required
errorMsg={getError('birth_postal_code')}
/>
<div className="md:col-span-2">
<InputText
name="address"
label="Adresse"
value={formData.address}
onChange={(e) => updateFormField('address', e.target.value)}
required
errorMsg={getError('address')}
/>
</div>
<InputText
name="attending_physician"
label="Médecin Traitant"
value={formData.attending_physician}
onChange={(e) => updateFormField('attending_physician', e.target.value)}
required
errorMsg={getError('attending_physician')}
/>
<SelectChoice
name="level"
label="Niveau"
placeHolder="Sélectionner un niveau"
selected={formData.level}
callback={(e) => updateFormField('level', e.target.value)}
choices={levels}
required
errorMsg={getError('level')}
/>
</div>
</div>
<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">Responsables</h2>
<ResponsableInputFields
guardians={guardians}
onGuardiansChange={(id, field, value) => {
const updatedGuardians = guardians.map(resp =>
resp.id === id ? { ...resp, [field]: value } : resp
);
setGuardians(updatedGuardians);
}}
addGuardian={(e) => {
e.preventDefault();
setGuardians([...guardians, { id: Date.now() }]);
}}
deleteGuardian={(index) => {
const newArray = [...guardians];
newArray.splice(index, 1);
setGuardians(newArray);
}}
errors={errors?.student?.guardians || []}
/>
</div>
</>
);
}