mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
fix: Ajout d'un champ is_required pour les documents parents facultatifs
This commit is contained in:
@ -291,6 +291,7 @@ class RegistrationParentFileMaster(models.Model):
|
|||||||
groups = models.ManyToManyField(RegistrationFileGroup, related_name='parent_file_masters', blank=True)
|
groups = models.ManyToManyField(RegistrationFileGroup, related_name='parent_file_masters', blank=True)
|
||||||
name = models.CharField(max_length=255, default="")
|
name = models.CharField(max_length=255, default="")
|
||||||
description = models.CharField(blank=True, null=True)
|
description = models.CharField(blank=True, null=True)
|
||||||
|
is_required = models.BooleanField(default=False)
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
####################### CLONE FILES ########################
|
####################### CLONE FILES ########################
|
||||||
|
|||||||
@ -46,6 +46,8 @@ class RegistrationParentFileTemplateSerializer(serializers.ModelSerializer):
|
|||||||
file_url = serializers.SerializerMethodField()
|
file_url = serializers.SerializerMethodField()
|
||||||
master_name = serializers.CharField(source='master.name', read_only=True)
|
master_name = serializers.CharField(source='master.name', read_only=True)
|
||||||
master_description = serializers.CharField(source='master.description', read_only=True)
|
master_description = serializers.CharField(source='master.description', read_only=True)
|
||||||
|
is_required = serializers.BooleanField(source='master.is_required', read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RegistrationParentFileTemplate
|
model = RegistrationParentFileTemplate
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|||||||
@ -17,14 +17,15 @@ export default function EmailSender({ csrfToken }) {
|
|||||||
message,
|
message,
|
||||||
};
|
};
|
||||||
sendMessage(data);
|
sendMessage(data);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-4 bg-white rounded shadow">
|
<div className="p-4 bg-white rounded shadow">
|
||||||
<h2 className="text-xl font-bold mb-4">Envoyer un Email</h2>
|
<h2 className="text-xl font-bold mb-4">Envoyer un Email</h2>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block font-medium">Destinataires (séparés par des virgules)</label>
|
<label className="block font-medium">
|
||||||
|
Destinataires (séparés par des virgules)
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={recipients}
|
value={recipients}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ const CheckBox = ({
|
|||||||
itemLabelFunc = () => null,
|
itemLabelFunc = () => null,
|
||||||
horizontal,
|
horizontal,
|
||||||
}) => {
|
}) => {
|
||||||
|
console.log(formData);
|
||||||
const isChecked = formData[fieldName].includes(parseInt(item.id));
|
const isChecked = formData[fieldName].includes(parseInt(item.id));
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -73,7 +73,7 @@ export default function InscriptionFormShared({
|
|||||||
const [uploadedFiles, setUploadedFiles] = useState([]);
|
const [uploadedFiles, setUploadedFiles] = useState([]);
|
||||||
const [schoolFileTemplates, setSchoolFileTemplates] = useState([]);
|
const [schoolFileTemplates, setSchoolFileTemplates] = useState([]);
|
||||||
const [parentFileTemplates, setParentFileTemplates] = useState([]);
|
const [parentFileTemplates, setParentFileTemplates] = useState([]);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(6);
|
||||||
|
|
||||||
const [isPage1Valid, setIsPage1Valid] = useState(false);
|
const [isPage1Valid, setIsPage1Valid] = useState(false);
|
||||||
const [isPage2Valid, setIsPage2Valid] = useState(false);
|
const [isPage2Valid, setIsPage2Valid] = useState(false);
|
||||||
@ -131,13 +131,14 @@ export default function InscriptionFormShared({
|
|||||||
}, [schoolFileTemplates]);
|
}, [schoolFileTemplates]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Vérifier si tous les parentFileTemplates ont leur champ "file" différent de null
|
// Vérifier si tous les documents avec is_required = true ont leur champ "file" différent de null
|
||||||
const allUploaded = parentFileTemplates.every(
|
const allRequiredUploaded = parentFileTemplates
|
||||||
(template) => template.file !== null
|
.filter((template) => template.is_required) // Ne garder que les documents requis
|
||||||
);
|
.every((template) => template.file !== null); // Vérifier que chaque fichier requis est uploadé
|
||||||
|
|
||||||
// Mettre à jour isPage6Valid en fonction de cette condition
|
// Mettre à jour isPage6Valid en fonction de cette condition
|
||||||
setIsPage6Valid(allUploaded);
|
setIsPage6Valid(allRequiredUploaded);
|
||||||
|
console.log(allRequiredUploaded);
|
||||||
}, [parentFileTemplates]);
|
}, [parentFileTemplates]);
|
||||||
|
|
||||||
const handleTemplateSigned = (index) => {
|
const handleTemplateSigned = (index) => {
|
||||||
@ -659,8 +660,7 @@ export default function InscriptionFormShared({
|
|||||||
(currentPage === 2 && !isPage2Valid) ||
|
(currentPage === 2 && !isPage2Valid) ||
|
||||||
(currentPage === 3 && !isPage3Valid) ||
|
(currentPage === 3 && !isPage3Valid) ||
|
||||||
(currentPage === 4 && !isPage4Valid) ||
|
(currentPage === 4 && !isPage4Valid) ||
|
||||||
(currentPage === 5 && !isPage5Valid) ||
|
(currentPage === 5 && !isPage5Valid)
|
||||||
(currentPage === 6 && !isPage6Valid)
|
|
||||||
? 'bg-gray-300 text-gray-700 cursor-not-allowed'
|
? 'bg-gray-300 text-gray-700 cursor-not-allowed'
|
||||||
: 'bg-emerald-500 text-white hover:bg-emerald-600'
|
: 'bg-emerald-500 text-white hover:bg-emerald-600'
|
||||||
}`}
|
}`}
|
||||||
@ -669,8 +669,7 @@ export default function InscriptionFormShared({
|
|||||||
(currentPage === 2 && !isPage2Valid) ||
|
(currentPage === 2 && !isPage2Valid) ||
|
||||||
(currentPage === 3 && !isPage3Valid) ||
|
(currentPage === 3 && !isPage3Valid) ||
|
||||||
(currentPage === 4 && !isPage4Valid) ||
|
(currentPage === 4 && !isPage4Valid) ||
|
||||||
(currentPage === 5 && !isPage5Valid) ||
|
(currentPage === 5 && !isPage5Valid)
|
||||||
(currentPage === 6 && !isPage6Valid)
|
|
||||||
}
|
}
|
||||||
primary
|
primary
|
||||||
name="Next"
|
name="Next"
|
||||||
@ -682,7 +681,12 @@ export default function InscriptionFormShared({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleSubmit(e);
|
handleSubmit(e);
|
||||||
}}
|
}}
|
||||||
className="px-4 py-2 bg-emerald-500 text-white rounded-md shadow-sm hover:bg-emerald-600 focus:outline-none"
|
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
|
||||||
|
currentPage === 6 && !isPage6Valid
|
||||||
|
? 'bg-gray-300 text-gray-700 cursor-not-allowed'
|
||||||
|
: 'bg-emerald-500 text-white hover:bg-emerald-600'
|
||||||
|
}`}
|
||||||
|
disabled={currentPage === 6 && !isPage6Valid}
|
||||||
primary
|
primary
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import logger from '@/utils/logger';
|
|||||||
import { createRegistrationParentFileTemplate } from '@/app/actions/registerFileGroupAction';
|
import { createRegistrationParentFileTemplate } from '@/app/actions/registerFileGroupAction';
|
||||||
import { useCsrfToken } from '@/context/CsrfContext';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import SectionHeader from '@/components/SectionHeader';
|
import SectionHeader from '@/components/SectionHeader';
|
||||||
|
import ToggleSwitch from '@/components/ToggleSwitch';
|
||||||
|
|
||||||
export default function ParentFilesSection({
|
export default function ParentFilesSection({
|
||||||
parentFiles,
|
parentFiles,
|
||||||
@ -32,7 +33,7 @@ export default function ParentFilesSection({
|
|||||||
|
|
||||||
const handleAddEmptyRequiredDocument = () => {
|
const handleAddEmptyRequiredDocument = () => {
|
||||||
setEditingDocumentId('new');
|
setEditingDocumentId('new');
|
||||||
setFormData({ name: '', description: '', groups: [] });
|
setFormData({ name: '', description: '', groups: [], is_required: false }); // Add is_required
|
||||||
setSelectedGroups([]); // Réinitialiser les groupes sélectionnés
|
setSelectedGroups([]); // Réinitialiser les groupes sélectionnés
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,7 +59,6 @@ export default function ParentFilesSection({
|
|||||||
"Attention !\nVeuillez sélectionner au moins un dossier d'inscription pour valider l'opération"
|
"Attention !\nVeuillez sélectionner au moins un dossier d'inscription pour valider l'opération"
|
||||||
);
|
);
|
||||||
setPopupVisible(true);
|
setPopupVisible(true);
|
||||||
setPopupVisible(true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,13 +73,12 @@ export default function ParentFilesSection({
|
|||||||
setFormData(null);
|
setFormData(null);
|
||||||
setSelectedGroups([]);
|
setSelectedGroups([]);
|
||||||
|
|
||||||
guardianDetails.forEach((guardian, index) => {
|
guardianDetails.forEach((guardian) => {
|
||||||
// Création des templates
|
// Création des templates
|
||||||
const data = {
|
const data = {
|
||||||
master: createdDocument?.id,
|
master: createdDocument?.id,
|
||||||
registration_form: guardian.registration_form,
|
registration_form: guardian.registration_form,
|
||||||
};
|
};
|
||||||
console.log(guardian);
|
|
||||||
createRegistrationParentFileTemplate(data, csrfToken)
|
createRegistrationParentFileTemplate(data, csrfToken)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
logger.debug('Template enregistré avec succès:', response);
|
logger.debug('Template enregistré avec succès:', response);
|
||||||
@ -178,6 +177,22 @@ export default function ParentFilesSection({
|
|||||||
errorMsg={null}
|
errorMsg={null}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
case 'Obligatoire':
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center items-center">
|
||||||
|
<ToggleSwitch
|
||||||
|
name="is_required"
|
||||||
|
checked={formData.is_required} // Utilise la valeur booléenne de is_required
|
||||||
|
onChange={(e) => {
|
||||||
|
const { checked } = e.target; // Récupère l'état du toggle
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
is_required: checked, // Met à jour directement le champ is_required
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
case 'Actions':
|
case 'Actions':
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center space-x-2">
|
<div className="flex justify-center space-x-2">
|
||||||
@ -218,6 +233,18 @@ export default function ParentFilesSection({
|
|||||||
.join(', ')}
|
.join(', ')}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
case 'Obligatoire':
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={`px-3 py-1 rounded-full text-sm font-semibold ${
|
||||||
|
document.is_required
|
||||||
|
? 'bg-green-100 text-green-600'
|
||||||
|
: 'bg-gray-100 text-gray-600'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{document.is_required ? 'Oui' : 'Non'}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
case 'Actions':
|
case 'Actions':
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center space-x-2">
|
<div className="flex justify-center space-x-2">
|
||||||
@ -283,6 +310,10 @@ export default function ParentFilesSection({
|
|||||||
transform: (row) =>
|
transform: (row) =>
|
||||||
renderRequiredDocumentCell(row, "Dossiers d'inscription"),
|
renderRequiredDocumentCell(row, "Dossiers d'inscription"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Obligatoire',
|
||||||
|
transform: (row) => renderRequiredDocumentCell(row, 'Obligatoire'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Actions',
|
name: 'Actions',
|
||||||
transform: (row) => renderRequiredDocumentCell(row, 'Actions'),
|
transform: (row) => renderRequiredDocumentCell(row, 'Actions'),
|
||||||
|
|||||||
Reference in New Issue
Block a user