mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Ajout de l'option d'envoi automatique [#1]
This commit is contained in:
@ -133,7 +133,6 @@ class FicheInscriptionView(APIView):
|
|||||||
di.eleve.responsables.add(responsable)
|
di.eleve.responsables.add(responsable)
|
||||||
di.save()
|
di.save()
|
||||||
|
|
||||||
ficheInscriptions_List=bdd.getAllObjects(FicheInscription)
|
|
||||||
return JsonResponse(ficheEleve_serializer.data, safe=False)
|
return JsonResponse(ficheEleve_serializer.data, safe=False)
|
||||||
|
|
||||||
return JsonResponse(ficheEleve_serializer.errors, safe=False)
|
return JsonResponse(ficheEleve_serializer.errors, safe=False)
|
||||||
|
|||||||
@ -183,7 +183,7 @@ export default function Page({ params: { locale } }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchClasses();
|
fetchClasses();
|
||||||
fetchStudents();
|
fetchStudents();
|
||||||
}, []);
|
}, [fichesInscriptionsDataEnCours]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchDataAndSetState = () => {
|
const fetchDataAndSetState = () => {
|
||||||
@ -303,8 +303,16 @@ export default function Page({ params: { locale } }) {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('Success:', data);
|
console.log('Success:', data);
|
||||||
setFichesInscriptionsDataEnCours(prevState => [...prevState, data]);
|
setFichesInscriptionsDataEnCours(prevState => {
|
||||||
|
if (prevState && prevState.length > 0) {
|
||||||
|
return [...prevState, data];
|
||||||
|
}
|
||||||
|
return prevState;
|
||||||
|
});
|
||||||
setTotalPending(totalPending+1);
|
setTotalPending(totalPending+1);
|
||||||
|
if (updatedData.autoMail) {
|
||||||
|
sendConfirmFicheInscription(data.eleve.id, updatedData.eleveNom, updatedData.elevePrenom);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
@ -344,7 +352,7 @@ export default function Page({ params: { locale } }) {
|
|||||||
responsables: [
|
responsables: [
|
||||||
{
|
{
|
||||||
mail: updatedData.responsableEmail,
|
mail: updatedData.responsableEmail,
|
||||||
//telephone: telephoneResponsable,
|
telephone: updatedData.responsableTel,
|
||||||
profilAssocie: idProfil // Association entre le reponsable de l'élève et le profil créé par défaut précédemment
|
profilAssocie: idProfil // Association entre le reponsable de l'élève et le profil créé par défaut précédemment
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -364,8 +372,16 @@ export default function Page({ params: { locale } }) {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('Success:', data);
|
console.log('Success:', data);
|
||||||
setFichesInscriptionsDataEnCours(prevState => [...prevState, data]);
|
setFichesInscriptionsDataEnCours(prevState => {
|
||||||
|
if (prevState && prevState.length > 0) {
|
||||||
|
return [...prevState, data];
|
||||||
|
}
|
||||||
|
return prevState;
|
||||||
|
});
|
||||||
setTotalPending(totalPending+1);
|
setTotalPending(totalPending+1);
|
||||||
|
if (updatedData.autoMail) {
|
||||||
|
sendConfirmFicheInscription(data.eleve.id, updatedData.eleveNom, updatedData.elevePrenom);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
@ -623,6 +639,7 @@ const columnsSubscribed = [
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
title={"Création d'un nouveau dossier d'inscription"}
|
title={"Création d'un nouveau dossier d'inscription"}
|
||||||
|
size='sm:w-1/4'
|
||||||
ContentComponent={() => (
|
ContentComponent={() => (
|
||||||
<InscriptionForm eleves={eleves}
|
<InscriptionForm eleves={eleves}
|
||||||
onSubmit={createDI}
|
onSubmit={createDI}
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { User, Mail, Phone, UserCheck } from 'lucide-react';
|
||||||
|
import InputTextIcon from '@/components/InputTextIcon';
|
||||||
|
|
||||||
const InscriptionForm = ( { eleves, onSubmit }) => {
|
const InscriptionForm = ( { eleves, onSubmit }) => {
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
eleveNom: '',
|
eleveNom: '',
|
||||||
elevePrenom: '',
|
elevePrenom: '',
|
||||||
responsableEmail: '',
|
responsableEmail: '',
|
||||||
|
responsableTel: '',
|
||||||
selectedResponsables: [],
|
selectedResponsables: [],
|
||||||
responsableType: 'new'
|
responsableType: 'new'
|
||||||
});
|
});
|
||||||
@ -12,6 +15,13 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
const [step, setStep] = useState(1);
|
const [step, setStep] = useState(1);
|
||||||
const [selectedEleve, setSelectedEleve] = useState('');
|
const [selectedEleve, setSelectedEleve] = useState('');
|
||||||
const [existingResponsables, setExistingResponsables] = useState([]);
|
const [existingResponsables, setExistingResponsables] = useState([]);
|
||||||
|
const [autoMail, setAutoMail] = useState(false);
|
||||||
|
const maxStep = 4
|
||||||
|
|
||||||
|
const handleToggleChange = () => {
|
||||||
|
setAutoMail(!autoMail);
|
||||||
|
setFormData({ ...formData, autoMail: !autoMail });
|
||||||
|
};
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const { name, value, type } = e.target;
|
const { name, value, type } = e.target;
|
||||||
@ -22,7 +32,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const nextStep = () => {
|
const nextStep = () => {
|
||||||
if (step < 3) {
|
if (step < maxStep) {
|
||||||
setStep(step + 1);
|
setStep(step + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -52,31 +62,31 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
onSubmit(formData);
|
onSubmit({ ...formData, autoMail });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(eleves)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4 mt-8">
|
<div className="space-y-4 mt-8">
|
||||||
{step === 1 && (
|
{step === 1 && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold mb-4">Nouvel élève</h2>
|
<h2 className="text-2xl font-bold mb-4">Nouvel élève</h2>
|
||||||
<input
|
<InputTextIcon
|
||||||
type="text"
|
|
||||||
placeholder="Nom de l'élève"
|
|
||||||
name="eleveNom"
|
name="eleveNom"
|
||||||
|
type="text"
|
||||||
|
IconItem={User}
|
||||||
|
placeholder="Nom de l'élève"
|
||||||
value={formData.eleveNom}
|
value={formData.eleveNom}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-emerald-500 focus:border-emerald-500 italic"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
<input
|
<InputTextIcon
|
||||||
type="text"
|
|
||||||
placeholder="Prénom de l'élève"
|
|
||||||
name="elevePrenom"
|
name="elevePrenom"
|
||||||
|
type="text"
|
||||||
|
IconItem={User}
|
||||||
|
placeholder="Prénom de l'élève"
|
||||||
value={formData.elevePrenom}
|
value={formData.elevePrenom}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className="mt-4 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-emerald-500 focus:border-emerald-500 italic"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -109,16 +119,15 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{formData.responsableType === 'new' && (
|
{formData.responsableType === 'new' && (
|
||||||
<div className="mt-4">
|
<InputTextIcon
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
placeholder="Email du responsable"
|
|
||||||
name="responsableEmail"
|
name="responsableEmail"
|
||||||
|
type="email"
|
||||||
|
IconItem={Mail}
|
||||||
|
placeholder="Email du responsable"
|
||||||
value={formData.responsableEmail}
|
value={formData.responsableEmail}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-emerald-500 focus:border-emerald-500 italic"
|
className="w-full mt-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{formData.responsableType === 'existing' && (
|
{formData.responsableType === 'existing' && (
|
||||||
@ -171,21 +180,47 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{step === 3 && (
|
{step === 3 && (
|
||||||
|
<div className="mt-6">
|
||||||
|
<h2 className="text-2xl font-bold mb-4">Téléphone (optionnel)</h2>
|
||||||
|
<InputTextIcon
|
||||||
|
name="responsableTel"
|
||||||
|
type="tel"
|
||||||
|
IconItem={Phone}
|
||||||
|
placeholder="Numéro de téléphone"
|
||||||
|
value={formData.responsableTel}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="w-full mt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === maxStep && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold mb-4">Récapitulatif</h2>
|
<h2 className="text-2xl font-bold mb-4">Récapitulatif</h2>
|
||||||
<div className="mb-4">
|
<div className="flex items-center justify-between space-x-4">
|
||||||
<h3 className="text-xl font-semibold">Élève</h3>
|
<div className="bg-gray-100 p-3 rounded-lg shadow-md flex items-center w-1/2 mb-4">
|
||||||
|
<User className="w-10 h-10 text-gray-300 mr-4" />
|
||||||
|
<div>
|
||||||
|
<p className="italic text-gray-600">Élève</p>
|
||||||
<p>Nom : {formData.eleveNom}</p>
|
<p>Nom : {formData.eleveNom}</p>
|
||||||
<p>Prénom : {formData.elevePrenom}</p>
|
<p>Prénom : {formData.elevePrenom}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
</div>
|
||||||
<h3 className="text-xl font-semibold">Responsable(s)</h3>
|
</div>
|
||||||
|
<div className="flex items-center justify-between space-x-4">
|
||||||
|
<div className="bg-gray-100 p-3 rounded-lg shadow-md flex items-center w-1/2">
|
||||||
|
<UserCheck className="w-10 h-10 text-gray-300 mr-4" />
|
||||||
{formData.responsableType === 'new' && (
|
{formData.responsableType === 'new' && (
|
||||||
<p>Email du nouveau responsable : {formData.responsableEmail}</p>
|
<div>
|
||||||
|
<p className="italic text-gray-600">Responsable</p>
|
||||||
|
<p>Email : {formData.responsableEmail}</p>
|
||||||
|
<p>Téléphone : {formData.responsableTel}</p>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
{formData.responsableType === 'existing' && selectedEleve && (
|
{formData.responsableType === 'existing' && selectedEleve && (
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-bold">Responsables associés à {selectedEleve.nom} {selectedEleve.prenom} :</h4>
|
<p className="italic text-gray-600">Responsable(s)</p>
|
||||||
|
<p>Associé(s) à : {selectedEleve.nom} {selectedEleve.prenom}</p>
|
||||||
<ul className="list-disc ml-6">
|
<ul className="list-disc ml-6">
|
||||||
{existingResponsables.filter(responsable => formData.selectedResponsables.includes(responsable.id)).map((responsable) => (
|
{existingResponsables.filter(responsable => formData.selectedResponsables.includes(responsable.id)).map((responsable) => (
|
||||||
<li key={responsable.id}>
|
<li key={responsable.id}>
|
||||||
@ -197,6 +232,24 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center mt-4">
|
||||||
|
<label className="mr-2 text-gray-600">Envoi automatique</label>
|
||||||
|
<div className="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="toggle"
|
||||||
|
id="toggle"
|
||||||
|
checked={autoMail}
|
||||||
|
onChange={handleToggleChange}
|
||||||
|
className="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer border-emerald-500 checked:right-0 checked:border-emerald-500 checked:bg-emerald-500 focus:border-emerald-500 focus:bg-emerald-500 hover:border-emerald-500 hover:bg-emerald-500"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="toggle"
|
||||||
|
className={`toggle-label block overflow-hidden h-6 rounded-full cursor-pointer transition-colors duration-200 ${autoMail ? 'bg-emerald-300' : 'bg-gray-300'}`}
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-end mt-4 space-x-4">
|
<div className="flex justify-end mt-4 space-x-4">
|
||||||
@ -208,7 +261,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => {
|
|||||||
Précédent
|
Précédent
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{step < 3 ? (
|
{step < maxStep ? (
|
||||||
<button
|
<button
|
||||||
onClick={nextStep}
|
onClick={nextStep}
|
||||||
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
|
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import * as Dialog from '@radix-ui/react-dialog';
|
import * as Dialog from '@radix-ui/react-dialog';
|
||||||
|
|
||||||
const Modal = ({ isOpen, setIsOpen, title, ContentComponent }) => {
|
const Modal = ({ isOpen, setIsOpen, title, ContentComponent, size }) => {
|
||||||
return (
|
return (
|
||||||
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
||||||
<Dialog.Content className="fixed inset-0 flex items-center justify-center">
|
<Dialog.Content className="fixed inset-0 flex items-center justify-center">
|
||||||
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:w-full sm:p-6">
|
<div className={`inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:p-6 ${size ? size : 'sm:w-full' }`}>
|
||||||
<Dialog.Title className="text-lg font-medium text-gray-900">
|
<Dialog.Title className="text-lg font-medium text-gray-900">
|
||||||
{title}
|
{title}
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
|
|||||||
Reference in New Issue
Block a user