feat: Ajout des Bundles de fichiers [#24]

This commit is contained in:
Luc SORIGNET
2025-02-10 18:35:24 +01:00
parent fb7fbaf839
commit ffc6ce8de8
25 changed files with 1736 additions and 743 deletions

View File

@ -9,7 +9,7 @@ import DiscountsSection from '@/components/Structure/Tarification/DiscountsSecti
import SectionTitle from '@/components/SectionTitle';
import ProgressStep from '@/components/ProgressStep';
const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, registrationFees, tuitionFees, onSubmit, currentStep }) => {
const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, registrationFees, tuitionFees, onSubmit, currentStep, groups }) => {
const [formData, setFormData] = useState({
studentLastName: '',
studentFirstName: '',
@ -21,7 +21,8 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
selectedRegistrationDiscounts: [],
selectedRegistrationFees: registrationFees.map(fee => fee.id),
selectedTuitionDiscounts: [],
selectedTuitionFees: []
selectedTuitionFees: [],
selectedFileGroup: null // Ajout du groupe de fichiers sélectionné
});
const [step, setStep] = useState(currentStep || 1);
@ -35,10 +36,11 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
2: 'Nouveau Responsable',
3: "Frais d'inscription",
4: 'Frais de scolarité',
5: 'Récapitulatif'
5: 'Documents requis',
6: 'Récapitulatif'
};
const steps = ['Élève', 'Responsable', 'Inscription', 'Scolarité', 'Récap'];
const steps = ['Élève', 'Responsable', 'Inscription', 'Scolarité', 'Documents', 'Récap'];
const isStep1Valid = formData.studentLastName && formData.studentFirstName;
const isStep2Valid = (
@ -47,7 +49,8 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
);
const isStep3Valid = formData.selectedRegistrationFees.length > 0;
const isStep4Valid = formData.selectedTuitionFees.length > 0;
const isStep5Valid = isStep1Valid && isStep2Valid && isStep3Valid && isStep4Valid;
const isStep5Valid = formData.selectedFileGroup !== null;
const isStep6Valid = isStep1Valid && isStep2Valid && isStep3Valid && isStep4Valid && isStep5Valid;
const isStepValid = (stepNumber) => {
switch (stepNumber) {
@ -61,6 +64,8 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
return isStep4Valid;
case 5:
return isStep5Valid;
case 6:
return isStep6Valid;
default:
return false;
}
@ -464,6 +469,44 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
</div>
)}
{step === 5 && (
<div>
{groups.length > 0 ? (
<div className="space-y-4">
<h3 className="font-bold">Sélectionnez un groupe de documents</h3>
{groups.map((group) => (
<div key={group.id} className="flex items-center space-x-3">
<input
type="radio"
name="fileGroup"
value={group.id}
checked={formData.selectedFileGroup === group.id}
onChange={(e) => setFormData({
...formData,
selectedFileGroup: parseInt(e.target.value)
})}
className="form-radio h-4 w-4 text-emerald-600"
/>
<label className="text-gray-900">
{group.name}
{group.description && (
<span className="text-sm text-gray-500 ml-2">
({group.description})
</span>
)}
</label>
</div>
))}
</div>
) : (
<p className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong className="font-bold">Attention!</strong>
<span className="block sm:inline"> Aucun groupe de documents n'a été créé.</span>
</p>
)}
</div>
)}
{step === steps.length && (
<div>
<div className="space-y-4">
@ -553,7 +596,8 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
(step === 1 && !isStep1Valid) ||
(step === 2 && !isStep2Valid) ||
(step === 3 && !isStep3Valid) ||
(step === 4 && !isStep4Valid)
(step === 4 && !isStep4Valid) ||
(step === 5 && !isStep5Valid)
)
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
@ -563,7 +607,8 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
(step === 1 && !isStep1Valid) ||
(step === 2 && !isStep2Valid) ||
(step === 3 && !isStep3Valid) ||
(step === 4 && !isStep4Valid)
(step === 4 && !isStep4Valid) ||
(step === 5 && !isStep5Valid)
)
}
primary

View File

@ -8,9 +8,10 @@ import Button from '@/components/Button';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Table from '@/components/Table';
import { fetchRegisterFormFileTemplate, createRegistrationFormFile, fetchRegisterForm, deleteRegisterFormFile } from '@/app/lib/subscriptionAction';
import { fetchRegistrationFileFromGroup } from '@/app/lib/registerFileGroupAction';
import { Download, Upload, Trash2, Eye } from 'lucide-react';
import { BASE_URL } from '@/utils/Url';
import DraggableFileUpload from '@/app/[locale]/admin/subscriptions/components/DraggableFileUpload';
import DraggableFileUpload from '@/components/DraggableFileUpload';
import Modal from '@/components/Modal';
import FileStatusLabel from '@/components/FileStatusLabel';
@ -57,6 +58,7 @@ export default function InscriptionFormShared({
// États pour la gestion des fichiers
const [uploadedFiles, setUploadedFiles] = useState([]);
const [fileTemplates, setFileTemplates] = useState([]);
const [fileGroup, setFileGroup] = useState(null);
const [fileName, setFileName] = useState("");
const [file, setFile] = useState("");
const [showUploadModal, setShowUploadModal] = useState(false);
@ -83,15 +85,21 @@ export default function InscriptionFormShared({
});
setGuardians(data?.student?.guardians || []);
setUploadedFiles(data.registration_files || []);
setFileGroup(data.fileGroup || null);
});
fetchRegisterFormFileTemplate().then((data) => {
setFileTemplates(data);
});
setIsLoading(false);
}
}, [studentId]);
useEffect(() => {
if(fileGroup){
fetchRegistrationFileFromGroup(fileGroup).then((data) => {
setFileTemplates(data);
});
}
}, [fileGroup]);
// Fonctions de gestion du formulaire et des fichiers
const updateFormField = (field, value) => {
setFormData(prev => ({...prev, [field]: value}));