feat: Mise en place des actions pour chaque state du RF, possibilité

d'éditer le formulaire de création de RF (reste à submit un PUT)
This commit is contained in:
N3WT DE COMPET
2025-05-06 00:53:45 +02:00
parent 4fc061fc25
commit 8fc9478786
11 changed files with 351 additions and 130 deletions

View File

@ -340,16 +340,22 @@ class RegistrationFormByParentSerializer(serializers.ModelSerializer):
class GuardianByDICreationSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
associated_profile_email = serializers.SerializerMethodField()
profile = serializers.SerializerMethodField()
class Meta:
model = Guardian
fields = ['id', 'last_name', 'first_name', 'associated_profile_email', 'phone']
fields = ['id', 'last_name', 'first_name', 'associated_profile_email', 'phone', 'profile_role', 'profile']
def get_associated_profile_email(self, obj):
if obj.profile_role and obj.profile_role.profile:
return obj.profile_role.profile.email
return None
def get_profile(self, obj):
if obj.profile_role and obj.profile_role.profile:
return obj.profile_role.profile.id # Retourne l'ID du profil associé
return None
class StudentByRFCreationSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
guardians = GuardianByDICreationSerializer(many=True, required=False)

View File

@ -9,7 +9,6 @@ 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 Popup from '@/components/Popup';
import InputPhone from '@/components/InputPhone';
import CheckBox from '@/components/CheckBox';
import RadioList from '@/components/RadioList';
@ -18,8 +17,9 @@ import { getCurrentSchoolYear, getNextSchoolYear } from '@/utils/Date';
import logger from '@/utils/logger';
import { levels, genders } from '@/utils/constants';
import { useEstablishment } from '@/context/EstablishmentContext';
import { useRouter } from 'next/navigation';
import { useSearchParams, useRouter } from 'next/navigation';
import {
fetchRegisterForm,
fetchStudents,
createRegisterForm,
} from '@/app/actions/subscriptionAction';
@ -37,6 +37,7 @@ import {
createRegistrationSchoolFileTemplate,
createRegistrationParentFileTemplate,
} from '@/app/actions/registerFileGroupAction';
import { fetchProfiles } from '@/app/actions/authAction';
import { useClasses } from '@/context/ClassesContext';
import { useCsrfToken } from '@/context/CsrfContext';
import { FE_ADMIN_SUBSCRIPTIONS_URL } from '@/utils/Url';
@ -46,6 +47,7 @@ export default function CreateSubscriptionPage() {
studentLastName: '',
studentFirstName: '',
studentLevel: '',
studentGender: '',
guardianLastName: '',
guardianFirstName: '',
guardianEmail: '',
@ -60,6 +62,11 @@ export default function CreateSubscriptionPage() {
schoolYear: getCurrentSchoolYear(),
});
const searchParams = useSearchParams();
// Si l'ID est valorisé, alors on est en mode édition
const registerFormID = searchParams.get('id');
const registerFormMoment = searchParams.get('school_year');
const [students, setStudents] = useState([]);
const [registrationDiscounts, setRegistrationDiscounts] = useState([]);
const [tuitionDiscounts, setTuitionDiscounts] = useState([]);
@ -67,16 +74,14 @@ export default function CreateSubscriptionPage() {
const [tuitionFees, setTuitionFees] = useState([]);
const [groups, setGroups] = useState([]);
const [schoolFileMasters, setSchoolFileMasters] = useState([]);
const [parentFileMasters, setParentFileMasters] = useState([]);
const [profiles, setProfiles] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [existingGuardians, setExistingGuardians] = useState([]);
const [totalRegistrationAmount, setTotalRegistrationAmount] = useState(0);
const [totalTuitionAmount, setTotalTuitionAmount] = useState(0);
const [popupVisible, setPopupVisible] = useState(false);
const [popupMessage, setPopupMessage] = useState('');
const [selectedStudent, setSelectedEleve] = useState(null);
const [isNewResponsable, setIsNewResponsable] = useState(true);
@ -122,39 +127,31 @@ export default function CreateSubscriptionPage() {
const getLocalError = (field) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// Extraire tous les guardians des students
const allGuardians = students.flatMap((student) => student.guardians);
if (field === 'guardianEmail') {
if (!formData.guardianEmail || formData.guardianEmail.trim() === '') {
return 'Champs requis';
}
if (
// Student Form
(field === 'schoolYear' &&
(!formData.schoolYear || String(formData.schoolYear).trim() === '')) ||
(field === 'studentLastName' &&
(!formData.studentLastName ||
formData.studentLastName.trim() === '')) ||
(field === 'studentFirstName' &&
(!formData.studentFirstName ||
formData.studentFirstName.trim() === '')) ||
(field === 'guardianEmail' &&
(!formData.guardianEmail ||
formData.guardianEmail.trim() === '' ||
!emailRegex.test(formData.guardianEmail) ||
allGuardians.some(
if (!emailRegex.test(formData.guardianEmail)) {
return 'Email invalide';
}
// Vérifiez si l'email existe déjà, mais ne mettez pas à jour `formData` ici
const existingGuardian = students
.flatMap((student) => student.guardians)
.find(
(guardian) =>
guardian.associated_profile_email === formData.guardianEmail
))) // Vérifie si l'email existe déjà dans la liste des guardians
) {
return field === 'guardianEmail' &&
allGuardians.some(
(guardian) =>
guardian.associated_profile_email === formData.guardianEmail
)
? 'Cet email est déjà associé à un responsable existant'
: 'Champs requis';
);
if (existingGuardian) {
return ''; // Pas d'erreur, mais l'email existe déjà
}
}
return '';
};
const requestErrorHandler = (err) => {
logger.error('Error fetching data:', err);
setErrors(err);
@ -165,7 +162,69 @@ export default function CreateSubscriptionPage() {
}, [formData]);
useEffect(() => {
if (!formData.guardianEmail) {
// Si l'email est vide, réinitialiser existingProfileId
setFormData((prevData) => ({
...prevData,
isExistingParentProfile: false,
existingProfileId: null,
}));
return;
}
// Vérifiez si le profil existe dans la liste des profils
const existingProfile = profiles.find(
(profile) => profile.email === formData.guardianEmail
);
if (existingProfile) {
// Si un profil avec cet email existe, valoriser isExistingParentProfile et existingProfileId
setFormData((prevData) => ({
...prevData,
isExistingParentProfile: true,
existingProfileId: existingProfile.id, // Récupérer l'ID du profil associé
guardianLastName: existingProfile.last_name || '',
guardianFirstName: existingProfile.first_name || '',
guardianPhone: existingProfile.phone || '',
}));
} else {
// Si aucun profil avec cet email n'existe, réinitialiser les champs
setFormData((prevData) => ({
...prevData,
isExistingParentProfile: false,
existingProfileId: null,
}));
}
}, [formData.guardianEmail, profiles]);
useEffect(() => {
fetchProfiles()
.then((data) => {
setProfiles(data);
})
.catch(requestErrorHandler);
if (selectedEstablishmentId) {
if (registerFormID) {
fetchRegisterForm(registerFormID)
.then((data) => {
setFormData((prevData) => ({
...prevData,
studentLastName: data?.student?.last_name || '',
studentFirstName: data?.student?.first_name || '',
studentLevel: data?.student?.level || '',
studentGender: data?.student?.gender || '',
guardianLastName: data?.student?.guardians[0]?.last_name || '',
guardianFirstName: data?.student?.guardians[0]?.first_name || '',
guardianEmail:
data?.student?.guardians[0]?.associated_profile_email || '',
guardianPhone: data?.student?.guardians[0]?.phone || '',
selectedFileGroup: data?.fileGroup || '',
schoolYear: data?.school_year || '',
}));
})
.catch(requestErrorHandler);
}
fetchStudents(selectedEstablishmentId)
.then((studentsData) => {
setStudents(studentsData);
@ -219,6 +278,17 @@ export default function CreateSubscriptionPage() {
}
}, [selectedEstablishmentId]);
useEffect(() => {
if (registrationFees.length > 0) {
const defaultSelectedFees = registrationFees.map((fee) => fee.id);
const totalAmount = calculateFinalRegistrationAmount(
defaultSelectedFees,
formData.selectedRegistrationDiscounts
);
setTotalRegistrationAmount(totalAmount);
}
}, [registrationFees]);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevState) => ({
@ -250,21 +320,22 @@ export default function CreateSubscriptionPage() {
};
const createRF = () => {
logger.debug('createRF formData:', formData);
logger.debug('createRF formData:', formDataRef.current);
// Préparation des données
const selectedRegistrationFeesIds = formData.selectedRegistrationFees.map(
(feeId) => feeId
);
const selectedRegistrationFeesIds =
formDataRef.current.selectedRegistrationFees.map((feeId) => feeId);
const selectedRegistrationDiscountsIds =
formData.selectedRegistrationDiscounts.map((discountId) => discountId);
const selectedTuitionFeesIds = formData.selectedTuitionFees.map(
(feeId) => feeId
);
const selectedTuitionDiscountsIds = formData.selectedTuitionDiscounts.map(
formDataRef.current.selectedRegistrationDiscounts.map(
(discountId) => discountId
);
const selectedFileGroup = formData.selectedFileGroup;
const selectedTuitionFeesIds = formDataRef.current.selectedTuitionFees.map(
(feeId) => feeId
);
const selectedTuitionDiscountsIds =
formDataRef.current.selectedTuitionDiscounts.map(
(discountId) => discountId
);
const selectedFileGroup = formDataRef.current.selectedFileGroup;
const allFeesIds = [
...selectedRegistrationFeesIds,
@ -277,25 +348,31 @@ export default function CreateSubscriptionPage() {
const data = {
student: {
last_name: formData.studentLastName,
first_name: formData.studentFirstName,
level: formData.studentLevel,
gender: formData.studentGender,
guardians: formData.selectedGuardians.length
? formData.selectedGuardians.map((guardianId) => ({ id: guardianId }))
: formData.isExistingParentProfile
last_name: formDataRef.current.studentLastName,
first_name: formDataRef.current.studentFirstName,
...(formDataRef.current.studentLevel && {
level: formDataRef.current.studentLevel,
}),
...(formDataRef.current.studentGender && {
gender: formDataRef.current.studentGender,
}),
guardians: formDataRef.current.selectedGuardians.length
? formDataRef.current.selectedGuardians.map((guardianId) => ({
id: guardianId,
}))
: formDataRef.current.isExistingParentProfile
? [
{
profile_role_data: {
establishment: selectedEstablishmentId,
role_type: 2,
is_active: false,
profile: formData.existingProfileId,
is_active: true,
profile: formDataRef.current.existingProfileId,
},
last_name: formData.guardianLastName,
first_name: formData.guardianFirstName,
birth_date: formData.guardianBirthDate,
phone: formData.guardianPhone,
last_name: formDataRef.current.guardianLastName,
first_name: formDataRef.current.guardianFirstName,
birth_date: formDataRef.current.guardianBirthDate,
phone: formDataRef.current.guardianPhone,
},
]
: [
@ -305,14 +382,14 @@ export default function CreateSubscriptionPage() {
role_type: 2,
is_active: false,
profile_data: {
email: formData.guardianEmail,
email: formDataRef.current.guardianEmail,
password: 'Provisoire01!',
username: formData.guardianEmail,
username: formDataRef.current.guardianEmail,
},
},
last_name: formData.guardianLastName,
first_name: formData.guardianFirstName,
phone: formData.guardianPhone,
last_name: formDataRef.current.guardianLastName,
first_name: formDataRef.current.guardianFirstName,
phone: formDataRef.current.guardianPhone,
},
],
sibling: [],
@ -321,7 +398,7 @@ export default function CreateSubscriptionPage() {
discounts: allDiscountsIds,
fileGroup: selectedFileGroup,
establishment: selectedEstablishmentId,
school_year: formData.schoolYear,
school_year: formDataRef.current.schoolYear,
};
setIsLoading(true);
@ -590,9 +667,19 @@ export default function CreateSubscriptionPage() {
return finalAmount.toFixed(2);
};
if (isLoading === true) {
return <Loader />; // Affichez le composant Loader
}
return (
<div className="container mx-auto max-w-8xl space-y-12">
{registerFormID ? (
<h1 className="text-2xl font-bold">
Modifier un dossier d'inscription
</h1>
) : (
<h1 className="text-2xl font-bold">Créer un dossier d'inscription</h1>
)}
{/* Sélection de l'année scolaire */}
<div className="grid grid-cols-1 md:grid-cols-5 gap-8">
@ -1000,7 +1087,7 @@ export default function CreateSubscriptionPage() {
{/* Bouton de soumission */}
<div className="flex justify-end">
<Button
text="Créer le dossier"
text={`${registerFormID ? 'Modifier' : 'Créer'} le dossier`}
onClick={createRF}
className={`px-6 py-2 rounded-md shadow ${
isSubmitDisabled()

View File

@ -12,7 +12,8 @@ import Loader from '@/components/Loader';
export default function Page() {
const router = useRouter();
const searchParams = useSearchParams();
const studentId = searchParams.get('studentId'); // Changé de codeDI à studentId
const studentId = searchParams.get('studentId');
const enable = searchParams.get('enabled') === 'true';
const [formErrors, setFormErrors] = useState({});
const csrfToken = useCsrfToken();
@ -49,6 +50,7 @@ export default function Page() {
onSubmit={handleSubmit}
cancelUrl={FE_ADMIN_SUBSCRIPTIONS_URL}
errors={formErrors}
enable={enable}
/>
);
}

View File

@ -6,12 +6,9 @@ import { useTranslations } from 'next-intl';
import StatusLabel from '@/components/StatusLabel';
import Popup from '@/components/Popup';
import Loader from '@/components/Loader';
import AlertWithModal from '@/components/AlertWithModal';
import { useRouter } from 'next/navigation';
import DropdownMenu from '@/components/DropdownMenu';
import {
Search,
MoreVertical,
Send,
Edit,
Archive,
@ -19,14 +16,12 @@ import {
CheckCircle,
Plus,
Upload,
Eye,
} from 'lucide-react';
import Modal from '@/components/Modal';
import { useEstablishment } from '@/context/EstablishmentContext';
import {
CURRENT_YEAR,
NEXT_YEAR,
HISTORICAL,
fetchRegisterForms,
sendRegisterForm,
archiveRegisterForm,
@ -34,9 +29,7 @@ import {
editRegisterFormWithBinaryFile,
} from '@/app/actions/subscriptionAction';
import { fetchClasses, updateDatas } from '@/app/actions/schoolAction';
import { fetchProfiles } from '@/app/actions/authAction';
import { fetchClasses } from '@/app/actions/schoolAction';
import {
FE_ADMIN_SUBSCRIPTIONS_EDIT_URL,
@ -51,11 +44,14 @@ import logger from '@/utils/logger';
import { PhoneLabel } from '@/components/PhoneLabel';
import FileUpload from '@/components/FileUpload';
import FilesModal from '@/components/Inscription/FilesModal';
import { getCurrentSchoolYear, getNextSchoolYear } from '@/utils/Date';
import {
getCurrentSchoolYear,
getNextSchoolYear,
getHistoricalYears,
} from '@/utils/Date';
RegistrationFormStatus,
CURRENT_YEAR,
NEXT_YEAR,
HISTORICAL,
} from '@/utils/constants';
export default function Page({ params: { locale } }) {
const t = useTranslations('subscriptions');
@ -68,9 +64,8 @@ export default function Page({ params: { locale } }) {
useState([]);
const [registrationFormsDataHistorical, setRegistrationFormsDataHistorical] =
useState([]);
const currentSchoolYear = getCurrentSchoolYear(); // Exemple : "2024-2025"
const nextSchoolYear = getNextSchoolYear(); // Exemple : "2025-2026"
const historicalYears = getHistoricalYears();
const currentSchoolYear = getCurrentSchoolYear();
const nextSchoolYear = getNextSchoolYear();
const [totalCurrentSchoolYearPages, setTotalCurrentSchoolYearPages] =
useState(1);
const [totalNextSchoolYearPages, setTotalNextSchoolYearPages] = useState(1);
@ -81,7 +76,7 @@ export default function Page({ params: { locale } }) {
useState(1);
const [searchTerm, setSearchTerm] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [activeTab, setActiveTab] = useState('currentYear');
const [activeTab, setActiveTab] = useState(CURRENT_YEAR);
const [totalCurrentYear, setTotalCurrentYear] = useState(0);
const [totalNextYear, setTotalNextYear] = useState(0);
const [totalHistorical, setTotalHistorical] = useState(0);
@ -91,7 +86,6 @@ export default function Page({ params: { locale } }) {
const [classes, setClasses] = useState([]);
const [reloadFetch, setReloadFetch] = useState(false);
const [profiles, setProfiles] = useState([]);
const [isOpenAddGuardian, setIsOpenAddGuardian] = useState(false);
const [isFilesModalOpen, setIsFilesModalOpen] = useState(false);
@ -217,13 +211,6 @@ export default function Page({ params: { locale } }) {
fetchRegisterForms(selectedEstablishmentId, HISTORICAL)
.then(registerFormHistoricalDataHandler)
.catch(requestErrorHandler),
fetchProfiles()
.then((data) => {
setProfiles(data);
})
.catch((error) => {
logger.error('Error fetching profileRoles:', error);
}),
])
.then(() => {
setIsLoading(false);
@ -275,13 +262,13 @@ export default function Page({ params: { locale } }) {
* UseEffect to update page count of tab
*/
useEffect(() => {
if (activeTab === 'currentYear') {
if (activeTab === CURRENT_YEAR) {
setTotalCurrentSchoolYearPages(
Math.ceil(totalCurrentYear / itemsPerPage)
);
} else if (activeTab === 'nextYear') {
} else if (activeTab === NEXT_YEAR) {
setTotalNextSchoolYearPages(Math.ceil(totalNextYear / itemsPerPage));
} else if (activeTab === 'historical') {
} else if (activeTab === HISTORICAL) {
setTotalHistoricalPages(Math.ceil(totalHistorical / itemsPerPage));
}
}, [currentSchoolYearPage]);
@ -390,7 +377,13 @@ export default function Page({ params: { locale } }) {
};
const handlePageChange = (newPage) => {
if (activeTab === CURRENT_YEAR) {
setCurrentSchoolYearPage(newPage);
} else if (activeTab === NEXT_YEAR) {
setCurrentSchoolNextYearPage(newPage);
} else if (activeTab === HISTORICAL) {
setCurrentSchoolHistoricalYearPage(newPage);
}
};
const updateRF = (updatedData) => {
@ -475,7 +468,22 @@ export default function Page({ params: { locale } }) {
const getActionsByStatus = (row) => {
const actions = {
1: [
// Etat "A envoyer" :
// - Editer le formulaire de création
// - Envoyer le formulaire aux parents
// - Archiver le dossier
[RegistrationFormStatus.STATUS_TO_SEND]: [
{
icon: (
<span title="Editer le formulaire de création">
<Edit className="w-5 h-5 text-blue-500 hover:text-blue-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_CREATE_URL}?id=${row.student.id}&school_year=${activeTab}`
),
},
{
icon: (
<span title="Envoyer le dossier">
@ -490,7 +498,42 @@ export default function Page({ params: { locale } }) {
),
},
],
2: [
// Etat "En attente" :
// - Editer le formulaire de création
// - Renvoyer le formulaire aux parents
// - Archiver le dossier
[RegistrationFormStatus.STATUS_PENDING]: [
{
icon: (
<span title="Editer le formulaire de création">
<Edit className="w-5 h-5 text-blue-500 hover:text-blue-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_CREATE_URL}?id=${row.student.id}&school_year=${activeTab}`
),
},
{
icon: (
<span title="Renvoyer le dossier">
<Send className="w-5 h-5 text-green-500 hover:text-green-700" />
</span>
),
onClick: () =>
sendConfirmRegisterForm(
row.student.id,
row.student.last_name,
row.student.first_name
),
},
],
// Etat "Signé" :
// - Editer le formulaire d'inscription
// - Visualiser les documents signés par les parents
// - Valider le dossier d'inscription
// - Archiver le dossier
[RegistrationFormStatus.STATUS_TO_VALIDATE]: [
{
icon: (
<span title="Editer le dossier">
@ -499,11 +542,9 @@ export default function Page({ params: { locale } }) {
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}`
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&enabled=true`
),
},
],
3: [
{
icon: (
<span title="Voir les fichiers">
@ -524,7 +565,27 @@ export default function Page({ params: { locale } }) {
},
},
],
5: [
// Etat "A relancer" - NON TESTE
[RegistrationFormStatus.STATUS_TO_FOLLOW_UP]: [
// To do...
],
// Etat "Validé" :
// - Editer le formulaire d'inscription
// - Visualiser les documents signés par les parents
// - A ajouter : Action pour éditer le suivi de l'élève
// - Archiver le dossier
[RegistrationFormStatus.STATUS_VALIDATED]: [
{
icon: (
<span title="Editer le dossier">
<Edit className="w-5 h-5 text-blue-500 hover:text-blue-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&enabled=true`
),
},
{
icon: (
<span title="Voir les fichiers">
@ -534,7 +595,37 @@ export default function Page({ params: { locale } }) {
onClick: () => openFilesModal(row),
},
],
7: [
// Etat "Archivé"
// - Editer le formulaire d'inscription en lecture seule
[RegistrationFormStatus.STATUS_ARCHIVED]: [
{
icon: (
<span title="Editer le dossier">
<Eye className="w-5 h-5 text-purple-500 hover:text-purple-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&enabled=false`
),
},
],
// Etat "En attente de signature de SEPA" :
// - Editer le formulaire d'inscription
// - Visualiser les documents signés par les parents
// - Archiver le dossier
[RegistrationFormStatus.STATUS_SEPA_PENDING]: [
{
icon: (
<span title="Editer le dossier">
<Edit className="w-5 h-5 text-blue-500 hover:text-blue-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&enabled=true`
),
},
{
icon: (
<span title="Voir les fichiers">
@ -544,7 +635,23 @@ export default function Page({ params: { locale } }) {
onClick: () => openFilesModal(row),
},
],
8: [
// Etat "SEPA à envoyer" :
// - Editer le formulaire d'inscription
// - Visualiser les documents signés par les parents
// - Envoyer le mandat SEPA aux parents
// - Archiver le dossier
[RegistrationFormStatus.STATUS_SEPA_TO_SEND]: [
{
icon: (
<span title="Editer le dossier">
<Edit className="w-5 h-5 text-blue-500 hover:text-blue-700" />
</span>
),
onClick: () =>
router.push(
`${FE_ADMIN_SUBSCRIPTIONS_EDIT_URL}?studentId=${row.student.id}&enabled=true`
),
},
{
icon: (
<span title="Voir les fichiers">
@ -566,7 +673,7 @@ export default function Page({ params: { locale } }) {
{
icon: (
<span title="Archiver le dossier">
<Archive className="w-5 h-5 text-gray-500 hover:text-gray-700" />
<Archive className="w-5 h-5 text-red-500 hover:text-red-700" />
</span>
),
onClick: () =>
@ -625,9 +732,10 @@ export default function Page({ params: { locale } }) {
},
{
name: t('phone'),
transform: (row) => (
transform: (row) =>
row.student.guardians[0]?.phone ? (
<PhoneLabel phoneNumber={row.student.guardians[0]?.phone} />
),
) : null, // N'affiche rien si le numéro de téléphone est absent
},
{
name: t('lastUpdateDate'),
@ -683,8 +791,8 @@ export default function Page({ params: { locale } }) {
</span>
</>
}
active={activeTab === 'currentYear'}
onClick={() => setActiveTab('currentYear')}
active={activeTab === CURRENT_YEAR}
onClick={() => setActiveTab(CURRENT_YEAR)}
/>
{/* Tab pour l'année scolaire prochaine */}
@ -697,8 +805,8 @@ export default function Page({ params: { locale } }) {
</span>
</>
}
active={activeTab === 'nextYear'}
onClick={() => setActiveTab('nextYear')}
active={activeTab === NEXT_YEAR}
onClick={() => setActiveTab(NEXT_YEAR)}
/>
{/* Tab pour l'historique */}
@ -711,16 +819,16 @@ export default function Page({ params: { locale } }) {
</span>
</>
}
active={activeTab === 'historical'}
onClick={() => setActiveTab('historical')}
active={activeTab === HISTORICAL}
onClick={() => setActiveTab(HISTORICAL)}
/>
</div>
</div>
<div className="border-b border-gray-200 mb-6 w-full">
{activeTab === 'currentYear' ||
activeTab === 'nextYear' ||
activeTab === 'historical' ? (
{activeTab === CURRENT_YEAR ||
activeTab === NEXT_YEAR ||
activeTab === HISTORICAL ? (
<React.Fragment>
<div className="flex justify-between items-center mb-4 w-full">
<div className="relative flex-grow">
@ -752,25 +860,25 @@ export default function Page({ params: { locale } }) {
<Table
key={`${currentSchoolYearPage}-${searchTerm}`}
data={
activeTab === 'currentYear'
activeTab === CURRENT_YEAR
? registrationFormsDataCurrentYear
: activeTab === 'nextYear'
: activeTab === NEXT_YEAR
? registrationFormsDataNextYear
: registrationFormsDataHistorical
}
columns={columns}
itemsPerPage={itemsPerPage}
currentPage={
activeTab === 'currentYear'
activeTab === CURRENT_YEAR
? currentSchoolYearPage
: activeTab === 'nextYear'
: activeTab === NEXT_YEAR
? currentSchoolNextYearPage
: currentSchoolHistoricalYearPage
}
totalPages={
activeTab === 'currentYear'
activeTab === CURRENT_YEAR
? totalCurrentSchoolYearPages
: activeTab === 'nextYear'
: activeTab === NEXT_YEAR
? totalNextSchoolYearPages
: totalHistoricalPages
}

View File

@ -5,7 +5,7 @@ import Table from '@/components/Table';
import { Edit3, Users, Download, Eye, Upload } from 'lucide-react';
import StatusLabel from '@/components/StatusLabel';
import FileUpload from '@/components/FileUpload';
import { FE_PARENTS_EDIT_INSCRIPTION_URL } from '@/utils/Url';
import { FE_PARENTS_EDIT_SUBSCRIPTION_URL } from '@/utils/Url';
import {
fetchChildren,
editRegisterFormWithBinaryFile,
@ -38,14 +38,14 @@ export default function ParentHomePage() {
function handleView(eleveId) {
logger.debug(`View dossier for student id: ${eleveId}`);
router.push(
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?studentId=${eleveId}&enabled=false`
`${FE_PARENTS_EDIT_SUBSCRIPTION_URL}?studentId=${eleveId}&enabled=false`
);
}
function handleEdit(eleveId) {
logger.debug(`Edit dossier for student id: ${eleveId}`);
router.push(
`${FE_PARENTS_EDIT_INSCRIPTION_URL}?studentId=${eleveId}&enabled=true`
`${FE_PARENTS_EDIT_SUBSCRIPTION_URL}?studentId=${eleveId}&enabled=true`
);
}

View File

@ -106,6 +106,7 @@ export default function Page() {
router.push(`${FE_USERS_LOGIN_URL}`);
}}
onCancel={() => setPopupVisible(false)}
uniqueConfirmButton={true}
/>
<div className="container max mx-auto p-4">
<div className="flex justify-center mb-4">

View File

@ -14,7 +14,6 @@ import { FE_USERS_LOGIN_URL } from '@/utils/Url';
import { useCsrfToken } from '@/context/CsrfContext';
import { subscribe } from '@/app/actions/authAction';
import logger from '@/utils/logger';
import { useEstablishment } from '@/context/EstablishmentContext';
export default function Page() {
const searchParams = useSearchParams();
@ -43,6 +42,7 @@ export default function Page() {
password2: formData.get('password2'),
establishment_id: establishment_id,
};
setIsLoading(true);
subscribe(data, csrfToken)
.then((data) => {
logger.debug('Success:', data);
@ -51,9 +51,11 @@ export default function Page() {
setPassword2FieldError('');
setErrorMessage('');
if (isOK(data)) {
setIsLoading(false);
setPopupMessage(data.message);
setPopupVisible(true);
} else {
setIsLoading(false);
if (data.errorMessage) {
setErrorMessage(data.errorMessage);
}
@ -65,6 +67,7 @@ export default function Page() {
}
})
.catch((error) => {
setIsLoading(false);
logger.error('Error fetching data:', error);
error = error.errorMessage;
logger.debug(error);
@ -148,6 +151,7 @@ export default function Page() {
router.push(`${FE_USERS_LOGIN_URL}`);
}}
onCancel={() => setPopupVisible(false)}
uniqueConfirmButton={true}
/>
</>
);

View File

@ -6,9 +6,7 @@ import {
BE_SUBSCRIPTION_ABSENCES_URL,
} from '@/utils/Url';
export const CURRENT_YEAR = 'current_year';
export const NEXT_YEAR = 'next_year';
export const HISTORICAL = 'historical';
import { CURRENT_YEAR, NEXT_YEAR, HISTORICAL } from '@/utils/constants';
const requestResponseHandler = async (response) => {
const body = await response.json();

View File

@ -69,7 +69,7 @@ export const FE_ADMIN_HOME_URL = `/admin`;
// ADMIN/SUBSCRIPTIONS URL
export const FE_ADMIN_SUBSCRIPTIONS_URL = `/admin/subscriptions`;
export const FE_ADMIN_SUBSCRIPTIONS_CREATE_URL = `/admin/subscriptions/createSubscription`;
export const FE_ADMIN_SUBSCRIPTIONS_EDIT_URL = `/admin/subscriptions/editInscription`;
export const FE_ADMIN_SUBSCRIPTIONS_EDIT_URL = `/admin/subscriptions/editSubscription`;
export const FE_ADMIN_SUBSCRIPTIONS_VALIDATE_URL = `/admin/subscriptions/validateSubscription`;
//ADMIN/CLASSES URL
@ -98,7 +98,7 @@ export const FE_ADMIN_SETTINGS_URL = `/admin/settings`;
export const FE_PARENTS_HOME_URL = `/parents`;
export const FE_PARENTS_MESSAGERIE_URL = `/parents/messagerie`;
export const FE_PARENTS_SETTINGS_URL = `/parents/settings`;
export const FE_PARENTS_EDIT_INSCRIPTION_URL = `/parents/editInscription`;
export const FE_PARENTS_EDIT_SUBSCRIPTION_URL = `/parents/editSubscription`;
// API DOCUSEAL
export const FE_API_DOCUSEAL_GENERATE_TOKEN = `/api/docuseal/generateToken`;

View File

@ -14,3 +14,18 @@ export const genders = [
{ value: '1', label: 'Garçon' },
{ value: '2', label: 'Fille' },
];
export const RegistrationFormStatus = {
STATUS_TO_SEND: 1,
STATUS_PENDING: 2,
STATUS_TO_VALIDATE: 3,
STATUS_TO_FOLLOW_UP: 4, // Non testé
STATUS_VALIDATED: 5,
STATUS_ARCHIVED: 6,
STATUS_SEPA_PENDING: 7,
STATUS_SEPA_TO_SEND: 8,
};
export const CURRENT_YEAR = 'current_year';
export const NEXT_YEAR = 'next_year';
export const HISTORICAL = 'historical';