From d51778ba54e95283aa6ad7821fda673813c7c7a0 Mon Sep 17 00:00:00 2001 From: N3WT DE COMPET Date: Sun, 24 Nov 2024 18:42:42 +0100 Subject: [PATCH] =?UTF-8?q?refactor:=20Cr=C3=A9ation=20de=20composants=20e?= =?UTF-8?q?t=20uniformisation=20des=20modales=20(#2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Back-End/GestionEnseignants/apps.py | 5 + Back-End/GestionLogin/models.py | 4 +- .../app/[locale]/admin/subscriptions/page.js | 2 +- .../src/app/[locale]/users/login/page.js | 7 +- Front-End/src/components/Button.js | 6 +- Front-End/src/components/ClassForm.js | 138 ++++++++-------- Front-End/src/components/ClassesSection.js | 8 +- Front-End/src/components/InputColorIcon.js | 28 ++++ .../components/Inscription/InscriptionForm.js | 90 +++++------ Front-End/src/components/Modal.js | 13 +- Front-End/src/components/RadioList.js | 39 +++++ Front-End/src/components/SelectChoice.js | 27 ++-- Front-End/src/components/Slider.js | 46 +++--- .../src/components/SpecialitiesSection.js | 8 +- Front-End/src/components/SpecialityForm.js | 52 +++--- Front-End/src/components/TeacherForm.js | 151 +++++++----------- Front-End/src/components/TeachersSection.js | 12 +- Front-End/src/components/ToggleSwitch.js | 25 +++ 18 files changed, 362 insertions(+), 299 deletions(-) create mode 100644 Front-End/src/components/InputColorIcon.js create mode 100644 Front-End/src/components/RadioList.js create mode 100644 Front-End/src/components/ToggleSwitch.js diff --git a/Back-End/GestionEnseignants/apps.py b/Back-End/GestionEnseignants/apps.py index 16c4573..bdf3e6d 100644 --- a/Back-End/GestionEnseignants/apps.py +++ b/Back-End/GestionEnseignants/apps.py @@ -4,3 +4,8 @@ from django.apps import AppConfig class GestionenseignantsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'GestionEnseignants' + + def ready(self): + from .models import Specialite + if not Specialite.objects.filter(nom='TRANSVERSE').exists(): + Specialite.objects.create(nom='TRANSVERSE', codeCouleur='#FF0000') diff --git a/Back-End/GestionLogin/models.py b/Back-End/GestionLogin/models.py index cff77da..f6af900 100644 --- a/Back-End/GestionLogin/models.py +++ b/Back-End/GestionLogin/models.py @@ -7,8 +7,8 @@ class Profil(AbstractUser): class Droits(models.IntegerChoices): PROFIL_UNDEFINED = -1, _('NON DEFINI') PROFIL_ECOLE = 0, _('ECOLE') - PROFIL_PARENT = 1, _('PARENT') - PROFIL_ADMIN = 2, _('ADMIN') + PROFIL_ADMIN = 1, _('ADMIN') + PROFIL_PARENT = 2, _('PARENT') email = models.EmailField(max_length=255, unique=True, default="", validators=[EmailValidator()]) diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js index 621bafc..95753bf 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js @@ -335,7 +335,7 @@ export default function Page({ params: { locale } }) { password: 'Provisoire01!', username: updatedData.responsableEmail, is_active: 0, // On rend le profil inactif : impossible de s'y connecter dans la fenêtre du login tant qu'il ne s'est pas inscrit - droit:1 + droit:2 // Profil PARENT }), } ); diff --git a/Front-End/src/app/[locale]/users/login/page.js b/Front-End/src/app/[locale]/users/login/page.js index 0352e9b..62824c8 100644 --- a/Front-End/src/app/[locale]/users/login/page.js +++ b/Front-End/src/app/[locale]/users/login/page.js @@ -80,13 +80,12 @@ export default function Page() { localStorage.setItem('userId', data.profil); // Stocker l'identifiant de l'utilisateur if (data.droit == 0) { // Vue ECOLE - } else if (data.droit == 1) { - // Vue PARENT - router.push(`${FR_PARENTS_HOME_URL}`); - } else if (data.droit == 2) { // Vue ADMIN router.push(`${FR_ADMIN_SUBSCRIPTIONS_URL}`); + } else if (data.droit == 2) { + // Vue PARENT + router.push(`${FR_PARENTS_HOME_URL}`); } else { // Cas anormal } diff --git a/Front-End/src/components/Button.js b/Front-End/src/components/Button.js index ab196eb..7a634fa 100644 --- a/Front-End/src/components/Button.js +++ b/Front-End/src/components/Button.js @@ -1,12 +1,12 @@ import React from 'react'; import { useRouter } from 'next/navigation'; -const Button = ({ text, onClick, href, className, primary, icon }) => { +const Button = ({ text, onClick, href, className, primary, icon, disabled}) => { const router = useRouter(); const baseClass = 'px-4 py-2 rounded-md text-white h-8 flex items-center justify-center'; const primaryClass = 'bg-emerald-500 hover:bg-emerald-600'; const secondaryClass = 'bg-gray-300 hover:bg-gray-400 text-black'; - const buttonClass = `${baseClass} ${primary ? primaryClass : secondaryClass} ${className}`; + const buttonClass = `${baseClass} ${primary && !disabled ? primaryClass : secondaryClass} ${className}`; const handleClick = (e) => { if (href) { @@ -17,7 +17,7 @@ const Button = ({ text, onClick, href, className, primary, icon }) => { }; return ( - diff --git a/Front-End/src/components/ClassForm.js b/Front-End/src/components/ClassForm.js index 2e7e702..45df9b7 100644 --- a/Front-End/src/components/ClassForm.js +++ b/Front-End/src/components/ClassForm.js @@ -1,13 +1,24 @@ import React, { useState } from 'react'; import Slider from '@/components/Slider' +import InputTextIcon from '@/components/InputTextIcon'; +import Button from '@/components/Button'; +import SelectChoice from '@/components/SelectChoice'; +import RadioList from '@/components/RadioList'; +import { Users, Maximize2, Globe, Calendar, GraduationCap } from 'lucide-react'; const ClassForm = ({ classe, onSubmit, isNew, specialities, teachers }) => { + const langues = [ + { value:'Français', label: 'Français'}, + { value:'Anglais', label: 'Anglais'}, + { value:'Espagnol', label: 'Espagnol'}, + ]; + const [formData, setFormData] = useState({ nom_ambiance: classe.nom_ambiance || '', tranche_age: classe.tranche_age || [3, 6], nombre_eleves: classe.nombre_eleves || '', langue_enseignement: classe.langue_enseignement || 'Français', - annee_scolaire: classe.annee_scolaire || '2024-2025', + annee_scolaire: classe.annee_scolaire || '', specialites_ids: classe.specialites_ids || [], enseignant_principal_id: classe.enseignant_principal_id || null, }); @@ -49,19 +60,21 @@ const ClassForm = ({ classe, onSubmit, isNew, specialities, teachers }) => { }); }; + const getTeacherLabel = (teacher) => { + return `${teacher.nom} ${teacher.prenom} (${teacher.specialite.nom})`; + }; + return ( -
+
- -
@@ -69,51 +82,43 @@ const ClassForm = ({ classe, onSubmit, isNew, specialities, teachers }) => { Tranche d'âge
- -
- - +
- -
@@ -144,41 +149,30 @@ const ClassForm = ({ classe, onSubmit, isNew, specialities, teachers }) => { ))}
-
- -
- {teachers.map(teacher => ( -
- - -
- ))} -
+
+
- +
); diff --git a/Front-End/src/components/ClassesSection.js b/Front-End/src/components/ClassesSection.js index d3e737b..366e08c 100644 --- a/Front-End/src/components/ClassesSection.js +++ b/Front-End/src/components/ClassesSection.js @@ -107,9 +107,11 @@ const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleE ( - - )} + title={editingClass ? "Modification de la classe" : "Création d'une nouvelle classe"} + size='sm:w-1/4' + ContentComponent={() => ( + + )} /> )} {isOpenDetails && ( diff --git a/Front-End/src/components/InputColorIcon.js b/Front-End/src/components/InputColorIcon.js new file mode 100644 index 0000000..363d0c5 --- /dev/null +++ b/Front-End/src/components/InputColorIcon.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { Palette } from 'lucide-react'; + +const InputColorIcon = ({ name, label, value, onChange, errorMsg, className }) => { + return ( + <> +
+ +
+ + + + +
+ {errorMsg &&

{errorMsg}

} +
+ + ); +}; + +export default InputColorIcon; diff --git a/Front-End/src/components/Inscription/InscriptionForm.js b/Front-End/src/components/Inscription/InscriptionForm.js index f9cbac8..ed7d8cc 100644 --- a/Front-End/src/components/Inscription/InscriptionForm.js +++ b/Front-End/src/components/Inscription/InscriptionForm.js @@ -1,6 +1,8 @@ import { useState } from 'react'; import { User, Mail, Phone, UserCheck } from 'lucide-react'; import InputTextIcon from '@/components/InputTextIcon'; +import ToggleSwitch from '@/components/ToggleSwitch'; +import Button from '@/components/Button'; const InscriptionForm = ( { eleves, onSubmit }) => { const [formData, setFormData] = useState({ @@ -9,18 +11,17 @@ const InscriptionForm = ( { eleves, onSubmit }) => { responsableEmail: '', responsableTel: '', selectedResponsables: [], - responsableType: 'new' + responsableType: 'new', + autoMail: false }); const [step, setStep] = useState(1); const [selectedEleve, setSelectedEleve] = useState(''); const [existingResponsables, setExistingResponsables] = useState([]); - const [autoMail, setAutoMail] = useState(false); const maxStep = 4 - const handleToggleChange = () => { - setAutoMail(!autoMail); - setFormData({ ...formData, autoMail: !autoMail }); + const handleToggleChange = () => { + setFormData({ ...formData, autoMail: !formData.autoMail }); }; const handleChange = (e) => { @@ -62,7 +63,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => { }; const submit = () => { - onSubmit({ ...formData, autoMail }); + onSubmit(formData); } return ( @@ -167,7 +168,7 @@ const InscriptionForm = ( { eleves, onSubmit }) => { onChange={() => handleResponsableSelection(responsable.id)} /> - {responsable.nom && responsable.prenom ? `${responsable.nom} ${responsable.prenom}` : `adresse mail : ${responsable.mail}`} + {responsable.nom && responsable.prenom ? `${responsable.nom} ${responsable.prenom}` : `${responsable.mail}`}
@@ -232,59 +233,46 @@ const InscriptionForm = ( { eleves, onSubmit }) => { )} -
- -
- - -
+
+
)}
{step > 1 && ( - + + +
diff --git a/Front-End/src/components/Modal.js b/Front-End/src/components/Modal.js index 18c36d0..b6a4cd3 100644 --- a/Front-End/src/components/Modal.js +++ b/Front-End/src/components/Modal.js @@ -1,4 +1,5 @@ import * as Dialog from '@radix-ui/react-dialog'; +import Button from '@/components/Button'; const Modal = ({ isOpen, setIsOpen, title, ContentComponent, size }) => { return ( @@ -13,14 +14,14 @@ const Modal = ({ isOpen, setIsOpen, title, ContentComponent, size }) => {
-
+
- + className="px-4 py-2 rounded-md shadow-sm focus:outline-none bg-gray-300 text-gray-700 hover:bg-gray-400" + secondary + type="submit" + name="Create" />
diff --git a/Front-End/src/components/RadioList.js b/Front-End/src/components/RadioList.js new file mode 100644 index 0000000..4b6a861 --- /dev/null +++ b/Front-End/src/components/RadioList.js @@ -0,0 +1,39 @@ +import React from 'react'; + +const RadioList = ({ items, formData, handleChange, fieldName, label, icon: Icon, className, itemLabelFunc}) => { + return ( +
+ +
+ {items.map(item => ( +
+ + +
+ ))} +
+
+ ); +}; + +export default RadioList; diff --git a/Front-End/src/components/SelectChoice.js b/Front-End/src/components/SelectChoice.js index 7fd8783..ea839a0 100644 --- a/Front-End/src/components/SelectChoice.js +++ b/Front-End/src/components/SelectChoice.js @@ -1,18 +1,23 @@ -export default function SelectChoice({type, name, label, choices, callback, selected, error }) { +export default function SelectChoice({type, name, label, choices, callback, selected, error, IconItem }) { return ( <>
- +
+ + {IconItem && } + + +
{error &&

{error}

}
diff --git a/Front-End/src/components/Slider.js b/Front-End/src/components/Slider.js index d0fa221..d20584a 100644 --- a/Front-End/src/components/Slider.js +++ b/Front-End/src/components/Slider.js @@ -23,28 +23,30 @@ const Slider = ({ min, max, value, onChange }) => { return (
-
- {value[0]} - -
-
- {value[1]} - -
+
+
+ {value[0]} + +
+
+ {value[1]} + +
+
); }; diff --git a/Front-End/src/components/SpecialitiesSection.js b/Front-End/src/components/SpecialitiesSection.js index e451175..fc96c08 100644 --- a/Front-End/src/components/SpecialitiesSection.js +++ b/Front-End/src/components/SpecialitiesSection.js @@ -75,9 +75,11 @@ const SpecialitiesSection = ({ specialities, handleCreate, handleEdit, handleDel ( - - )} + title={editingSpeciality ? "Modification de la spécialité" : "Création d'une nouvelle spécialité"} + size='sm:w-1/6' + ContentComponent={() => ( + + )} /> )} diff --git a/Front-End/src/components/SpecialityForm.js b/Front-End/src/components/SpecialityForm.js index 9849fa5..24c4941 100644 --- a/Front-End/src/components/SpecialityForm.js +++ b/Front-End/src/components/SpecialityForm.js @@ -1,4 +1,8 @@ import { useState } from 'react'; +import { BookOpen, Palette } from 'lucide-react'; +import InputTextIcon from '@/components/InputTextIcon'; +import InputColorIcon from '@/components/InputColorIcon'; +import Button from '@/components/Button'; const SpecialityForm = ({ speciality = {}, onSubmit, isNew }) => { const [nom, setNom] = useState(speciality.nom || ''); @@ -13,35 +17,39 @@ const SpecialityForm = ({ speciality = {}, onSubmit, isNew }) => { }; return ( -
+
- setNom(e.target.value)} - 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" + setNom(e.target.value)} + className="w-full mt-4" />
- - setCodeCouleur(e.target.value)} - 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 h-10 w-10 p-0 cursor-pointer" - style={{ appearance: 'none', borderRadius: '0' }} + setCodeCouleur(e.target.value)} + className="w-full mt-4" />
- +
); diff --git a/Front-End/src/components/TeacherForm.js b/Front-End/src/components/TeacherForm.js index fa778aa..ed48f51 100644 --- a/Front-End/src/components/TeacherForm.js +++ b/Front-End/src/components/TeacherForm.js @@ -1,10 +1,11 @@ import React, { useState } from 'react'; +import { GraduationCap, Mail, BookOpen } from 'lucide-react'; +import InputTextIcon from '@/components/InputTextIcon'; +import Button from '@/components/Button'; +import RadioList from '@/components/RadioList'; +import ToggleSwitch from '@/components/ToggleSwitch' const TeacherForm = ({ teacher, onSubmit, isNew, specialities }) => { - const profils = [ - { value: 0, label: "École" }, - { value: 2, label: "Administrateur" }, - ]; const [formData, setFormData] = useState({ nom: teacher.nom || '', @@ -13,13 +14,17 @@ const TeacherForm = ({ teacher, onSubmit, isNew, specialities }) => { specialite_id: teacher.specialite_id || '', classes: teacher.classes || [], profilAssocie_id: teacher.profilAssocie_id || [], - DroitValue: teacher.DroitValue || 0 + droit: teacher.DroitValue || 0 }); + const handleToggleChange = () => { + console.log('new value : ', 1-formData.droit) + setFormData({ ...formData, droit: 1-formData.droit }); + }; + const handleChange = (e) => { const { name, value, type } = e.target; const newValue = type === 'radio' ? parseInt(value, 10) : value; - console.log(`Name: ${name}, Value: ${newValue}`); setFormData((prevState) => ({ ...prevState, [name]: newValue, @@ -31,112 +36,70 @@ const TeacherForm = ({ teacher, onSubmit, isNew, specialities }) => { }; return ( -
+
- -
- -
- -
-
- -
- {specialities.map(speciality => ( -
- - -
- ))} -
+
+
-
- -
- {profils.map((profil) => ( -
- - -
- ))} -
+
+
- +
); diff --git a/Front-End/src/components/TeachersSection.js b/Front-End/src/components/TeachersSection.js index ae454ce..2204b6d 100644 --- a/Front-End/src/components/TeachersSection.js +++ b/Front-End/src/components/TeachersSection.js @@ -39,7 +39,7 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe body: JSON.stringify( { email: updatedData.mail, username: updatedData.mail, - droit:updatedData.DroitValue + droit:updatedData.droit }), } ); @@ -71,7 +71,7 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe password: 'Provisoire01!', username: updatedData.mail, is_active: 1, // On rend le profil actif : on considère qu'au moment de la configuration de l'école un abonnement a été souscrit - droit:updatedData.DroitValue + droit:updatedData.droit }), } ); @@ -159,9 +159,11 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe ( - - )} + title={editingTeacher ? "Modification de l'enseignant" : "Création d'un nouvel enseignant"} + size='sm:w-1/4' + ContentComponent={() => ( + + )} /> )}
diff --git a/Front-End/src/components/ToggleSwitch.js b/Front-End/src/components/ToggleSwitch.js new file mode 100644 index 0000000..284a559 --- /dev/null +++ b/Front-End/src/components/ToggleSwitch.js @@ -0,0 +1,25 @@ +import React from 'react'; + +const ToggleSwitch = ({ label, checked, onChange }) => { + return ( +
+ +
+ + +
+
+ ); +}; + +export default ToggleSwitch;