diff --git a/Front-End/package-lock.json b/Front-End/package-lock.json
index c5f800b..07c265e 100644
--- a/Front-End/package-lock.json
+++ b/Front-End/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "n3wt-school-front-end",
- "version": "0.0.1",
+ "version": "0.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "n3wt-school-front-end",
- "version": "0.0.1",
+ "version": "0.0.3",
"dependencies": {
"@docuseal/react": "^1.0.56",
"@radix-ui/react-dialog": "^1.1.2",
@@ -29,6 +29,7 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18",
+ "react-hook-form": "^7.62.0",
"react-international-phone": "^4.5.0",
"react-quill": "^2.0.0",
"react-tooltip": "^5.28.0"
@@ -8834,6 +8835,21 @@
"react": "^18.3.1"
}
},
+ "node_modules/react-hook-form": {
+ "version": "7.62.0",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
+ "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
"node_modules/react-international-phone": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/react-international-phone/-/react-international-phone-4.5.0.tgz",
@@ -17160,6 +17176,12 @@
"scheduler": "^0.23.2"
}
},
+ "react-hook-form": {
+ "version": "7.62.0",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
+ "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
+ "requires": {}
+ },
"react-international-phone": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/react-international-phone/-/react-international-phone-4.5.0.tgz",
diff --git a/Front-End/package.json b/Front-End/package.json
index 810b4c4..cc0a551 100644
--- a/Front-End/package.json
+++ b/Front-End/package.json
@@ -35,20 +35,21 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18",
+ "react-hook-form": "^7.62.0",
"react-international-phone": "^4.5.0",
"react-quill": "^2.0.0",
"react-tooltip": "^5.28.0"
},
"devDependencies": {
- "@testing-library/react": "^13.4.0",
"@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
- "jest": "^29.7.0",
- "jest-environment-jsdom": "^29.7.0",
"autoprefixer": "^10.4.20",
"eslint": "^8",
"eslint-config-next": "14.2.11",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.14"
}
-}
\ No newline at end of file
+}
diff --git a/Front-End/src/app/[locale]/admin/grades/page.js b/Front-End/src/app/[locale]/admin/grades/page.js
index 3170d8b..4b098e8 100644
--- a/Front-End/src/app/[locale]/admin/grades/page.js
+++ b/Front-End/src/app/[locale]/admin/grades/page.js
@@ -1,6 +1,6 @@
'use client';
import React, { useState, useEffect } from 'react';
-import SelectChoice from '@/components/SelectChoice';
+import SelectChoice from '@/components/Form/SelectChoice';
import AcademicResults from '@/components/Grades/AcademicResults';
import Attendance from '@/components/Grades/Attendance';
import Remarks from '@/components/Grades/Remarks';
@@ -9,7 +9,7 @@ import Homeworks from '@/components/Grades/Homeworks';
import SpecificEvaluations from '@/components/Grades/SpecificEvaluations';
import Orientation from '@/components/Grades/Orientation';
import GradesStatsCircle from '@/components/Grades/GradesStatsCircle';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import logger from '@/utils/logger';
import {
FE_ADMIN_GRADES_STUDENT_COMPETENCIES_URL,
@@ -29,7 +29,7 @@ import { useClasses } from '@/context/ClassesContext';
import { Award, FileText } from 'lucide-react';
import SectionHeader from '@/components/SectionHeader';
import GradesDomainBarChart from '@/components/Grades/GradesDomainBarChart';
-import InputText from '@/components/InputText';
+import InputText from '@/components/Form/InputText';
import dayjs from 'dayjs';
import { useCsrfToken } from '@/context/CsrfContext';
diff --git a/Front-End/src/app/[locale]/admin/grades/studentCompetencies/page.js b/Front-End/src/app/[locale]/admin/grades/studentCompetencies/page.js
index 433bb5c..cca7e8e 100644
--- a/Front-End/src/app/[locale]/admin/grades/studentCompetencies/page.js
+++ b/Front-End/src/app/[locale]/admin/grades/studentCompetencies/page.js
@@ -2,7 +2,7 @@
import React, { useState, useEffect } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import GradeView from '@/components/Grades/GradeView';
import {
fetchStudentCompetencies,
diff --git a/Front-End/src/app/[locale]/admin/settings/page.js b/Front-End/src/app/[locale]/admin/settings/page.js
index 58d06f9..d037ad0 100644
--- a/Front-End/src/app/[locale]/admin/settings/page.js
+++ b/Front-End/src/app/[locale]/admin/settings/page.js
@@ -2,8 +2,8 @@
import React, { useState, useEffect } from 'react';
import Tab from '@/components/Tab';
import TabContent from '@/components/TabContent';
-import Button from '@/components/Button';
-import InputText from '@/components/InputText';
+import Button from '@/components/Form/Button';
+import InputText from '@/components/Form/InputText';
import CheckBox from '@/components/CheckBox'; // Import du composant CheckBox
import logger from '@/utils/logger';
import {
diff --git a/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js b/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js
index 01fe220..737f36d 100644
--- a/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js
+++ b/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js
@@ -8,8 +8,8 @@ import { fetchClasse } from '@/app/actions/schoolAction';
import { useSearchParams } from 'next/navigation';
import logger from '@/utils/logger';
import { useClasses } from '@/context/ClassesContext';
-import Button from '@/components/Button';
-import SelectChoice from '@/components/SelectChoice';
+import Button from '@/components/Form/Button';
+import SelectChoice from '@/components/Form/SelectChoice';
import CheckBox from '@/components/CheckBox';
import {
fetchAbsences,
diff --git a/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js b/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js
index 797a485..51bf505 100644
--- a/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js
+++ b/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js
@@ -2,17 +2,17 @@
import React, { useState, useRef, useEffect } from 'react';
import { User, Mail } from 'lucide-react';
-import InputTextIcon from '@/components/InputTextIcon';
-import ToggleSwitch from '@/components/ToggleSwitch';
-import Button from '@/components/Button';
+import InputTextIcon from '@/components/Form/InputTextIcon';
+import ToggleSwitch from '@/components/Form/ToggleSwitch';
+import Button from '@/components/Form/Button';
import Table from '@/components/Table';
import FeesSection from '@/components/Structure/Tarification/FeesSection';
import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection';
import SectionTitle from '@/components/SectionTitle';
-import InputPhone from '@/components/InputPhone';
+import InputPhone from '@/components/Form/InputPhone';
import CheckBox from '@/components/CheckBox';
-import RadioList from '@/components/RadioList';
-import SelectChoice from '@/components/SelectChoice';
+import RadioList from '@/components/Form/RadioList';
+import SelectChoice from '@/components/Form/SelectChoice';
import Loader from '@/components/Loader';
import { getCurrentSchoolYear, getNextSchoolYear } from '@/utils/Date';
import logger from '@/utils/logger';
diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js
index 821fa93..bc546b5 100644
--- a/Front-End/src/app/[locale]/admin/subscriptions/page.js
+++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js
@@ -40,8 +40,8 @@ import {
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import { useCsrfToken } from '@/context/CsrfContext';
import logger from '@/utils/logger';
-import { PhoneLabel } from '@/components/PhoneLabel';
-import FileUpload from '@/components/FileUpload';
+import { PhoneLabel } from '@/components/Form/PhoneLabel';
+import FileUpload from '@/components/Form/FileUpload';
import FilesModal from '@/components/Inscription/FilesModal';
import { getCurrentSchoolYear, getNextSchoolYear } from '@/utils/Date';
@@ -250,7 +250,12 @@ export default function Page({ params: { locale } }) {
}, 500); // Debounce la recherche
return () => clearTimeout(timeoutId);
}
- }, [searchTerm, selectedEstablishmentId, currentSchoolYearPage, itemsPerPage]);
+ }, [
+ searchTerm,
+ selectedEstablishmentId,
+ currentSchoolYearPage,
+ itemsPerPage,
+ ]);
/**
* UseEffect to update page count of tab
diff --git a/Front-End/src/app/[locale]/page.js b/Front-End/src/app/[locale]/page.js
index cadbff1..8f13814 100644
--- a/Front-End/src/app/[locale]/page.js
+++ b/Front-End/src/app/[locale]/page.js
@@ -1,8 +1,9 @@
'use client';
import { useTranslations } from 'next-intl';
import React from 'react';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import Logo from '@/components/Logo'; // Import du composant Logo
+import FormRenderer from '@/components/Form/FormRenderer';
export default function Home() {
const t = useTranslations('homePage');
@@ -13,6 +14,7 @@ export default function Home() {
{t('welcomeParents')}
{t('pleaseLogin')}
+
);
}
diff --git a/Front-End/src/app/[locale]/parents/page.js b/Front-End/src/app/[locale]/parents/page.js
index 55a160a..992329e 100644
--- a/Front-End/src/app/[locale]/parents/page.js
+++ b/Front-End/src/app/[locale]/parents/page.js
@@ -11,7 +11,7 @@ import {
CalendarDays,
} from 'lucide-react';
import StatusLabel from '@/components/StatusLabel';
-import FileUpload from '@/components/FileUpload';
+import FileUpload from '@/components/Form/FileUpload';
import { FE_PARENTS_EDIT_SUBSCRIPTION_URL } from '@/utils/Url';
import {
fetchChildren,
diff --git a/Front-End/src/app/[locale]/parents/settings/page.js b/Front-End/src/app/[locale]/parents/settings/page.js
index dd647c0..76e624f 100644
--- a/Front-End/src/app/[locale]/parents/settings/page.js
+++ b/Front-End/src/app/[locale]/parents/settings/page.js
@@ -1,7 +1,7 @@
'use client';
import React, { useState } from 'react';
-import Button from '@/components/Button';
-import InputText from '@/components/InputText';
+import Button from '@/components/Form/Button';
+import InputText from '@/components/Form/InputText';
import logger from '@/utils/logger';
import { useNotification } from '@/context/NotificationContext';
diff --git a/Front-End/src/app/[locale]/users/login/page.js b/Front-End/src/app/[locale]/users/login/page.js
index 80f9fab..2fa1359 100644
--- a/Front-End/src/app/[locale]/users/login/page.js
+++ b/Front-End/src/app/[locale]/users/login/page.js
@@ -3,9 +3,9 @@ import React, { useState } from 'react';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Logo from '@/components/Logo';
import { useRouter } from 'next/navigation';
-import InputTextIcon from '@/components/InputTextIcon';
+import InputTextIcon from '@/components/Form/InputTextIcon';
import Loader from '@/components/Loader'; // Importez le composant Loader
-import Button from '@/components/Button'; // Importez le composant Button
+import Button from '@/components/Form/Button'; // Importez le composant Button
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
import { FE_USERS_NEW_PASSWORD_URL, getRedirectUrlFromRole } from '@/utils/Url';
import { login } from '@/app/actions/authAction';
@@ -35,11 +35,7 @@ export default function Page() {
logger.debug('Sign In Result', result);
if (result.error) {
- showNotification(
- result.error,
- 'error',
- 'Erreur'
- );
+ showNotification(result.error, 'error', 'Erreur');
setIsLoading(false);
} else {
// On initialise le contexte establishement avec la session
@@ -50,11 +46,7 @@ export default function Page() {
if (url) {
router.push(url);
} else {
- showNotification(
- 'Type de rôle non géré',
- 'error',
- 'Erreur'
- );
+ showNotification('Type de rôle non géré', 'error', 'Erreur');
}
});
setIsLoading(false);
diff --git a/Front-End/src/app/[locale]/users/password/new/page.js b/Front-End/src/app/[locale]/users/password/new/page.js
index f7a3754..3a44909 100644
--- a/Front-End/src/app/[locale]/users/password/new/page.js
+++ b/Front-End/src/app/[locale]/users/password/new/page.js
@@ -3,9 +3,9 @@
import React, { useState } from 'react';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Logo from '@/components/Logo';
-import InputTextIcon from '@/components/InputTextIcon';
+import InputTextIcon from '@/components/Form/InputTextIcon';
import Loader from '@/components/Loader';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import { User } from 'lucide-react';
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
import { useCsrfToken } from '@/context/CsrfContext';
@@ -25,25 +25,13 @@ export default function Page() {
.then((data) => {
logger.debug('Success:', data);
if (data.message !== '') {
- showNotification(
- data.message,
- 'success',
- 'Succès'
- );
+ showNotification(data.message, 'success', 'Succès');
router.push(`${FE_USERS_LOGIN_URL}`);
} else {
if (data.errorMessage) {
- showNotification(
- data.errorMessage,
- 'error',
- 'Erreur'
- );
+ showNotification(data.errorMessage, 'error', 'Erreur');
} else if (data.errorFields) {
- showNotification(
- data.errorFields.email,
- 'error',
- 'Erreur'
- );
+ showNotification(data.errorFields.email, 'error', 'Erreur');
}
}
setIsLoading(false);
diff --git a/Front-End/src/app/[locale]/users/password/reset/page.js b/Front-End/src/app/[locale]/users/password/reset/page.js
index 620ad2f..14c1b7d 100644
--- a/Front-End/src/app/[locale]/users/password/reset/page.js
+++ b/Front-End/src/app/[locale]/users/password/reset/page.js
@@ -5,9 +5,9 @@ import React, { useState, useEffect } from 'react';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Logo from '@/components/Logo';
import { useSearchParams, useRouter } from 'next/navigation';
-import InputTextIcon from '@/components/InputTextIcon';
+import InputTextIcon from '@/components/Form/InputTextIcon';
import Loader from '@/components/Loader';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
import { KeySquare } from 'lucide-react';
import { useCsrfToken } from '@/context/CsrfContext';
@@ -33,21 +33,12 @@ export default function Page() {
resetPassword(uuid, data, csrfToken)
.then((data) => {
if (data.message !== '') {
-
logger.debug('Success:', data);
- showNotification(
- data.message,
- 'success',
- 'Succès'
- );
+ showNotification(data.message, 'success', 'Succès');
router.push(`${FE_USERS_LOGIN_URL}`);
} else {
if (data.errorMessage) {
- showNotification(
- data.errorMessage,
- 'error',
- 'Erreur'
- );
+ showNotification(data.errorMessage, 'error', 'Erreur');
} else if (data.errorFields) {
showNotification(
data.errorFields.password1 || data.errorFields.password2,
diff --git a/Front-End/src/app/[locale]/users/subscribe/page.js b/Front-End/src/app/[locale]/users/subscribe/page.js
index bf51143..e475cbe 100644
--- a/Front-End/src/app/[locale]/users/subscribe/page.js
+++ b/Front-End/src/app/[locale]/users/subscribe/page.js
@@ -4,9 +4,9 @@ import React, { useState, useEffect } from 'react';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import Logo from '@/components/Logo';
import { useSearchParams, useRouter } from 'next/navigation';
-import InputTextIcon from '@/components/InputTextIcon';
+import InputTextIcon from '@/components/Form/InputTextIcon';
import Loader from '@/components/Loader';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import { User, KeySquare } from 'lucide-react';
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
import { useCsrfToken } from '@/context/CsrfContext';
@@ -36,22 +36,16 @@ export default function Page() {
.then((data) => {
logger.debug('Success:', data);
if (data.message !== '') {
- showNotification(
- data.message,
- 'success',
- 'Succès'
- );
+ showNotification(data.message, 'success', 'Succès');
router.push(`${FE_USERS_LOGIN_URL}`);
} else {
if (data.errorMessage) {
- showNotification(
- data.errorMessage,
- 'error',
- 'Erreur'
- );
+ showNotification(data.errorMessage, 'error', 'Erreur');
} else if (data.errorFields) {
showNotification(
- data.errorFields.email || data.errorFields.password1 || data.errorFields.password2,
+ data.errorFields.email ||
+ data.errorFields.password1 ||
+ data.errorFields.password2,
'error',
'Erreur'
);
diff --git a/Front-End/src/components/Admin/EmailSender.js b/Front-End/src/components/Admin/EmailSender.js
index 89ce8d4..9dc25c7 100644
--- a/Front-End/src/components/Admin/EmailSender.js
+++ b/Front-End/src/components/Admin/EmailSender.js
@@ -9,10 +9,10 @@ import { useEstablishment } from '@/context/EstablishmentContext';
import AlertMessage from '@/components/AlertMessage';
import RecipientInput from '@/components/RecipientInput';
import { useRouter } from 'next/navigation'; // Ajoute cette ligne
-import WisiwigTextArea from '@/components/WisiwigTextArea';
+import WisiwigTextArea from '@/components/Form/WisiwigTextArea';
import logger from '@/utils/logger';
-import InputText from '@/components/InputText';
-import Button from '@/components/Button';
+import InputText from '@/components/Form/InputText';
+import Button from '@/components/Form/Button';
export default function EmailSender({ csrfToken }) {
const [recipients, setRecipients] = useState([]);
diff --git a/Front-End/src/components/Button.js b/Front-End/src/components/Form/Button.js
similarity index 100%
rename from Front-End/src/components/Button.js
rename to Front-End/src/components/Form/Button.js
diff --git a/Front-End/src/components/DraggableFileUpload.js b/Front-End/src/components/Form/DraggableFileUpload.js
similarity index 100%
rename from Front-End/src/components/DraggableFileUpload.js
rename to Front-End/src/components/Form/DraggableFileUpload.js
diff --git a/Front-End/src/components/FileUpload.js b/Front-End/src/components/Form/FileUpload.js
similarity index 100%
rename from Front-End/src/components/FileUpload.js
rename to Front-End/src/components/Form/FileUpload.js
diff --git a/Front-End/src/components/Form/FormRenderer.js b/Front-End/src/components/Form/FormRenderer.js
new file mode 100644
index 0000000..30acdfb
--- /dev/null
+++ b/Front-End/src/components/Form/FormRenderer.js
@@ -0,0 +1,194 @@
+import logger from '@/utils/logger';
+import { useForm, Controller } from 'react-hook-form';
+import SelectChoice from './SelectChoice';
+import InputTextIcon from './InputTextIcon';
+import * as LucideIcons from 'lucide-react';
+import Button from './Button';
+import DjangoCSRFToken from '../DjangoCSRFToken';
+import WisiwigTextArea from './WisiwigTextArea';
+
+/*
+ * Récupère une icône Lucide par son nom.
+ */
+export function getIcon(name) {
+ if (Object.keys(LucideIcons).includes(name)) {
+ const Icon = LucideIcons[name];
+ return Icon ?? null;
+ } else {
+ return null;
+ }
+}
+
+const formConfigTest = {
+ id: 0,
+ title: 'Mon formulaire dynamique',
+ submitLabel: 'Envoyer',
+ fields: [
+ { id: 'name', label: 'Nom', type: 'text', required: true },
+ { id: 'email', label: 'Email', type: 'email' },
+ {
+ id: 'email2',
+ label: 'Email',
+ type: 'text',
+ icon: 'Mail',
+ },
+ {
+ id: 'role',
+ label: 'Rôle',
+ type: 'select',
+ options: ['Admin', 'Utilisateur', 'Invité'],
+ required: true,
+ },
+ {
+ type: 'paragraph',
+ text: "Bonjour, Bienvenue dans ce formulaire d'inscription haha",
+ },
+ {
+ id: 'birthdate',
+ label: 'Date de naissance',
+ type: 'date',
+ icon: 'Calendar',
+ },
+ {
+ id: 'textarea',
+ label: 'toto',
+ type: 'textarea',
+ },
+ ],
+};
+
+export default function FormRenderer({
+ formConfig = formConfigTest,
+ csrfToken,
+}) {
+ const {
+ handleSubmit,
+ control,
+ formState: { errors },
+ reset,
+ } = useForm();
+
+ const onSubmit = (data) => {
+ logger.debug('=== DÉBUT onSubmit ===');
+ logger.debug('Réponses :', data);
+
+ const formattedData = {
+ //TODO: idDossierInscriptions: 123,
+ formId: formConfig.id,
+ responses: { ...data },
+ };
+
+ //TODO: ENVOYER LES DONNÉES AU BACKEND
+ alert('Données reçues : ' + JSON.stringify(formattedData, null, 2));
+ reset(); // Réinitialiser le formulaire après soumission
+ logger.debug('=== FIN onSubmit ===');
+ };
+
+ const onError = (errors) => {
+ logger.error('=== ERREURS DE VALIDATION ===');
+ logger.error('Erreurs :', errors);
+ alert('Erreurs de validation : ' + JSON.stringify(errors, null, 2));
+ };
+
+ return (
+
+ );
+}
diff --git a/Front-End/src/components/InputPhone.js b/Front-End/src/components/Form/InputPhone.js
similarity index 100%
rename from Front-End/src/components/InputPhone.js
rename to Front-End/src/components/Form/InputPhone.js
diff --git a/Front-End/src/components/InputText.js b/Front-End/src/components/Form/InputText.js
similarity index 100%
rename from Front-End/src/components/InputText.js
rename to Front-End/src/components/Form/InputText.js
diff --git a/Front-End/src/components/InputTextIcon.js b/Front-End/src/components/Form/InputTextIcon.js
similarity index 86%
rename from Front-End/src/components/InputTextIcon.js
rename to Front-End/src/components/Form/InputTextIcon.js
index 1f54ed7..d5b2989 100644
--- a/Front-End/src/components/InputTextIcon.js
+++ b/Front-End/src/components/Form/InputTextIcon.js
@@ -1,3 +1,5 @@
+import React from 'react';
+
export default function InputTextIcon({
name,
type,
@@ -31,9 +33,11 @@ export default function InputTextIcon({
!enable ? 'bg-gray-100 cursor-not-allowed' : ''
}`}
>
-
- {IconItem && }
-
+ {IconItem ? (
+
+
+
+ ) : null}
import('react-quill'), { ssr: false });
export default function WisiwigTextArea({
- label = 'Mail',
+ label = 'Zone de Texte',
value,
onChange,
- placeholder = 'Ecrivez votre mail ici...',
+ placeholder = 'Ecrivez votre texte ici...',
className = 'h-64',
required = false,
errorMsg,
diff --git a/Front-End/src/components/Grades/Attendance.js b/Front-End/src/components/Grades/Attendance.js
index 715a561..288b7e5 100644
--- a/Front-End/src/components/Grades/Attendance.js
+++ b/Front-End/src/components/Grades/Attendance.js
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { Trash2 } from 'lucide-react';
-import ToggleSwitch from '@/components/ToggleSwitch';
-import Button from '@/components/Button';
+import ToggleSwitch from '@/components/Form/ToggleSwitch';
+import Button from '@/components/Form/Button';
import Popup from '@/components/Popup';
import { useNotification } from '@/context/NotificationContext';
diff --git a/Front-End/src/components/Grades/GradeView.js b/Front-End/src/components/Grades/GradeView.js
index 0442c1e..d245fba 100644
--- a/Front-End/src/components/Grades/GradeView.js
+++ b/Front-End/src/components/Grades/GradeView.js
@@ -1,6 +1,6 @@
import React, { useState, useMemo, useEffect } from 'react';
import { BookOpen, CheckCircle, AlertCircle, Clock } from 'lucide-react';
-import RadioList from '@/components/RadioList';
+import RadioList from '@/components/Form/RadioList';
const LEVELS = [
{ value: 0, label: 'Non évalué' },
diff --git a/Front-End/src/components/Inscription/FilesToUpload.js b/Front-End/src/components/Inscription/FilesToUpload.js
index 5342924..56633a8 100644
--- a/Front-End/src/components/Inscription/FilesToUpload.js
+++ b/Front-End/src/components/Inscription/FilesToUpload.js
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import Table from '@/components/Table';
-import FileUpload from '@/components/FileUpload';
+import FileUpload from '@/components/Form/FileUpload';
import { Upload, Eye, Trash2, FileText } from 'lucide-react';
import { BASE_URL } from '@/utils/Url';
import Popup from '@/components/Popup';
diff --git a/Front-End/src/components/Inscription/InscriptionFormShared.js b/Front-End/src/components/Inscription/InscriptionFormShared.js
index b1fb881..006eec3 100644
--- a/Front-End/src/components/Inscription/InscriptionFormShared.js
+++ b/Front-End/src/components/Inscription/InscriptionFormShared.js
@@ -1,6 +1,6 @@
// Import des dépendances nécessaires
import React, { useState, useEffect } from 'react';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import {
fetchSchoolFileTemplatesFromRegistrationFiles,
@@ -220,9 +220,7 @@ export default function InscriptionFormShared({
.then((data) => {
setProfiles(data);
})
- .catch((error) =>
- logger.error('Error fetching profiles : ', error)
- );
+ .catch((error) => logger.error('Error fetching profiles : ', error));
if (selectedEstablishmentId) {
// Fetch data for registration payment modes
@@ -385,7 +383,7 @@ export default function InscriptionFormShared({
// Soumission du formulaire
const handleSubmit = (e) => {
e.preventDefault();
-
+
// Vérifier si le mode de paiement sélectionné est un prélèvement SEPA
const isSepaPayment = formData.isSepa === 1;
diff --git a/Front-End/src/components/Inscription/PaymentMethodSelector.js b/Front-End/src/components/Inscription/PaymentMethodSelector.js
index 53ff5d9..4ff29f2 100644
--- a/Front-End/src/components/Inscription/PaymentMethodSelector.js
+++ b/Front-End/src/components/Inscription/PaymentMethodSelector.js
@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
-import SelectChoice from '@/components/SelectChoice';
-import RadioList from '@/components/RadioList';
+import SelectChoice from '@/components/Form/SelectChoice';
+import RadioList from '@/components/Form/RadioList';
import logger from '@/utils/logger';
export default function PaymentMethodSelector({
diff --git a/Front-End/src/components/Inscription/ResponsableInputFields.js b/Front-End/src/components/Inscription/ResponsableInputFields.js
index 2bd917e..a156316 100644
--- a/Front-End/src/components/Inscription/ResponsableInputFields.js
+++ b/Front-End/src/components/Inscription/ResponsableInputFields.js
@@ -1,5 +1,5 @@
-import InputText from '@/components/InputText';
-import InputPhone from '@/components/InputPhone';
+import InputText from '@/components/Form/InputText';
+import InputPhone from '@/components/Form/InputPhone';
import React, { useEffect } from 'react';
import { useTranslations } from 'next-intl';
import { Trash2, Plus, Users } from 'lucide-react';
diff --git a/Front-End/src/components/Inscription/SiblingInputFields.js b/Front-End/src/components/Inscription/SiblingInputFields.js
index 656d297..b9ead46 100644
--- a/Front-End/src/components/Inscription/SiblingInputFields.js
+++ b/Front-End/src/components/Inscription/SiblingInputFields.js
@@ -1,4 +1,4 @@
-import InputText from '@/components/InputText';
+import InputText from '@/components/Form/InputText';
import React, { useEffect } from 'react';
import { Trash2, Plus, Users } from 'lucide-react';
import SectionHeader from '@/components/SectionHeader';
diff --git a/Front-End/src/components/Inscription/StudentInfoForm.js b/Front-End/src/components/Inscription/StudentInfoForm.js
index ef6cb74..a8739cf 100644
--- a/Front-End/src/components/Inscription/StudentInfoForm.js
+++ b/Front-End/src/components/Inscription/StudentInfoForm.js
@@ -1,12 +1,12 @@
import React, { useState, useEffect } from 'react';
-import InputText from '@/components/InputText';
-import SelectChoice from '@/components/SelectChoice';
+import InputText from '@/components/Form/InputText';
+import SelectChoice from '@/components/Form/SelectChoice';
import Loader from '@/components/Loader';
import { fetchRegisterForm } from '@/app/actions/subscriptionAction';
import logger from '@/utils/logger';
import SectionHeader from '@/components/SectionHeader';
import { User } from 'lucide-react';
-import FileUpload from '@/components/FileUpload';
+import FileUpload from '@/components/Form/FileUpload';
import { BASE_URL } from '@/utils/Url';
import { levels, genders } from '@/utils/constants';
@@ -112,13 +112,10 @@ export default function StudentInfoForm({
(field === 'birth_place' &&
(!formData.birth_place || formData.birth_place.trim() === '')) ||
(field === 'birth_postal_code' &&
- (
- !formData.birth_postal_code ||
+ (!formData.birth_postal_code ||
String(formData.birth_postal_code).trim() === '' ||
isNaN(Number(formData.birth_postal_code)) ||
- !Number.isInteger(Number(formData.birth_postal_code))
- )
- ) ||
+ !Number.isInteger(Number(formData.birth_postal_code)))) ||
(field === 'address' &&
(!formData.address || formData.address.trim() === '')) ||
(field === 'attending_physician' &&
diff --git a/Front-End/src/components/Inscription/ValidateSubscription.js b/Front-End/src/components/Inscription/ValidateSubscription.js
index bf551aa..c49816f 100644
--- a/Front-End/src/components/Inscription/ValidateSubscription.js
+++ b/Front-End/src/components/Inscription/ValidateSubscription.js
@@ -1,7 +1,7 @@
'use client';
import React, { useState, useEffect } from 'react';
-import ToggleSwitch from '@/components/ToggleSwitch';
-import SelectChoice from '@/components/SelectChoice';
+import ToggleSwitch from '@/components/Form/ToggleSwitch';
+import SelectChoice from '@/components/Form/SelectChoice';
import { BASE_URL } from '@/utils/Url';
import {
fetchSchoolFileTemplatesFromRegistrationFiles,
@@ -10,7 +10,7 @@ import {
import logger from '@/utils/logger';
import { School, CheckCircle, Hourglass, FileText } from 'lucide-react';
import SectionHeader from '@/components/SectionHeader';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
export default function ValidateSubscription({
studentId,
diff --git a/Front-End/src/components/Structure/Competencies/CompetenciesList.js b/Front-End/src/components/Structure/Competencies/CompetenciesList.js
index 1b017e7..afc06b3 100644
--- a/Front-End/src/components/Structure/Competencies/CompetenciesList.js
+++ b/Front-End/src/components/Structure/Competencies/CompetenciesList.js
@@ -2,9 +2,9 @@ import React, { useState, useRef, useCallback } from 'react';
import TreeView from '@/components/Structure/Competencies/TreeView';
import SectionHeader from '@/components/SectionHeader';
import { Award, CheckCircle } from 'lucide-react';
-import SelectChoice from '@/components/SelectChoice';
+import SelectChoice from '@/components/Form/SelectChoice';
import CheckBox from '@/components/CheckBox';
-import Button from '@/components/Button';
+import Button from '@/components/Form/Button';
import { useEstablishment } from '@/context/EstablishmentContext';
import {
fetchEstablishmentCompetencies,
diff --git a/Front-End/src/components/Structure/Configuration/ClassesSection.js b/Front-End/src/components/Structure/Configuration/ClassesSection.js
index 71c24f0..86d65b7 100644
--- a/Front-End/src/components/Structure/Configuration/ClassesSection.js
+++ b/Front-End/src/components/Structure/Configuration/ClassesSection.js
@@ -2,10 +2,10 @@ import { Trash2, Edit3, ZoomIn, Users, Check, X, Hand } from 'lucide-react';
import React, { useState, useEffect } from 'react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
-import InputText from '@/components/InputText';
-import SelectChoice from '@/components/SelectChoice';
+import InputText from '@/components/Form/InputText';
+import SelectChoice from '@/components/Form/SelectChoice';
import TeacherItem from '@/components/Structure/Configuration/TeacherItem';
-import MultiSelect from '@/components/MultiSelect';
+import MultiSelect from '@/components/Form/MultiSelect';
import LevelLabel from '@/components/CustomLabels/LevelLabel';
import { DndProvider, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
diff --git a/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js b/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js
index b890a32..fe5bacc 100644
--- a/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js
+++ b/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js
@@ -2,7 +2,7 @@ import { Trash2, Edit3, Check, X, BookOpen } from 'lucide-react';
import { useState } from 'react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
-import InputTextWithColorIcon from '@/components/InputTextWithColorIcon';
+import InputTextWithColorIcon from '@/components/Form/InputTextWithColorIcon';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
diff --git a/Front-End/src/components/Structure/Configuration/TeachersSection.js b/Front-End/src/components/Structure/Configuration/TeachersSection.js
index 37aa84f..fab2546 100644
--- a/Front-End/src/components/Structure/Configuration/TeachersSection.js
+++ b/Front-End/src/components/Structure/Configuration/TeachersSection.js
@@ -2,11 +2,11 @@ import React, { useState, useEffect } from 'react';
import { Edit3, Trash2, GraduationCap, Check, X, Hand } from 'lucide-react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
-import ToggleSwitch from '@/components/ToggleSwitch';
+import ToggleSwitch from '@/components/Form/ToggleSwitch';
import { useCsrfToken } from '@/context/CsrfContext';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
-import InputText from '@/components/InputText';
+import InputText from '@/components/Form/InputText';
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
import TeacherItem from './TeacherItem';
import logger from '@/utils/logger';
diff --git a/Front-End/src/components/Structure/Files/FileUploadDocuSeal.js b/Front-End/src/components/Structure/Files/FileUploadDocuSeal.js
index da9f70f..a3173ea 100644
--- a/Front-End/src/components/Structure/Files/FileUploadDocuSeal.js
+++ b/Front-End/src/components/Structure/Files/FileUploadDocuSeal.js
@@ -7,7 +7,7 @@ import {
} from '@/app/actions/registerFileGroupAction';
import { DocusealBuilder } from '@docuseal/react';
import logger from '@/utils/logger';
-import MultiSelect from '@/components/MultiSelect'; // Import du composant MultiSelect
+import MultiSelect from '@/components/Form/MultiSelect'; // Import du composant MultiSelect
import { useCsrfToken } from '@/context/CsrfContext';
import { useEstablishment } from '@/context/EstablishmentContext';
import Popup from '@/components/Popup';
@@ -121,7 +121,13 @@ export default function FileUploadDocuSeal({
guardianDetails.forEach((guardian, index) => {
logger.debug('creation du clone avec required : ', is_required);
- cloneTemplate(templateMaster?.id, guardian.email, is_required, selectedEstablishmentId, apiDocuseal)
+ cloneTemplate(
+ templateMaster?.id,
+ guardian.email,
+ is_required,
+ selectedEstablishmentId,
+ apiDocuseal
+ )
.then((clonedDocument) => {
// Sauvegarde des schoolFileTemplates clonés dans la base de données
const data = {
diff --git a/Front-End/src/components/Structure/Files/ParentFilesSection.js b/Front-End/src/components/Structure/Files/ParentFilesSection.js
index 044a391..86b1efb 100644
--- a/Front-End/src/components/Structure/Files/ParentFilesSection.js
+++ b/Front-End/src/components/Structure/Files/ParentFilesSection.js
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import { Plus, Edit3, Trash2, Check, X, FileText } from 'lucide-react';
import Table from '@/components/Table';
-import InputText from '@/components/InputText';
-import MultiSelect from '@/components/MultiSelect';
+import InputText from '@/components/Form/InputText';
+import MultiSelect from '@/components/Form/MultiSelect';
import Popup from '@/components/Popup';
import logger from '@/utils/logger';
import { createRegistrationParentFileTemplate } from '@/app/actions/registerFileGroupAction';
import { useCsrfToken } from '@/context/CsrfContext';
import SectionHeader from '@/components/SectionHeader';
-import ToggleSwitch from '@/components/ToggleSwitch';
+import ToggleSwitch from '@/components/Form/ToggleSwitch';
import { useNotification } from '@/context/NotificationContext';
import AlertMessage from '@/components/AlertMessage';
diff --git a/Front-End/src/components/Structure/Tarification/DiscountsSection.js b/Front-End/src/components/Structure/Tarification/DiscountsSection.js
index 3c874aa..bbd9ac8 100644
--- a/Front-End/src/components/Structure/Tarification/DiscountsSection.js
+++ b/Front-End/src/components/Structure/Tarification/DiscountsSection.js
@@ -3,7 +3,7 @@ import { Trash2, Edit3, Check, X, Percent, EuroIcon, Tag } from 'lucide-react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
import CheckBox from '@/components/CheckBox';
-import InputText from '@/components/InputText';
+import InputText from '@/components/Form/InputText';
import logger from '@/utils/logger';
import SectionHeader from '@/components/SectionHeader';
import { useEstablishment } from '@/context/EstablishmentContext';
diff --git a/Front-End/src/components/Structure/Tarification/FeesSection.js b/Front-End/src/components/Structure/Tarification/FeesSection.js
index 6c9bc6a..a26cf84 100644
--- a/Front-End/src/components/Structure/Tarification/FeesSection.js
+++ b/Front-End/src/components/Structure/Tarification/FeesSection.js
@@ -3,7 +3,7 @@ import { Trash2, Edit3, Check, X, EyeOff, Eye, CreditCard } from 'lucide-react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
import CheckBox from '@/components/CheckBox';
-import InputText from '@/components/InputText';
+import InputText from '@/components/Form/InputText';
import logger from '@/utils/logger';
import SectionHeader from '@/components/SectionHeader';
import { useEstablishment } from '@/context/EstablishmentContext';