From 753a8d647ec3e45c8aabecba6d38b1a19741e0c0 Mon Sep 17 00:00:00 2001 From: N3WT DE COMPET Date: Tue, 11 Mar 2025 21:58:09 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Refactoring=20de=20la=20fonction=20de?= =?UTF-8?q?=20cr=C3=A9ation=20de=20profil=20sur=20guardian=20c=C3=B4t?= =?UTF-8?q?=C3=A9=20FRONT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Back-End/Auth/serializers.py | 55 +++-- .../management/commands/init_mock_datas.py | 145 ++++++------ Back-End/School/serializers.py | 28 ++- Back-End/Subscriptions/serializers.py | 81 ++++--- .../views/registration_file_group_views.py | 6 + Front-End/src/app/[locale]/admin/layout.js | 41 +--- .../src/app/[locale]/admin/structure/page.js | 2 +- .../app/[locale]/admin/subscriptions/page.js | 217 ++++++------------ Front-End/src/app/[locale]/parents/layout.js | 16 +- Front-End/src/app/actions/authAction.js | 28 --- .../app/actions/registerFileGroupAction.js | 4 +- Front-End/src/components/FileUpload copy.js | 5 +- Front-End/src/components/Sidebar.js | 2 +- .../components/Structure/Files/FileUpload.js | 5 +- .../Structure/Files/FilesGroupsManagement.js | 36 +-- .../Structure/Files/FilesManagement.js | 6 +- .../Files/RegistrationFileGroupList.js | 5 +- Front-End/src/context/EstablishmentContext.js | 30 ++- 18 files changed, 326 insertions(+), 386 deletions(-) diff --git a/Back-End/Auth/serializers.py b/Back-End/Auth/serializers.py index c35569a..2647a14 100644 --- a/Back-End/Auth/serializers.py +++ b/Back-End/Auth/serializers.py @@ -1,24 +1,17 @@ from rest_framework import serializers from Auth.models import Profile, ProfileRole -from django.core.exceptions import ValidationError - -class ProfileRoleSerializer(serializers.ModelSerializer): - class Meta: - model = ProfileRole - fields = ['role_type', 'establishment', 'is_active', 'profile'] +from Establishment.models import Establishment class ProfileSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) password = serializers.CharField(write_only=True) - roles = ProfileRoleSerializer(many=True, required=False) class Meta: model = Profile - fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username', 'roles'] + fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username'] extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data): - roles_data = validated_data.pop('roles', []) user = Profile( username=validated_data['username'], email=validated_data['email'], @@ -28,14 +21,9 @@ class ProfileSerializer(serializers.ModelSerializer): user.set_password(validated_data['password']) user.full_clean() user.save() - - for role_data in roles_data: - ProfileRole.objects.create(profile=user, **role_data) - return user def update(self, instance, validated_data): - roles_data = validated_data.pop('roles', []) password = validated_data.pop('password', None) instance = super().update(instance, validated_data) @@ -44,17 +32,6 @@ class ProfileSerializer(serializers.ModelSerializer): instance.full_clean() instance.save() - - for role_data in roles_data: - ProfileRole.objects.update_or_create( - profile=instance, - establishment_id=role_data.get('establishment_id'), - defaults={ - 'role_type': role_data.get('role_type'), - 'is_active': role_data.get('is_active', True) - } - ) - return instance def to_representation(self, instance): @@ -62,6 +39,34 @@ class ProfileSerializer(serializers.ModelSerializer): ret['password'] = '********' return ret +class ProfileRoleSerializer(serializers.ModelSerializer): + profile = ProfileSerializer() + establishment = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all()) + + class Meta: + model = ProfileRole + fields = ['role_type', 'establishment', 'is_active', 'profile'] + + def create(self, validated_data): + profile_data = validated_data.pop('profile') + profile_serializer = ProfileSerializer(data=profile_data) + profile_serializer.is_valid(raise_exception=True) + profile = profile_serializer.save() + profile_role = ProfileRole.objects.create(profile=profile, **validated_data) + return profile_role + + def update(self, instance, validated_data): + profile_data = validated_data.pop('profile') + profile_serializer = ProfileSerializer(instance.profile, data=profile_data) + profile_serializer.is_valid(raise_exception=True) + profile = profile_serializer.save() + + instance.role_type = validated_data.get('role_type', instance.role_type) + instance.establishment_id = validated_data.get('establishment', instance.establishment.id) + instance.is_active = validated_data.get('is_active', instance.is_active) + instance.save() + return instance + class ProfilUpdateSerializer(serializers.ModelSerializer): roles = ProfileRoleSerializer(many=True, required=False) diff --git a/Back-End/School/management/commands/init_mock_datas.py b/Back-End/School/management/commands/init_mock_datas.py index 902a55f..1e3cd05 100644 --- a/Back-End/School/management/commands/init_mock_datas.py +++ b/Back-End/School/management/commands/init_mock_datas.py @@ -42,7 +42,7 @@ from School.serializers import ( ) from Auth.serializers import ProfileSerializer, ProfileRoleSerializer from Establishment.serializers import EstablishmentSerializer -from Subscriptions.serializers import RegistrationFormSerializer, GuardianSerializer +from Subscriptions.serializers import RegistrationFormSerializer, StudentSerializer # Définir le chemin vers le dossier mock_datas MOCK_DATAS_PATH = os.path.join(settings.BASE_DIR, 'School', 'management', 'mock_datas') @@ -52,14 +52,13 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): self.init_establishments() - self.init_profiles() + #self.init_profiles() self.init_fees() self.init_discounts() self.init_payment_modes() self.init_payment_plans() self.init_specialities() self.init_teachers() - self.init_guardians() self.init_school_classes() self.init_file_group() self.init_register_form() @@ -121,7 +120,7 @@ class Command(BaseCommand): # Create or update the profile role for each selected role using ProfileRoleSerializer for role in selected_roles: role_data = { - "profile": profile.id, + "profile": profile.id, # Passer l'ID du profil au lieu de l'instance de modèle Profile "establishment": role["establishment"], "role_type": role["role_type"], "is_active": True @@ -240,70 +239,51 @@ class Command(BaseCommand): def init_teachers(self): fake = Faker() - # Récupérer tous les profils dont le role_type est soit ECOLE soit ADMIN - profiles = Profile.objects.filter(roles__role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN]).distinct() + # Récupérer tous les établissements + establishments = self.establishments - for profile in profiles: - # Récupérer les rôles associés au profil - profile_roles = ProfileRole.objects.filter(profile=profile, role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN]) + for establishment in establishments: + # Générer des données fictives pour le profil + profile_data = { + "username": fake.user_name(), + "email": fake.email(), + "password": "Provisoire01!", + "code": "", + "datePeremption": "" + } - for profile_role in profile_roles: - establishment = profile_role.establishment - teacher_data = { - "last_name": fake.last_name(), - "first_name": f"{fake.first_name()} - {establishment.name}", - "profile_role": profile_role.id - } + # Générer des données fictives pour le profile_role + profile_role_data = { + "establishment": establishment.id, + "role_type": fake.random_int(min=ProfileRole.RoleType.PROFIL_ECOLE, max=ProfileRole.RoleType.PROFIL_ADMIN), + "is_active": True, + "profile": profile_data + } - establishment_specialities = list(Speciality.objects.filter(establishment=establishment)) - num_specialities = min(random.randint(1, 3), len(establishment_specialities)) - selected_specialities = random.sample(establishment_specialities, num_specialities) + # Générer des données fictives pour l'enseignant + teacher_data = { + "last_name": fake.last_name(), + "first_name": f"{fake.first_name()} - {establishment.name}", + "profile_role": profile_role_data + } - # Créer l'enseignant si il n'existe pas - teacher_serializer = TeacherSerializer(data=teacher_data) - if teacher_serializer.is_valid(): - teacher = teacher_serializer.save() - # Associer les spécialités - teacher.specialities.set(selected_specialities) - teacher.save() - self.stdout.write(self.style.SUCCESS(f'Teacher {teacher.last_name} created successfully for establishment {establishment.name}')) - else: - self.stdout.write(self.style.ERROR(f'Error in data for teacher: {teacher_serializer.errors}')) + establishment_specialities = list(Speciality.objects.filter(establishment=establishment)) + num_specialities = min(random.randint(1, 3), len(establishment_specialities)) + selected_specialities = random.sample(establishment_specialities, num_specialities) + + # Créer l'enseignant si il n'existe pas + teacher_serializer = TeacherSerializer(data=teacher_data) + if teacher_serializer.is_valid(): + teacher = teacher_serializer.save() + # Associer les spécialités + teacher.specialities.set(selected_specialities) + teacher.save() + self.stdout.write(self.style.SUCCESS(f'Teacher {teacher.last_name} created successfully for establishment {establishment.name}')) + else: + self.stdout.write(self.style.ERROR(f'Error in data for teacher: {teacher_serializer.errors}')) self.stdout.write(self.style.SUCCESS('Teachers initialized or updated successfully')) - def init_guardians(self): - fake = Faker() - - # Récupérer tous les profils dont le role_type est PROFIL_PARENT - profiles = Profile.objects.filter(roles__role_type=ProfileRole.RoleType.PROFIL_PARENT).distinct() - - for profile in profiles: - # Récupérer les rôles associés au profil - profile_roles = ProfileRole.objects.filter(profile=profile, role_type=ProfileRole.RoleType.PROFIL_PARENT) - - for profile_role in profile_roles: - establishment = profile_role.establishment - guardian_data = { - "last_name": fake.last_name(), - "first_name": f"{fake.first_name()} - {establishment.name}", - "profile_role": profile_role.id, - "birth_date": fake.date_of_birth().strftime('%Y-%m-%d'), # Convertir en chaîne de caractères valide - "address": fake.address(), - "phone": fake.phone_number(), - "profession": fake.job() - } - - # Créer le guardian si il n'existe pas - guardian_serializer = GuardianSerializer(data=guardian_data) - if guardian_serializer.is_valid(): - guardian = guardian_serializer.save() - self.stdout.write(self.style.SUCCESS(f'Guardian {guardian.last_name} created successfully for establishment {establishment.name}')) - else: - self.stdout.write(self.style.ERROR(f'Error in data for guardian: {guardian_serializer.errors}')) - - self.stdout.write(self.style.SUCCESS('Guardians initialized or updated successfully')) - def init_school_classes(self): school_classes_data = self.load_data('school_classes.json') @@ -358,8 +338,30 @@ class Command(BaseCommand): for _ in range(50): establishment = random.choice(self.establishments) - # Récupérer un guardian aléatoire déjà créé - guardian = Guardian.objects.order_by('?').first() + # Générer des données fictives pour le profil + profile_data = { + "username": fake.user_name(), + "email": fake.email(), + "password": "Provisoire01!", + "code": "", + "datePeremption": "" + } + + # Générer des données fictives pour le guardian + guardian_data = { + "profile_role": { + "establishment": establishment.id, + "role_type": ProfileRole.RoleType.PROFIL_PARENT, + "is_active": True, + "profile": profile_data + }, + "last_name": fake.last_name(), + "first_name": fake.first_name(), + "birth_date": fake.date_of_birth().strftime('%Y-%m-%d'), + "address": fake.address(), + "phone": fake.phone_number(), + "profession": fake.job() + } # Générer des données fictives pour l'étudiant student_data = { @@ -371,16 +373,19 @@ class Command(BaseCommand): "birth_postal_code": fake.postcode(), "nationality": fake.country(), "attending_physician": fake.name(), - "level": fake.random_int(min=1, max=6) + "level": fake.random_int(min=1, max=6), + "guardians": [guardian_data], + "sibling": [] } # Créer ou mettre à jour l'étudiant - student, created = Student.objects.get_or_create( - last_name=student_data["last_name"], - first_name=student_data["first_name"], - defaults=student_data - ) - student.guardians.add(guardian) + student_serializer = StudentSerializer(data=student_data) + if student_serializer.is_valid(): + student = student_serializer.save() + self.stdout.write(self.style.SUCCESS(f'Student {student.last_name} created successfully')) + else: + self.stdout.write(self.style.ERROR(f'Error in data for student: {student_serializer.errors}')) + continue # Récupérer les frais et les réductions fees = Fee.objects.filter(id__in=[1, 2, 3, 4]) diff --git a/Back-End/School/serializers.py b/Back-End/School/serializers.py index 5e17371..f8791b6 100644 --- a/Back-End/School/serializers.py +++ b/Back-End/School/serializers.py @@ -3,6 +3,7 @@ from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, D from Auth.models import Profile, ProfileRole from Subscriptions.models import Student from Establishment.models import Establishment +from Auth.serializers import ProfileRoleSerializer from N3wtSchool import settings, bdd from django.utils import timezone import pytz @@ -31,10 +32,10 @@ class TeacherDetailSerializer(serializers.ModelSerializer): class TeacherSerializer(serializers.ModelSerializer): specialities = serializers.PrimaryKeyRelatedField(queryset=Speciality.objects.all(), many=True, required=False) specialities_details = serializers.SerializerMethodField() - profile_role = serializers.PrimaryKeyRelatedField(queryset=ProfileRole.objects.all(), required=True) updated_date_formatted = serializers.SerializerMethodField() role_type = serializers.SerializerMethodField() associated_profile_email = serializers.SerializerMethodField() + profile_role = ProfileRoleSerializer() class Meta: model = Teacher @@ -42,21 +43,36 @@ class TeacherSerializer(serializers.ModelSerializer): def create(self, validated_data): specialities_data = validated_data.pop('specialities', None) - profile_role = validated_data.pop('profile_role', None) - teacher = Teacher.objects.create(**validated_data) + profile_role_data = validated_data.pop('profile_role') + establishment_id = profile_role_data.pop('establishment').id + profile_role_data['establishment'] = establishment_id + + # Créer l'instance de ProfileRole + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + profile_role_serializer.is_valid(raise_exception=True) + profile_role = profile_role_serializer.save() + + # Créer l'enseignant avec l'instance de ProfileRole + teacher = Teacher.objects.create(profile_role=profile_role, **validated_data) if specialities_data: teacher.specialities.set(specialities_data) - if profile_role: - teacher.profile_role = profile_role teacher.save() return teacher def update(self, instance, validated_data): specialities_data = validated_data.pop('specialities', []) + profile_role_data = validated_data.pop('profile_role', None) + + if profile_role_data: + establishment_id = profile_role_data.pop('establishment').id + profile_role_data['establishment'] = establishment_id + profile_role_serializer = ProfileRoleSerializer(instance.profile_role, data=profile_role_data) + profile_role_serializer.is_valid(raise_exception=True) + profile_role_serializer.save() + instance.last_name = validated_data.get('last_name', instance.last_name) instance.first_name = validated_data.get('first_name', instance.first_name) instance.email = validated_data.get('email', instance.email) - instance.profile_role = validated_data.get('profile_role', instance.profile_role) instance.save() if specialities_data: instance.specialities.set(specialities_data) diff --git a/Back-End/Subscriptions/serializers.py b/Back-End/Subscriptions/serializers.py index bcd60a7..a72c214 100644 --- a/Back-End/Subscriptions/serializers.py +++ b/Back-End/Subscriptions/serializers.py @@ -2,8 +2,8 @@ from rest_framework import serializers from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationTemplateMaster, RegistrationTemplate from School.models import SchoolClass, Fee, Discount, FeeType from School.serializers import FeeSerializer, DiscountSerializer -from Auth.models import ProfileRole -from Auth.serializers import ProfileSerializer +from Auth.models import ProfileRole, Profile +from Auth.serializers import ProfileSerializer, ProfileRoleSerializer from GestionMessagerie.models import Messagerie from GestionNotification.models import Notification from N3wtSchool import settings @@ -24,9 +24,14 @@ class RegistrationTemplateSerializer(serializers.ModelSerializer): fields = '__all__' class GuardianSimpleSerializer(serializers.ModelSerializer): + associated_profile_email = serializers.SerializerMethodField() + class Meta: model = Guardian - fields = ['id', 'email'] + fields = ['id', 'associated_profile_email'] + + def get_associated_profile_email(self, obj): + return obj.profile_role.profile.email class RegistrationFormSimpleSerializer(serializers.ModelSerializer): guardians = GuardianSimpleSerializer(many=True, source='student.guardians') @@ -68,7 +73,7 @@ class SiblingSerializer(serializers.ModelSerializer): class GuardianSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) - profile_role = serializers.PrimaryKeyRelatedField(queryset=ProfileRole.objects.all(), required=True) + profile_role = ProfileRoleSerializer() associated_profile_email = serializers.SerializerMethodField() class Meta: @@ -78,13 +83,11 @@ class GuardianSerializer(serializers.ModelSerializer): def get_associated_profile_email(self, obj): return obj.profile_role.profile.email - class StudentSerializer(serializers.ModelSerializer): - id = serializers.IntegerField(required=False) guardians = GuardianSerializer(many=True, required=False) siblings = SiblingSerializer(many=True, required=False) - languages = LanguageSerializer(many=True, required=False) + spoken_languages = LanguageSerializer(many=True, required=False) associated_class_id = serializers.PrimaryKeyRelatedField(queryset=SchoolClass.objects.all(), source='associated_class', required=False, write_only=False, read_only=False) age = serializers.SerializerMethodField() formatted_birth_date = serializers.SerializerMethodField() @@ -95,30 +98,19 @@ class StudentSerializer(serializers.ModelSerializer): model = Student fields = '__all__' - def get_or_create_packages(self, guardians_data): + def create_or_update_guardians(self, guardians_data): guardians_ids = [] for guardian_data in guardians_data: - guardian_instance, created = Guardian.objects.get_or_create( - id=guardian_data.get('id'), - defaults=guardian_data - ) - guardians_ids.append(guardian_instance.id) - return guardians_ids + profile_role_data = guardian_data.pop('profile_role') + establishment_id = profile_role_data.pop('establishment').id + profile_role_data['establishment'] = establishment_id - def create(self, validated_data): - guardians_data = validated_data.pop('guardians', []) - siblings_data = validated_data.pop('siblings', []) - languages_data = validated_data.pop('spoken_languages', []) - student = Student.objects.create(**validated_data) - student.guardians.set(self.get_or_create_packages(guardians_data)) - student.siblings.set(self.get_or_create_packages(siblings_data)) - student.spoken_languages.set(self.get_or_create_packages(languages_data)) + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + profile_role_serializer.is_valid(raise_exception=True) + profile_role = profile_role_serializer.save() - return student + guardian_data['profile_role'] = profile_role - def create_or_update_packages(self, guardians_data): - guardians_ids = [] - for guardian_data in guardians_data: guardian_instance, created = Guardian.objects.update_or_create( id=guardian_data.get('id'), defaults=guardian_data @@ -126,16 +118,47 @@ class StudentSerializer(serializers.ModelSerializer): guardians_ids.append(guardian_instance.id) return guardians_ids + def create_or_update_siblings(self, siblings_data): + siblings_ids = [] + for sibling_data in siblings_data: + sibling_instance, created = Sibling.objects.update_or_create( + id=sibling_data.get('id'), + defaults=sibling_data + ) + siblings_ids.append(sibling_instance.id) + return siblings_ids + + def create_or_update_languages(self, languages_data): + languages_ids = [] + for language_data in languages_data: + language_instance, created = Language.objects.update_or_create( + id=language_data.get('id'), + defaults=language_data + ) + languages_ids.append(language_instance.id) + return languages_ids + + def create(self, validated_data): + guardians_data = validated_data.pop('guardians', []) + siblings_data = validated_data.pop('siblings', []) + languages_data = validated_data.pop('lanspoken_languagesguages', []) + student = Student.objects.create(**validated_data) + student.guardians.set(self.create_or_update_guardians(guardians_data)) + student.siblings.set(self.create_or_update_siblings(siblings_data)) + student.spoken_languages.set(self.create_or_update_languages(languages_data)) + + return student + def update(self, instance, validated_data): guardians_data = validated_data.pop('guardians', []) siblings_data = validated_data.pop('siblings', []) languages_data = validated_data.pop('spoken_languages', []) if guardians_data: - instance.guardians.set(self.create_or_update_packages(guardians_data)) + instance.guardians.set(self.create_or_update_guardians(guardians_data)) if siblings_data: - instance.siblings.set(self.create_or_update_packages(siblings_data)) + instance.siblings.set(self.create_or_update_siblings(siblings_data)) if languages_data: - instance.spoken_languages.set(self.create_or_update_packages(languages_data)) + instance.spoken_languages.set(self.create_or_update_languages(languages_data)) for field in self.fields: try: diff --git a/Back-End/Subscriptions/views/registration_file_group_views.py b/Back-End/Subscriptions/views/registration_file_group_views.py index dc016fc..cce88e9 100644 --- a/Back-End/Subscriptions/views/registration_file_group_views.py +++ b/Back-End/Subscriptions/views/registration_file_group_views.py @@ -20,7 +20,13 @@ class RegistrationFileGroupView(APIView): """ Récupère tous les groupes de fichiers d'inscription. """ + establishment_id = request.GET.get('establishment_id', None) + if establishment_id is None: + return JsonResponse({'error': 'establishment_id est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST) + groups = RegistrationFileGroup.objects.all() + if groups: + groups = groups.filter(establishment_id=establishment_id).distinct() serializer = RegistrationFileGroupSerializer(groups, many=True) return Response(serializer.data) diff --git a/Front-End/src/app/[locale]/admin/layout.js b/Front-End/src/app/[locale]/admin/layout.js index 07b1110..35196f7 100644 --- a/Front-End/src/app/[locale]/admin/layout.js +++ b/Front-End/src/app/[locale]/admin/layout.js @@ -27,14 +27,12 @@ import { FE_ADMIN_SETTINGS_URL } from '@/utils/Url'; -import { disconnect, getUser } from '@/app/actions/authAction'; +import { disconnect } from '@/app/actions/authAction'; import { useSession } from 'next-auth/react'; -import { fetchEstablishment } from '@/app/actions/schoolAction'; import ProtectedRoute from '@/components/ProtectedRoute'; import { getGravatarUrl } from '@/utils/gravatar'; import Footer from '@/components/Footer'; import { getRightStr, RIGHTS } from '@/utils/rights'; -import { getSession } from 'next-auth/react'; import logger from '@/utils/logger'; import { useEstablishment } from '@/context/EstablishmentContext'; @@ -53,12 +51,10 @@ export default function Layout({ "settings": { "id": "settings", "name": t('settings'), "url": FE_ADMIN_SETTINGS_URL, "icon": Settings } }; - const [establishments, setEstablishments] = useState([]); const [isLoading, setIsLoading] = useState(false); const [isPopupVisible, setIsPopupVisible] = useState(false); - const [user, setUser] = useState(null); const { data: session } = useSession(); - const { selectedEstablishmentId, setSelectedEstablishmentId, profileRole, setProfileRole } = useEstablishment(); + const { selectedEstablishmentId, setSelectedEstablishmentId, profileRole, setProfileRole, establishments, user } = useEstablishment(); const pathname = usePathname(); const currentPage = pathname.split('/').pop(); @@ -108,39 +104,6 @@ export default function Layout({ setIsSidebarOpen(false); }, [pathname]); - useEffect(() => { - getSession() - .then(session => { - if (session && session.user) { - setUser(session.user); - setEstablishments(session.user.roles.map(role => ({ - id: role.establishment__id, - name: role.establishment__name, - role_type: role.role_type - }))); - // Sélectionner l'établissement depuis la session ou le premier établissement par défaut - if (!selectedEstablishmentId && session.user.roles.length > 0) { - setSelectedEstablishmentId(session.user.roles[0].establishment__id); - setProfileRole(session.user.roles[0].role_type); - } - } - }) - .catch(err => { - logger.error('Error fetching session:', err); - }); - }, []); - - useEffect(() => { - const fetchUser = async () => { - if (session) { // Vérifier que la session existe - const userData = await getUser(); - setUser(userData); - } - }; - - fetchUser(); - }, [session]); - return ( {!isLoading && ( diff --git a/Front-End/src/app/[locale]/admin/structure/page.js b/Front-End/src/app/[locale]/admin/structure/page.js index 5b2d25a..0ee44f7 100644 --- a/Front-End/src/app/[locale]/admin/structure/page.js +++ b/Front-End/src/app/[locale]/admin/structure/page.js @@ -306,7 +306,7 @@ export default function Page() { { id: 'Files', label: 'Documents d\'inscription', - content: + content: } ]; diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js index 2a1d4e1..e89e44e 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js @@ -369,164 +369,85 @@ useEffect(()=>{ const allFeesIds = [...selectedRegistrationFeesIds, ...selectedTuitionFeesIds]; const allDiscountsds = [...selectedRegistrationDiscountsIds, ...selectedTuitionDiscountsIds]; - if (updatedData.selectedGuardians.length !== 0) { - const selectedGuardiansIds = updatedData.selectedGuardians.map(guardianId => guardianId) - const guardianEmail = updatedData.guardianEmail - - const data = { - student: { - last_name: updatedData.studentLastName, - first_name: updatedData.studentFirstName, + const data = { + student: { + last_name: updatedData.studentLastName, + first_name: updatedData.studentFirstName, + guardians: updatedData.selectedGuardians.length !== 0 ? updatedData.selectedGuardians.map(guardianId => ({ id: guardianId })) : [{ + profile_role: { + establishment: selectedEstablishmentId, + role_type: 2, + is_active: false, + profile: { + email: updatedData.guardianEmail, + password: 'Provisoire01!', + username: updatedData.guardianEmail, + } }, - idGuardians: selectedGuardiansIds, - fees: allFeesIds, - discounts: allDiscountsds, - fileGroup: selectedFileGroup, - establishment: ESTABLISHMENT_ID - }; + last_name: updatedData.guardianLastName, + first_name: updatedData.guardianFirstName, + birth_date: updatedData.guardianBirthDate, + address: updatedData.guardianAddress, + phone: updatedData.guardianPhone, + profession: updatedData.guardianProfession + }], + sibling: [] + }, + fees: allFeesIds, + discounts: allDiscountsds, + fileGroup: selectedFileGroup, + establishment: selectedEstablishmentId + }; - createRegisterForm(data, csrfToken) - .then(data => { - // Cloner les templates pour chaque templateMaster du fileGroup - const masters = templateMasters.filter(file => file.groups.includes(selectedFileGroup)); - const clonePromises = masters.map((templateMaster, index) => { - return cloneTemplate(templateMaster.id, guardianEmail, templateMaster.is_required) - .then(clonedDocument => { - // Sauvegarde des templates clonés dans la base de données - const cloneData = { - name: `clone_${clonedDocument.id}`, - slug: clonedDocument.slug, - id: clonedDocument.id, - master: templateMaster.id, - registration_form: data.student.id - }; - - return createRegistrationTemplates(cloneData, csrfToken) - .then(response => { - logger.debug('Template enregistré avec succès:', response); - }) - .catch(error => { - logger.error('Erreur lors de l\'enregistrement du template:', error); - }); - }) - .catch(error => { - logger.error('Error during cloning or sending:', error); - }); - }); - - // Attendre que tous les clones soient créés - Promise.all(clonePromises) - .then(() => { - // Mise à jour immédiate des données - setRegistrationFormsDataPending(prevState => [...(prevState || []), data]); - setTotalPending(prev => prev + 1); - if (updatedData.autoMail) { - sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName); - } - closeModal(); - // Forcer le rechargement complet des données - setReloadFetch(true); - }) - .catch(error => { - logger.error('Error during cloning or sending:', error); - }); - }) - .catch((error) => { - logger.error('Error:', error); - }); - } else { - const data = { - email: updatedData.guardianEmail, - password: 'Provisoire01!', - username: updatedData.guardianEmail, - is_active: 0, - droit: 2 - } - - createProfile(data, csrfToken) - .then(response => { - if (response.id) { - const data = { - student: { - last_name: updatedData.studentLastName, - first_name: updatedData.studentFirstName, - guardians: [{ - email: updatedData.guardianEmail, - phone: updatedData.guardianPhone, - associated_profile: response.id - }], - sibling: [] - }, - fees: allFeesIds, - discounts: allDiscountsds, - fileGroup: selectedFileGroup, - establishment: ESTABLISHMENT_ID + createRegisterForm(data, csrfToken) + .then(data => { + // Cloner les templates pour chaque templateMaster du fileGroup + const masters = templateMasters.filter(file => file.groups.includes(selectedFileGroup)); + const clonePromises = masters.map((templateMaster, index) => { + return cloneTemplate(templateMaster.id, updatedData.guardianEmail, templateMaster.is_required) + .then(clonedDocument => { + // Sauvegarde des templates clonés dans la base de données + const cloneData = { + name: `clone_${clonedDocument.id}`, + slug: clonedDocument.slug, + id: clonedDocument.id, + master: templateMaster.id, + registration_form: data.student.id }; - createRegisterForm(data, csrfToken) - .then(data => { - // Cloner les templates pour chaque templateMaster du fileGroup - const masters = templateMasters.filter(file => file.groups.includes(selectedFileGroup)); - const clonePromises = masters.map((templateMaster, index) => { - return cloneTemplate(templateMaster.id, updatedData.guardianEmail, templateMaster.is_required) - .then(clonedDocument => { - // Sauvegarde des templates clonés dans la base de données - const cloneData = { - name: `clone_${clonedDocument.id}`, - slug: clonedDocument.slug, - id: clonedDocument.id, - master: templateMaster.id, - registration_form: data.student.id - }; - - return createRegistrationTemplates(cloneData, csrfToken) - .then(response => { - logger.debug('Template enregistré avec succès:', response); - }) - .catch(error => { - logger.error('Erreur lors de l\'enregistrement du template:', error); - }); - }) - .catch(error => { - logger.error('Error during cloning or sending:', error); - }); - }); - - // Attendre que tous les clones soient créés - Promise.all(clonePromises) - .then(() => { - // Mise à jour immédiate des données - setRegistrationFormsDataPending(prevState => [...(prevState || []), data]); - setTotalPending(prev => prev + 1); - - if (updatedData.autoMail) { - sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName); - } - closeModal(); - logger.debug('Success:', data); - // Forcer le rechargement complet des données - setReloadFetch(true); - }) - .catch(error => { - logger.error('Error during cloning or sending:', error); - }); + return createRegistrationTemplates(cloneData, csrfToken) + .then(response => { + logger.debug('Template enregistré avec succès:', response); }) - .catch((error) => { - logger.error('Error:', error); - deleteProfile(response.id, csrfToken) - .then(() => { - logger.debug('Profile deleted due to RF creation failure'); - }) - .catch(deleteError => { - logger.error('Error deleting profile:', deleteError); - }); + .catch(error => { + logger.error('Erreur lors de l\'enregistrement du template:', error); }); + }) + .catch(error => { + logger.error('Error during cloning or sending:', error); + }); + }); + + // Attendre que tous les clones soient créés + Promise.all(clonePromises) + .then(() => { + // Mise à jour immédiate des données + setRegistrationFormsDataPending(prevState => [...(prevState || []), data]); + setTotalPending(prev => prev + 1); + if (updatedData.autoMail) { + sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName); } + closeModal(); + // Forcer le rechargement complet des données + setReloadFetch(true); }) .catch(error => { - logger.error('Error:', error); + logger.error('Error during cloning or sending:', error); }); - } + }) + .catch((error) => { + logger.error('Error:', error); + }); } const columns = [ diff --git a/Front-End/src/app/[locale]/parents/layout.js b/Front-End/src/app/[locale]/parents/layout.js index ddf78c3..a94fb6e 100644 --- a/Front-End/src/app/[locale]/parents/layout.js +++ b/Front-End/src/app/[locale]/parents/layout.js @@ -8,7 +8,7 @@ import Logo from '@/components/Logo'; // Ajout de l'importation du composant Log import { FE_PARENTS_HOME_URL,FE_PARENTS_MESSAGERIE_URL,FE_PARENTS_SETTINGS_URL } from '@/utils/Url'; // Ajout de l'importation de l'URL de la page d'accueil parent import { fetchMessages } from '@/app/actions/messagerieAction'; import ProtectedRoute from '@/components/ProtectedRoute'; -import { disconnect, getUser } from '@/app/actions/authAction'; +import { disconnect } from '@/app/actions/authAction'; import Popup from '@/components/Popup'; import logger from '@/utils/logger'; import { useSession } from 'next-auth/react'; @@ -36,19 +36,7 @@ export default function Layout({ const confirmDisconnect = () => { setIsPopupVisible(false); disconnect(); - }; - - useEffect(() => { - const fetchUser = async () => { - if (session) { // Vérifier que la session existe - const userData = await getUser(); - setUser(userData); - } - }; - - fetchUser(); - }, [session]); - + }; // useEffect(() => { // if (status === 'loading') return; diff --git a/Front-End/src/app/actions/authAction.js b/Front-End/src/app/actions/authAction.js index 54e5031..42241f0 100644 --- a/Front-End/src/app/actions/authAction.js +++ b/Front-End/src/app/actions/authAction.js @@ -179,31 +179,3 @@ export const getResetPassword = (uuid) => { }, }).then(requestResponseHandler); }; - -/** - * Récupère les informations de l'utilisateur connecté depuis la session - * @returns {Promise} Les données de l'utilisateur - */ -export const getUser = async () => { - try { - const session = await getSession(); - - if (!session || !session.user) { - return null; - } - - return { - id: session.user.user_id, - email: session.user.email, - roles: session.user.roles.map(role => ({ - role_type: role.role_type, - establishment_id: role.establishment__id, - establishment_name: role.establishment__name - })) - }; - - } catch (error) { - console.error('Error getting user from session:', error); - throw error; - } -}; \ No newline at end of file diff --git a/Front-End/src/app/actions/registerFileGroupAction.js b/Front-End/src/app/actions/registerFileGroupAction.js index 1c74d2d..a22fb9d 100644 --- a/Front-End/src/app/actions/registerFileGroupAction.js +++ b/Front-End/src/app/actions/registerFileGroupAction.js @@ -17,8 +17,8 @@ const requestResponseHandler = async (response) => { throw error; } -export async function fetchRegistrationFileGroups() { - const response = await fetch(`${BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL}`, { +export async function fetchRegistrationFileGroups(establishment) { + const response = await fetch(`${BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL}?establishment_id=${establishment}`, { credentials: 'include', headers: { 'Accept': 'application/json', diff --git a/Front-End/src/components/FileUpload copy.js b/Front-End/src/components/FileUpload copy.js index e13ba15..f77a798 100644 --- a/Front-End/src/components/FileUpload copy.js +++ b/Front-End/src/components/FileUpload copy.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import ToggleSwitch from '@/components/ToggleSwitch'; // Import du composant ToggleSwitch import DraggableFileUpload from './DraggableFileUpload'; import { fetchRegistrationFileGroups } from '@/app/actions/registerFileGroupAction'; +import { useEstablishment } from '@/context/EstablishmentContext'; export default function FileUpload({ onFileUpload, fileToEdit = null }) { const [fileName, setFileName] = useState(''); @@ -11,8 +12,10 @@ export default function FileUpload({ onFileUpload, fileToEdit = null }) { const [groups, setGroups] = useState([]); const [selectedGroup, setSelectedGroup] = useState(''); + const { selectedEstablishmentId } = useEstablishment(); + useEffect(() => { - fetchRegistrationFileGroups().then(data => setGroups(data)); + fetchRegistrationFileGroups(selectedEstablishmentId).then(data => setGroups(data)); if (fileToEdit) { setFileName(fileToEdit.name || ''); diff --git a/Front-End/src/components/Sidebar.js b/Front-End/src/components/Sidebar.js index cfd51b1..8b52f19 100644 --- a/Front-End/src/components/Sidebar.js +++ b/Front-End/src/components/Sidebar.js @@ -44,7 +44,7 @@ function Sidebar({ establishments, currentPage, items, onCloseMobile, onEstablis