chore: Application du linter

This commit is contained in:
Luc SORIGNET
2025-05-12 10:34:47 +02:00
parent 23a593dbc7
commit 425e6d73e5
56 changed files with 1140 additions and 1469 deletions

View File

@ -0,0 +1 @@
cd $(dirname "$0")/../Front-End/ && npm run lint-light

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"eslint.workingDirectories": ["./Front-End"]
}

View File

@ -50,6 +50,8 @@ class SendEmailView(APIView):
def post(self, request):
data = request.data
recipients = data.get('recipients', [])
cc = data.get('cc', [])
bcc = data.get('bcc', [])
subject = data.get('subject', 'Notification')
message = data.get('message', '')
establishment_id = data.get('establishment_id', '')
@ -63,9 +65,12 @@ class SendEmailView(APIView):
# Envoyer l'email
return mailer.sendMail(
recipients=recipients,
subject=subject,
message=message,
recipients=recipients,
cc=cc,
bcc=bcc,
attachments=[],
connection=connection
)
except NotFound as e:

View File

@ -34,14 +34,31 @@ def getConnection(id_establishement):
raise NotFound(f"Aucun paramètre SMTP trouvé pour l'établissement {id_establishement}")
def sendMail(recipients, subject, message, connection=None):
def sendMail(subject, message, recipients, cc=[], bcc=[], attachments=[], connection=None):
try:
plain_message = strip_tags(message)
from_email = settings.EMAIL_HOST_USER
if connection is None:
send_mail(subject, plain_message, from_email, recipients, html_message=message, fail_silently=False)
else:
send_mail(subject, plain_message, from_email, recipients, html_message=message, connection=connection, fail_silently=False)
if connection is not None:
from_email = connection.username
email = EmailMultiAlternatives(
subject=subject,
body=plain_message,
from_email=from_email,
to=recipients,
cc=cc,
bcc=bcc,
connection=connection
)
email.attach_alternative(message, "text/html")
# Ajout des pièces jointes
for attachment in attachments:
# attachment doit être un tuple (filename, content, mimetype)
# ex: ("document.pdf", fichier.read(), "application/pdf")
email.attach(*attachment)
email.send(fail_silently=False)
return Response({'message': 'Email envoyé avec succès.'}, status=status.HTTP_200_OK)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@ -56,7 +73,7 @@ def envoieReinitMotDePasse(recipients, code):
}
subject = EMAIL_REINIT_SUBJECT
html_message = render_to_string('emails/resetPassword.html', context)
sendMail(recipients, subject, html_message)
sendMail(subject, html_message, recipients)
except Exception as e:
errorMessage = str(e)
@ -77,7 +94,7 @@ def sendRegisterForm(recipients, establishment_id):
subject = EMAIL_INSCRIPTION_SUBJECT
html_message = render_to_string('emails/inscription.html', context)
sendMail(recipients, subject, html_message)
sendMail(subject, html_message, recipients)
except Exception as e:
@ -98,7 +115,7 @@ def sendMandatSEPA(recipients, establishment_id):
subject = EMAIL_INSCRIPTION_SUBJECT
html_message = render_to_string('emails/sepa.html', context)
sendMail(recipients, subject, html_message)
sendMail(subject, html_message, recipients)
except Exception as e:
errorMessage = str(e)
@ -110,7 +127,7 @@ def envoieRelanceDossierInscription(recipients, code):
EMAIL_RELANCE_CORPUS = 'Bonjour,\nN\'ayant pas eu de retour de votre part, nous vous renvoyons le lien vers le formulaire d\'inscription : ' + BASE_URL + '/users/login\nCordialement'
errorMessage = ''
try:
sendMail(recipients, EMAIL_RELANCE_SUBJECT, EMAIL_RELANCE_CORPUS%str(code))
sendMail(EMAIL_RELANCE_SUBJECT, EMAIL_RELANCE_CORPUS%str(code), recipients)
except Exception as e:
errorMessage = str(e)

4
Front-End/.babelrc Normal file
View File

@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": []
}

3
Front-End/.eslintignore Normal file
View File

@ -0,0 +1,3 @@
node_modules/
build/
public/

View File

@ -1,3 +1,10 @@
{
"extends": "next/core-web-vitals"
"extends": ["next", "next/core-web-vitals"],
"rules": {
// Ajoutez vos règles personnalisées ici
"react/react-in-jsx-scope": "off", // Désactive l'obligation d'importer React
"no-console": "error", // Avertissement pour les console.log
"semi": ["error", "always"], // Exige un point-virgule à la fin des lignes
"quotes": ["error", "single", { "avoidEscape": true }] // Exige des guillemets simples, sauf si l'on utilise des guillemets doubles à l'intérieur
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint-light": "next lint --quiet",
"check-strings": "node scripts/check-hardcoded-strings.js"
},
"dependencies": {
@ -34,8 +35,6 @@
"react-tooltip": "^5.28.0"
},
"devDependencies": {
"@babel/parser": "^7.26.2",
"@babel/traverse": "^7.25.9",
"autoprefixer": "^10.4.20",
"eslint": "^8",
"eslint-config-next": "14.2.11",

View File

@ -3,6 +3,7 @@ import React, { useState } from 'react';
import SelectChoice from '@/components/SelectChoice';
import Button from '@/components/Button';
import Table from '@/components/Table';
import logger from '@/utils/logger';
export default function Page() {
const [formData, setFormData] = useState({
@ -132,7 +133,7 @@ export default function Page() {
<div className="mt-4">
<Button
text="Enregistrer"
onClick={() => console.log('FormData:', formData)}
onClick={() => logger.debug('FormData:', formData)}
primary
className="bg-emerald-500 text-white hover:bg-emerald-600"
/>

View File

@ -4,6 +4,7 @@ import SidebarTabs from '@/components/SidebarTabs';
import EmailSender from '@/components/Admin/EmailSender';
import InstantMessaging from '@/components/Admin/InstantMessaging';
import AnnouncementScheduler from '@/components/Admin/AnnouncementScheduler';
import logger from '@/utils/logger';
export default function MessageriePage({ csrfToken }) {
const tabs = [
@ -28,7 +29,7 @@ export default function MessageriePage({ csrfToken }) {
<div className="flex h-full w-full">
<SidebarTabs
tabs={tabs}
onTabChange={(tabId) => console.log(`Onglet actif : ${tabId}`)}
onTabChange={(tabId) => logger.debug(`Onglet actif : ${tabId}`)}
/>
</div>
);

View File

@ -13,6 +13,7 @@ import {
import { useEstablishment } from '@/context/EstablishmentContext';
import { useCsrfToken } from '@/context/CsrfContext'; // Import du hook pour récupérer le csrfToken
import { useNotification } from '@/context/NotificationContext';
import { useSearchParams } from 'next/navigation'; // Ajoute cet import
export default function SettingsPage() {
const [activeTab, setActiveTab] = useState('structure');
@ -28,10 +29,22 @@ export default function SettingsPage() {
const { selectedEstablishmentId } = useEstablishment();
const csrfToken = useCsrfToken(); // Récupération du csrfToken
const { showNotification } = useNotification();
const searchParams = useSearchParams();
const handleTabClick = (tab) => {
setActiveTab(tab);
};
// Ajout : sélection automatique de l'onglet via l'ancre ou le paramètre de recherche
useEffect(() => {
const tabParam = searchParams.get('tab');
if (tabParam === 'smtp') {
setActiveTab('smtp');
} else if (tabParam === 'structure') {
setActiveTab('structure');
}
}, [searchParams]);
// Charger les paramètres SMTP existants
useEffect(() => {
if (activeTab === 'smtp') {
@ -45,12 +58,23 @@ export default function SettingsPage() {
setUseSsl(data.use_ssl || false);
})
.catch((error) => {
logger.error('Erreur lors du chargement des paramètres SMTP:', error);
if (error.response && error.response.status === 404) {
showNotification(
"Les données SMTP n'ont pas été trouvées.",
'warning',
'Attention'
);
} else {
logger.error(
'Erreur lors du chargement des paramètres SMTP:',
error
);
showNotification(
'Erreur lors du chargement des paramètres SMTP.',
'error',
'Erreur'
);
}
});
}
}, [activeTab, csrfToken]); // Ajouter csrfToken comme dépendance

View File

@ -151,7 +151,7 @@ export default function Page() {
// Envoyer les absences modifiées à une API
absencesToUpdate.forEach(([studentId, absenceData]) => {
console.log('Modification absence élève : ', studentId);
logger.debug('Modification absence élève : ', studentId);
saveAbsence(studentId, absenceData);
});
@ -203,7 +203,7 @@ export default function Page() {
// Appeler la fonction pour supprimer l'absence
deleteAbsences(existingAbsence.id, csrfToken)
.then(() => {
console.log(
logger.debug(
`Absence pour l'élève ${studentId} supprimée avec succès.`
);
// Mettre à jour les absences récupérées
@ -214,7 +214,7 @@ export default function Page() {
});
})
.catch((error) => {
console.error(
logger.error(
`Erreur lors de la suppression de l'absence pour l'élève ${studentId}:`,
error
);
@ -235,7 +235,7 @@ export default function Page() {
const saveAbsence = (studentId, absenceData) => {
if (!absenceData.reason || !studentId || !absenceData.moment) {
console.error('Tous les champs requis doivent être fournis.');
logger.error('Tous les champs requis doivent être fournis.');
return;
}
@ -251,7 +251,7 @@ export default function Page() {
// Modifier une absence existante
editAbsences(absenceData.id, payload, csrfToken)
.then(() => {
console.log(
logger.debug(
`Absence pour l'élève ${studentId} modifiée avec succès.`
);
// Mettre à jour fetchedAbsences et formAbsences localement
@ -265,7 +265,7 @@ export default function Page() {
}));
})
.catch((error) => {
console.error(
logger.error(
`Erreur lors de la modification de l'absence pour l'élève ${studentId}:`,
error
);
@ -274,7 +274,7 @@ export default function Page() {
// Créer une nouvelle absence
createAbsences(payload, csrfToken)
.then((response) => {
console.log(`Absence pour l'élève ${studentId} créée avec succès.`);
logger.debug(`Absence pour l'élève ${studentId} créée avec succès.`);
// Mettre à jour fetchedAbsences et formAbsences localement
setFetchedAbsences((prev) => ({
...prev,
@ -286,7 +286,7 @@ export default function Page() {
}));
})
.catch((error) => {
console.error(
logger.error(
`Erreur lors de la création de l'absence pour l'élève ${studentId}:`,
error
);

View File

@ -385,14 +385,14 @@ export default function CreateSubscriptionPage() {
const guardians = (() => {
if (formDataRef.current.selectedGuardians.length > 0) {
// Cas 3 : Des guardians sont sélectionnés
console.log('Cas 3 : Des guardians sont sélectionnés');
logger.debug('Cas 3 : Des guardians sont sélectionnés');
return formDataRef.current.selectedGuardians.map((guardianId) => ({
id: guardianId,
}));
} else if (formDataRef.current.isExistingParentProfile) {
if (initialGuardianEmail !== existingProfile?.email) {
// Cas 2 : Profil existant différent de l'ancien
console.log(
logger.debug(
"Cas 2 : Profil existant différent de l'ancien, mise à jour du profil",
{
existingProfile,
@ -415,14 +415,14 @@ export default function CreateSubscriptionPage() {
];
} else {
// Cas 4 : Profil existant avec le même email
console.log('Cas 4 : Profil existant avec le même email', {
logger.debug('Cas 4 : Profil existant avec le même email', {
existingProfile,
});
return [];
}
} else {
// Cas 1 : Profil inexistant
console.log("Cas 1 : Profil inexistant, création d'un nouveau profil");
logger.debug("Cas 1 : Profil inexistant, création d'un nouveau profil");
return [
{
profile_role_data: {
@ -444,7 +444,7 @@ export default function CreateSubscriptionPage() {
}
})();
console.log('test : ', guardians);
logger.debug('test : ', guardians);
const data = {
student: {
@ -763,10 +763,12 @@ export default function CreateSubscriptionPage() {
<div className="mx-auto p-12 space-y-12">
{registerFormID ? (
<h1 className="text-2xl font-bold">
Modifier un dossier d'inscription
Modifier un dossier d&apos;inscription
</h1>
) : (
<h1 className="text-2xl font-bold">Créer un dossier d'inscription</h1>
<h1 className="text-2xl font-bold">
Créer un dossier d&apos;inscription
</h1>
)}
{/* Sélection de l'année scolaire */}
@ -1047,7 +1049,7 @@ export default function CreateSubscriptionPage() {
{/* Montant total */}
<div className="flex items-center justify-between bg-gray-50 p-4 rounded-lg shadow-sm border border-gray-300 mt-4">
<span className="text-sm font-medium text-gray-600">
Montant total des frais d'inscription :
Montant total des frais d&apos;inscription :
</span>
<span className="text-lg font-semibold text-gray-800">
{totalRegistrationAmount}

View File

@ -321,7 +321,7 @@ export default function Page({ params: { locale } }) {
.then((data) => {
logger.debug('Success:', data);
setPopupMessage(
`Le dossier d'inscription a été correctement archivé`
"Le dossier d'inscription a été correctement archivé"
);
setPopupVisible(true);
setRegistrationForms(
@ -332,7 +332,7 @@ export default function Page({ params: { locale } }) {
.catch((error) => {
logger.error('Error archiving data:', error);
setPopupMessage(
`Erreur lors de l'archivage du dossier d'inscription.\nContactez l'administrateur.`
"Erreur lors de l'archivage du dossier d'inscription.\nContactez l'administrateur."
);
setPopupVisible(true);
});
@ -349,14 +349,14 @@ export default function Page({ params: { locale } }) {
sendRegisterForm(id)
.then((data) => {
logger.debug('Success:', data);
setPopupMessage(`Le dossier d'inscription a été envoyé avec succès`);
setPopupMessage("Le dossier d'inscription a été envoyé avec succès");
setPopupVisible(true);
setReloadFetch(true);
})
.catch((error) => {
logger.error('Error archiving data:', error);
setPopupMessage(
`Erreur lors de l'envoi du dossier d'inscription.\nContactez l'administrateur.`
"Erreur lors de l'envoi du dossier d'inscription.\nContactez l'administrateur."
);
setPopupVisible(true);
});

View File

@ -0,0 +1,31 @@
import logger from '@/utils/logger';
/**
*
* @param {*} response
* @returns
*/
export const requestResponseHandler = async (response) => {
try {
const body = await response?.json();
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
error.response = response;
throw error;
} catch (error) {
logger.error('Une erreur est survenue lors du traitement de la réponse', {
error,
response,
});
throw error;
}
};
export const errorHandler = (error) => {
logger.error('Error:', { error });
// Handle the error here, e.g., show a notification
throw error;
};

View File

@ -1,4 +1,5 @@
import { signOut, signIn, getSession } from 'next-auth/react';
import { signOut, signIn } from 'next-auth/react';
import { errorHandler, requestResponseHandler } from './actionsHandlers';
import {
BE_AUTH_LOGIN_URL,
BE_AUTH_REFRESH_JWT_URL,
@ -11,17 +12,6 @@ import {
} from '@/utils/Url';
import { PARENT_FILTER } from '@/utils/constants';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
throw error;
};
/**
* Login action
*/
@ -46,7 +36,7 @@ export const getJWT = (data) => {
body: JSON.stringify(data),
credentials: 'include',
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const refreshJWT = (data) => {
const request = new Request(`${BE_AUTH_REFRESH_JWT_URL}`, {
@ -57,7 +47,7 @@ export const refreshJWT = (data) => {
body: JSON.stringify(data),
credentials: 'include',
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
/**
@ -87,7 +77,9 @@ export const fetchProfileRoles = (
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const updateProfileRoles = (id, data, csrfToken) => {
@ -100,7 +92,7 @@ export const updateProfileRoles = (id, data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const deleteProfileRoles = async (id, csrfToken) => {
@ -127,7 +119,9 @@ export const deleteProfileRoles = async (id, csrfToken) => {
};
export const fetchProfiles = () => {
return fetch(`${BE_AUTH_PROFILES_URL}`).then(requestResponseHandler);
return fetch(`${BE_AUTH_PROFILES_URL}`)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createProfile = (data, csrfToken) => {
@ -140,7 +134,7 @@ export const createProfile = (data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const deleteProfile = (id, csrfToken) => {
@ -151,7 +145,7 @@ export const deleteProfile = (id, csrfToken) => {
},
credentials: 'include',
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const updateProfile = (id, data, csrfToken) => {
@ -164,7 +158,7 @@ export const updateProfile = (id, data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const sendNewPassword = (data, csrfToken) => {
@ -177,7 +171,7 @@ export const sendNewPassword = (data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const subscribe = (data, csrfToken) => {
@ -190,7 +184,7 @@ export const subscribe = (data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const resetPassword = (uuid, data, csrfToken) => {
@ -203,7 +197,7 @@ export const resetPassword = (uuid, data, csrfToken) => {
credentials: 'include',
body: JSON.stringify(data),
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const getResetPassword = (uuid) => {
@ -212,5 +206,7 @@ export const getResetPassword = (uuid) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -3,23 +3,16 @@ import {
BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL,
BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL,
} from '@/utils/Url';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
throw error;
};
import { errorHandler, requestResponseHandler } from './actionsHandlers';
export const fetchMessages = (id) => {
return fetch(`${BE_GESTIONMESSAGERIE_MESSAGES_URL}/${id}`, {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const sendMessage = (data, csrfToken) => {
@ -30,7 +23,9 @@ export const sendMessage = (data, csrfToken) => {
'X-CSRFToken': csrfToken,
},
body: JSON.stringify(data),
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const searchRecipients = (establishmentId, query) => {
@ -40,5 +35,7 @@ export const searchRecipients = (establishmentId, query) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -1,21 +1,8 @@
import { BE_PLANNING_PLANNINGS_URL, BE_PLANNING_EVENTS_URL } from '@/utils/Url';
const requestResponseHandler = async (response) => {
const body = response.status !== 204 ? await response?.json() : {};
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(
body?.errorMessage ||
`Une erreur est survenue code de retour : ${response.status}`
);
error.details = body;
throw error;
};
import { errorHandler, requestResponseHandler } from './actionsHandlers';
const getData = (url) => {
return fetch(`${url}`).then(requestResponseHandler);
return fetch(`${url}`).then(requestResponseHandler).catch(errorHandler);
};
const createDatas = (url, newData, csrfToken) => {
@ -27,7 +14,9 @@ const createDatas = (url, newData, csrfToken) => {
},
body: JSON.stringify(newData),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
const updateDatas = (url, updatedData, csrfToken) => {
@ -39,7 +28,9 @@ const updateDatas = (url, updatedData, csrfToken) => {
},
body: JSON.stringify(updatedData),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
const removeDatas = (url, csrfToken) => {
@ -50,7 +41,9 @@ const removeDatas = (url, csrfToken) => {
'X-CSRFToken': csrfToken,
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchPlannings = (

View File

@ -8,17 +8,7 @@ import {
FE_API_DOCUSEAL_DOWNLOAD_URL,
FE_API_DOCUSEAL_GENERATE_TOKEN,
} from '@/utils/Url';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
throw error;
};
import { errorHandler, requestResponseHandler } from './actionsHandlers';
// FETCH requests
@ -67,7 +57,7 @@ export const fetchRegistrationSchoolFileMasters = (id = null) => {
'Content-Type': 'application/json',
},
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const fetchRegistrationParentFileMasters = (id = null) => {
@ -81,7 +71,7 @@ export const fetchRegistrationParentFileMasters = (id = null) => {
'Content-Type': 'application/json',
},
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const fetchRegistrationSchoolFileTemplates = (id = null) => {
@ -95,7 +85,7 @@ export const fetchRegistrationSchoolFileTemplates = (id = null) => {
'Content-Type': 'application/json',
},
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
// CREATE requests
@ -130,7 +120,9 @@ export const createRegistrationSchoolFileMaster = (data, csrfToken) => {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createRegistrationParentFileMaster = (data, csrfToken) => {
@ -142,7 +134,9 @@ export const createRegistrationParentFileMaster = (data, csrfToken) => {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createRegistrationSchoolFileTemplate = (data, csrfToken) => {
@ -154,7 +148,9 @@ export const createRegistrationSchoolFileTemplate = (data, csrfToken) => {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createRegistrationParentFileTemplate = (data, csrfToken) => {
@ -166,7 +162,9 @@ export const createRegistrationParentFileTemplate = (data, csrfToken) => {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
// EDIT requests
@ -207,7 +205,9 @@ export const editRegistrationSchoolFileMaster = (fileId, data, csrfToken) => {
},
credentials: 'include',
}
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editRegistrationParentFileMaster = (id, data, csrfToken) => {
@ -222,7 +222,9 @@ export const editRegistrationParentFileMaster = (id, data, csrfToken) => {
},
credentials: 'include',
}
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editRegistrationSchoolFileTemplates = (
@ -240,7 +242,9 @@ export const editRegistrationSchoolFileTemplates = (
},
credentials: 'include',
}
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editRegistrationParentFileTemplates = (
@ -258,7 +262,9 @@ export const editRegistrationParentFileTemplates = (
},
credentials: 'include',
}
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
// DELETE requests
@ -343,7 +349,9 @@ export const cloneTemplate = (templateId, email, is_required) => {
email,
is_required,
}),
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const downloadTemplate = (slug) => {
@ -352,7 +360,9 @@ export const downloadTemplate = (slug) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const generateToken = (email, id = null) => {
@ -362,5 +372,7 @@ export const generateToken = (email, id = null) => {
'Content-Type': 'application/json',
},
body: JSON.stringify({ user_email: email, id }),
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -9,34 +9,28 @@ import {
BE_SCHOOL_PAYMENT_MODES_URL,
BE_SCHOOL_ESTABLISHMENT_URL,
} from '@/utils/Url';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
throw error;
};
import { errorHandler, requestResponseHandler } from './actionsHandlers';
export const fetchSpecialities = (establishment) => {
return fetch(
`${BE_SCHOOL_SPECIALITIES_URL}?establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchTeachers = (establishment) => {
return fetch(
`${BE_SCHOOL_TEACHERS_URL}?establishment_id=${establishment}`
).then(requestResponseHandler);
return fetch(`${BE_SCHOOL_TEACHERS_URL}?establishment_id=${establishment}`)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchClasses = (establishment) => {
return fetch(
`${BE_SCHOOL_SCHOOLCLASSES_URL}?establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchClasse = (id) => {
@ -46,61 +40,79 @@ export const fetchClasse = (id) => {
};
export const fetchSchedules = () => {
return fetch(`${BE_SCHOOL_PLANNINGS_URL}`).then(requestResponseHandler);
return fetch(`${BE_SCHOOL_PLANNINGS_URL}`)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchRegistrationDiscounts = (establishment) => {
return fetch(
`${BE_SCHOOL_DISCOUNTS_URL}?filter=registration&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchTuitionDiscounts = (establishment) => {
return fetch(
`${BE_SCHOOL_DISCOUNTS_URL}?filter=tuition&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchRegistrationFees = (establishment) => {
return fetch(
`${BE_SCHOOL_FEES_URL}?filter=registration&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchTuitionFees = (establishment) => {
return fetch(
`${BE_SCHOOL_FEES_URL}?filter=tuition&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchRegistrationPaymentPlans = (establishment) => {
return fetch(
`${BE_SCHOOL_PAYMENT_PLANS_URL}?filter=registration&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchTuitionPaymentPlans = (establishment) => {
return fetch(
`${BE_SCHOOL_PAYMENT_PLANS_URL}?filter=tuition&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchRegistrationPaymentModes = (establishment) => {
return fetch(
`${BE_SCHOOL_PAYMENT_MODES_URL}?filter=registration&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchTuitionPaymentModes = (establishment) => {
return fetch(
`${BE_SCHOOL_PAYMENT_MODES_URL}?filter=tuition&establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchEstablishment = (establishment) => {
return fetch(`${BE_SCHOOL_ESTABLISHMENT_URL}/${establishment}`).then(
requestResponseHandler
);
return fetch(`${BE_SCHOOL_ESTABLISHMENT_URL}/${establishment}`)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createDatas = (url, newData, csrfToken) => {
@ -112,7 +124,9 @@ export const createDatas = (url, newData, csrfToken) => {
},
body: JSON.stringify(newData),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const updateDatas = (url, id, updatedData, csrfToken) => {
@ -124,7 +138,9 @@ export const updateDatas = (url, id, updatedData, csrfToken) => {
},
body: JSON.stringify(updatedData),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const removeDatas = (url, id, csrfToken) => {
@ -135,5 +151,7 @@ export const removeDatas = (url, id, csrfToken) => {
'X-CSRFToken': csrfToken,
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -1,20 +1,10 @@
import { BE_SETTINGS_SMTP_URL } from '@/utils/Url';
import { errorHandler, requestResponseHandler } from './actionsHandlers';
export const PENDING = 'pending';
export const SUBSCRIBED = 'subscribed';
export const ARCHIVED = 'archived';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
throw error;
};
export const fetchSmtpSettings = (csrfToken, establishment_id = null) => {
let url = `${BE_SETTINGS_SMTP_URL}/`;
if (establishment_id) {
@ -25,7 +15,9 @@ export const fetchSmtpSettings = (csrfToken, establishment_id = null) => {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken,
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editSmtpSettings = (data, csrfToken) => {
@ -37,5 +29,7 @@ export const editSmtpSettings = (data, csrfToken) => {
},
body: JSON.stringify(data),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -7,19 +7,7 @@ import {
} from '@/utils/Url';
import { CURRENT_YEAR_FILTER } from '@/utils/constants';
import { useNotification } from '@/context/NotificationContext';
const requestResponseHandler = async (response) => {
const body = await response.json();
if (response.ok) {
return body;
}
// Throw an error with the JSON body containing the form errors
const error = new Error(body?.errorMessage || 'Une erreur est survenue');
error.details = body;
showNotification('Une erreur inattendue est survenue.', 'error', 'Erreur');
throw error;
};
import { errorHandler, requestResponseHandler } from './actionsHandlers';
export const fetchRegisterForms = (
establishment,
@ -36,17 +24,20 @@ export const fetchRegisterForms = (
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchRegisterForm = (id) => {
return fetch(`${BE_SUBSCRIPTION_REGISTERFORMS_URL}/${id}`) // Utilisation de studentId au lieu de codeDI
.then(requestResponseHandler);
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchLastGuardian = () => {
return fetch(`${BE_SUBSCRIPTION_LAST_GUARDIAN_ID_URL}`).then(
requestResponseHandler
);
return fetch(`${BE_SUBSCRIPTION_LAST_GUARDIAN_ID_URL}`)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editRegisterForm = (id, data, csrfToken) => {
@ -57,7 +48,9 @@ export const editRegisterForm = (id, data, csrfToken) => {
},
body: data,
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createRegisterForm = (data, csrfToken) => {
@ -70,7 +63,9 @@ export const createRegisterForm = (data, csrfToken) => {
},
body: JSON.stringify(data),
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const sendRegisterForm = (id) => {
@ -79,7 +74,9 @@ export const sendRegisterForm = (id) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const resendRegisterForm = (id) => {
@ -88,7 +85,9 @@ export const resendRegisterForm = (id) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const archiveRegisterForm = (id) => {
const url = `${BE_SUBSCRIPTION_REGISTERFORMS_URL}/${id}/archive`;
@ -97,7 +96,9 @@ export const archiveRegisterForm = (id) => {
headers: {
'Content-Type': 'application/json',
},
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const fetchStudents = (establishment, id = null) => {
@ -110,7 +111,7 @@ export const fetchStudents = (establishment, id = null) => {
'Content-Type': 'application/json',
},
});
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export const fetchChildren = (id, establishment) => {
@ -123,7 +124,7 @@ export const fetchChildren = (id, establishment) => {
},
}
);
return fetch(request).then(requestResponseHandler);
return fetch(request).then(requestResponseHandler).catch(errorHandler);
};
export async function getRegisterFormFileTemplate(fileId) {
@ -206,7 +207,9 @@ export const dissociateGuardian = async (studentId, guardianId) => {
export const fetchAbsences = (establishment) => {
return fetch(
`${BE_SUBSCRIPTION_ABSENCES_URL}?establishment_id=${establishment}`
).then(requestResponseHandler);
)
.then(requestResponseHandler)
.catch(errorHandler);
};
export const createAbsences = (data, csrfToken) => {
@ -218,7 +221,9 @@ export const createAbsences = (data, csrfToken) => {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(requestResponseHandler);
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const editAbsences = (absenceId, payload, csrfToken) => {

View File

@ -1,4 +1,5 @@
'use client';
import logger from '@/utils/logger';
import React, { useState } from 'react';
export default function AnnouncementScheduler({ csrfToken }) {
@ -8,7 +9,7 @@ export default function AnnouncementScheduler({ csrfToken }) {
const handleSchedule = () => {
// Logique pour planifier une annonce
console.log('Annonce planifiée:', { title, date, message });
logger.debug('Annonce planifiée:', { title, date, message });
};
return (

View File

@ -8,10 +8,11 @@ import { useNotification } from '@/context/NotificationContext';
import { useEstablishment } from '@/context/EstablishmentContext';
import AlertMessage from '@/components/AlertMessage';
import RecipientInput from '@/components/RecipientInput';
// Charger Quill dynamiquement pour éviter les problèmes de SSR
const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });
import 'react-quill/dist/quill.snow.css'; // Importer les styles de Quill
import { useRouter } from 'next/navigation'; // Ajoute cette ligne
import WisiwigTextArea from '@/components/WisiwigTextArea';
import logger from '@/utils/logger';
import InputText from '@/components/InputText';
import Button from '@/components/Button';
export default function EmailSender({ csrfToken }) {
const [recipients, setRecipients] = useState([]);
@ -23,6 +24,7 @@ export default function EmailSender({ csrfToken }) {
const [smtpConfigured, setSmtpConfigured] = useState(false); // État pour vérifier si SMTP est configuré
const { showNotification } = useNotification();
const { selectedEstablishmentId } = useEstablishment(); // Récupérer l'establishment_id depuis le contexte
const router = useRouter(); // Ajoute cette ligne
useEffect(() => {
// Vérifier si les paramètres SMTP sont configurés
@ -36,10 +38,9 @@ export default function EmailSender({ csrfToken }) {
}
})
.catch((error) => {
console.error(
'Erreur lors de la vérification des paramètres SMTP:',
error
);
logger.error('Erreur lors de la vérification des paramètres SMTP:', {
error,
});
setSmtpConfigured(false);
});
}, [csrfToken, selectedEstablishmentId]);
@ -64,7 +65,7 @@ export default function EmailSender({ csrfToken }) {
setSubject('');
setMessage('');
} catch (error) {
console.error("Erreur lors de l'envoi de l'email:", error);
logger.error("Erreur lors de l'envoi de l'email:", { error });
showNotification(
"Une erreur est survenue lors de l'envoi de l'email.",
'error',
@ -80,82 +81,76 @@ export default function EmailSender({ csrfToken }) {
title="Configuration SMTP requise"
message="Les paramètres SMTP de cet établissement ne sont pas configurés. Veuillez les configurer dans la page des paramètres."
actionLabel="Aller aux paramètres"
onAction={() => (window.location.href = '/admin/settings')} // Redirige vers la page des paramètres
onAction={() => router.push('/admin/settings?tab=smtp')} // Utilise next/navigation ici
/>
);
}
return (
<div className="max-w-3xl mx-auto bg-white rounded-lg shadow-md">
{/* Header */}
<div className="flex items-center justify-between px-4 py-2 border-b">
<h2 className="text-sm font-medium text-gray-700">
Email from {fromEmail}
</h2>
</div>
{/* Form */}
<div className="p-4">
{/* To */}
<div className="p-4 flex flex-col min-h-[600px]">
{' '}
{/* Ajout flex-col et min-h */}
{/* Destinataires */}
<RecipientInput
label="Destinataires"
recipients={recipients}
setRecipients={setRecipients}
searchRecipients={searchRecipients} // Passer l'action de recherche
establishmentId={selectedEstablishmentId} // Passer l'ID de l'établissement
searchRecipients={searchRecipients}
establishmentId={selectedEstablishmentId}
required
/>
{/* Cc and Bcc */}
<div className="flex space-x-4">
{/* Cc */}
<div className="mt-2">
<RecipientInput
label="Cc"
placeholder="Add Cc"
placeholder="Ajouter Cc"
recipients={cc}
searchRecipients={searchRecipients}
establishmentId={selectedEstablishmentId}
setRecipients={setCc}
/>
</div>
{/* Bcc */}
<div className="mt-2">
<RecipientInput
label="Bcc"
placeholder="Add Bcc"
label="Cci"
placeholder="Ajouter Bcc"
recipients={bcc}
searchRecipients={searchRecipients}
establishmentId={selectedEstablishmentId}
setRecipients={setBcc}
/>
</div>
{/* Subject */}
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700">
Subject
</label>
<input
type="text"
<InputText
name="subject"
label="Sujet"
value={subject}
onChange={(e) => setSubject(e.target.value)}
placeholder="Enter subject"
className="w-full p-2 border rounded"
placeholder="Saisir le sujet"
className="mb-4 mt-2"
required
/>
</div>
{/* Email Body */}
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700">
Your email
</label>
<ReactQuill
theme="snow"
<div className="mb-4 flex flex-col">
<WisiwigTextArea
label="Mail"
value={message}
onChange={setMessage}
placeholder="Write your email here..."
placeholder="Ecrivez votre mail ici..."
required
/>
</div>
{/* Footer */}
<div className="flex justify-between items-center">
<button
<div className="flex justify-between items-center mt-10">
<Button
text="Envoyer"
onClick={handleSendEmail}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Send email
</button>
primary
className="px-4 py-2"
/>
</div>
</div>
</div>

View File

@ -2,6 +2,7 @@
import React from 'react';
import Chat from '@/components/Chat';
import { getGravatarUrl } from '@/utils/gravatar';
import logger from '@/utils/logger';
const contacts = [
{
@ -18,7 +19,7 @@ const contacts = [
export default function InstantMessaging({ csrfToken }) {
const handleSendMessage = (contact, message) => {
console.log(`Message envoyé à ${contact.name}: ${message}`);
logger.debug(`Message envoyé à ${contact.name}: ${message}`);
};
return <Chat contacts={contacts} onSendMessage={handleSendMessage} />;

View File

@ -14,7 +14,7 @@ const AffectationClasseForm = ({ eleve = {}, onSubmit, classes }) => {
};
const handleSubmit = () => {
console.log(formData);
logger.debug(formData);
/*onSubmit({
eleve: {
...formData,

View File

@ -1,6 +1,7 @@
import { useState } from 'react';
import { usePlanning, PlanningModes } from '@/context/PlanningContext';
import { Plus, Edit2, Eye, EyeOff, Check, X } from 'lucide-react';
import logger from '@/utils/logger';
export default function ScheduleNavigation({ classes, modeSet = 'event' }) {
const {
@ -118,7 +119,7 @@ export default function ScheduleNavigation({ classes, modeSet = 'event' }) {
>
<option value="">Aucune</option>
{classes.map((classe) => {
console.log({ classe });
logger.debug({ classe });
return (
<option key={classe.id} value={classe.id}>
{classe.atmosphere_name}

View File

@ -1,3 +1,4 @@
import logger from '@/utils/logger';
import React from 'react';
const CheckBox = ({
@ -8,7 +9,7 @@ const CheckBox = ({
itemLabelFunc = () => null,
horizontal,
}) => {
console.log(formData);
logger.debug(formData);
// Vérifier si formData[fieldName] est un tableau ou une valeur booléenne
const isChecked = Array.isArray(formData[fieldName])

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import { Check } from 'lucide-react';
import Popup from '@/components/Popup';
import logger from '@/utils/logger';
const DateTab = ({
dates,
@ -29,13 +30,13 @@ const DateTab = ({
handleEdit(paymentPlanId, dataWithType)
.then(() => {
setPopupMessage(
`Mise à jour de la date d'échéance effectuée avec succès`
"Mise à jour de la date d'échéance effectuée avec succès"
);
setPopupVisible(true);
setModifiedDates({});
})
.catch((error) => {
console.error(error);
logger.error(error);
});
};

View File

@ -93,7 +93,6 @@ export default function FileUpload({
{typeof existingFile === 'string'
? existingFile.split('/').pop() // Si c'est une chaîne, utilisez split
: existingFile?.name || 'Nom de fichier inconnu'}{' '}
// Sinon, utilisez une propriété ou un fallback
</span>
</p>
</div>

View File

@ -22,6 +22,7 @@ const typeStyles = {
};
export default function FlashNotification({
displayPeriod = 3000,
title,
message,
type = 'info',
@ -33,9 +34,9 @@ export default function FlashNotification({
const timer = setTimeout(() => {
setIsVisible(false); // Déclenche la disparition
setTimeout(onClose, 300); // Appelle onClose après l'animation
}, 3000); // Notification visible pendant 3 secondes
}, displayPeriod); // Notification visible pendant 3 secondes par défaut
return () => clearTimeout(timer);
}, [onClose]);
}, [onClose, displayPeriod]);
if (!message || !isVisible) return null;
@ -47,14 +48,14 @@ export default function FlashNotification({
animate={{ opacity: 1, x: 0 }} // Animation visible
exit={{ opacity: 0, x: 50 }} // Animation de sortie
transition={{ duration: 0.3 }} // Durée des animations
className="fixed top-5 right-5 flex items-stretch w-96 rounded-lg shadow-lg bg-white z-50 border border-gray-200"
className="fixed top-5 right-5 flex items-stretch rounded-lg shadow-lg bg-white z-50 border border-gray-200"
>
{/* Rectangle gauche avec l'icône */}
<div className={`flex items-center justify-center w-12 ${bg}`}>
<div className={`flex items-center justify-center w-14 ${bg}`}>
{icon}
</div>
{/* Zone de texte */}
<div className="flex-1 p-4">
<div className="flex-1 w-96 p-4">
<p className="font-bold text-black">{title}</p>
<p className="text-gray-700">{message}</p>
</div>

View File

@ -6,6 +6,7 @@ import {
fetchParentFileTemplatesFromRegistrationFiles,
} from '@/app/actions/subscriptionAction';
import { BASE_URL } from '@/utils/Url';
import logger from '@/utils/logger';
const FilesModal = ({
isOpen,
@ -23,9 +24,7 @@ const FilesModal = ({
useEffect(() => {
if (!selectedRegisterForm?.student?.id) {
console.error(
'selectedRegisterForm.student.id est invalide ou manquant.'
);
logger.error('selectedRegisterForm.student.id est invalide ou manquant.');
return;
}
@ -37,7 +36,7 @@ const FilesModal = ({
)
.then((schoolFiles) => {
if (!Array.isArray(schoolFiles)) {
console.error(
logger.error(
'Les fichiers scolaires ne sont pas un tableau :',
schoolFiles
);
@ -84,7 +83,7 @@ const FilesModal = ({
setFiles(categorizedFiles);
})
.catch((error) => {
console.error('Erreur lors de la récupération des fichiers :', error);
logger.error('Erreur lors de la récupération des fichiers :', error);
});
}, [selectedRegisterForm]);
@ -144,7 +143,7 @@ const FilesModal = ({
{/* Section Fichiers École */}
<div>
<h3 className="text-lg font-semibold text-gray-800 mb-4">
Formulaires de l'établissement
Formulaires de l&apos;établissement
</h3>
<ul className="space-y-2">
{files.schoolFiles.length > 0 ? (

View File

@ -138,7 +138,7 @@ export default function InscriptionFormShared({
// Mettre à jour isPage6Valid en fonction de cette condition
setIsPage6Valid(allRequiredUploaded);
console.log(allRequiredUploaded);
logger.debug(allRequiredUploaded);
}, [parentFileTemplates]);
const handleTemplateSigned = (index) => {
@ -420,7 +420,7 @@ export default function InscriptionFormShared({
formDataToSend.append('photo', formData.photo);
}
console.log('submit : ', jsonData);
logger.debug('submit : ', jsonData);
// Appeler la fonction onSubmit avec les données FormData
onSubmit(formDataToSend);

View File

@ -1,6 +1,7 @@
import React, { useEffect } from 'react';
import SelectChoice from '@/components/SelectChoice';
import RadioList from '@/components/RadioList';
import logger from '@/utils/logger';
export default function PaymentMethodSelector({
formData,
@ -18,7 +19,7 @@ export default function PaymentMethodSelector({
(field) => getLocalError(field) !== ''
);
setIsPageValid(isValid);
console.log('formdata : ', formData);
logger.debug('formdata : ', formData);
}, [formData, setIsPageValid]);
const paymentModesOptions = [
@ -68,7 +69,7 @@ export default function PaymentMethodSelector({
{/* Frais d'inscription */}
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<h2 className="text-2xl font-semibold mb-6 text-gray-800 border-b pb-2">
Frais d'inscription
Frais d&apos;inscription
</h2>
<div className="mb-6 bg-gray-50 p-4 rounded-lg border border-gray-100">

View File

@ -115,8 +115,8 @@ export default function ResponsableInputFields({
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<SectionHeader
icon={Users}
title={`Responsables légaux`}
description={`Remplissez les champs requis`}
title={'Responsables légaux'}
description={'Remplissez les champs requis'}
/>
{guardians.map((item, index) => (
<div className="p-6 " key={index}>

View File

@ -97,8 +97,8 @@ export default function SiblingInputFields({
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<SectionHeader
icon={Users}
title={`Frères et Sœurs`}
description={`Ajoutez les informations des frères et sœurs`}
title={'Frères et Sœurs'}
description={'Ajoutez les informations des frères et sœurs'}
/>
{siblings.map((item, index) => (
<div className="p-6" key={index}>

View File

@ -154,8 +154,8 @@ export default function StudentInfoForm({
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200 space-y-8">
<SectionHeader
icon={User}
title={`Informations de l'élève`}
description={`Remplissez les champs requis`}
title={"Informations de l'élève"}
description={'Remplissez les champs requis'}
/>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<InputText

View File

@ -126,7 +126,7 @@ export default function ValidateSubscription({
]
: []),
];
console.log(allTemplates);
logger.debug(allTemplates);
return (
<div className="mb-4 w-full mx-auto">

View File

@ -4,6 +4,7 @@ import Table from '@/components/Table';
import DateTab from '@/components/DateTab';
import InputTextIcon from '@/components/InputTextIcon';
import Popup from '@/components/Popup';
import logger from '@/utils/logger';
const paymentPlansOptions = [
{ id: 0, name: '1 fois', frequency: 1 },
@ -118,7 +119,7 @@ const PaymentPlanSelector = ({
});
})
.catch((error) => {
console.error(error);
logger.error(error);
});
};
@ -222,13 +223,13 @@ const PaymentPlanSelector = ({
handleEdit(selectedPlan.id, updatedData)
.then(() => {
setPopupMessage(
`Mise à jour des dates d'échéances effectuée avec succès`
"Mise à jour des dates d'échéances effectuée avec succès"
);
setPopupVisible(true);
setIsDefaultDayModified(false);
})
.catch((error) => {
console.error(error);
logger.error(error);
});
};

View File

@ -8,10 +8,11 @@ import { NotificationProvider } from '@/context/NotificationContext';
import { ClassesProvider } from '@/context/ClassesContext';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import logger from '@/utils/logger';
export default function Providers({ children, messages, locale, session }) {
if (!locale) {
console.error('Locale non définie dans Providers');
logger.error('Locale non définie dans Providers');
locale = 'fr'; // Valeur par défaut
}
return (

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { getGravatarUrl } from '@/utils/gravatar'; // Assurez-vous que cette fonction est définie pour générer les URLs Gravatar
import { getRightStr } from '@/utils/rights'; // Fonction existante pour récupérer le nom des rôles
import logger from '@/utils/logger';
export default function RecipientInput({
label,
@ -8,6 +9,7 @@ export default function RecipientInput({
setRecipients,
searchRecipients, // Fonction pour effectuer la recherche
establishmentId, // ID de l'établissement
required = false, // Ajout de la prop required avec valeur par défaut
}) {
const [inputValue, setInputValue] = useState('');
const [suggestions, setSuggestions] = useState([]);
@ -22,7 +24,7 @@ export default function RecipientInput({
const results = await searchRecipients(establishmentId, value);
setSuggestions(results);
} catch (error) {
console.error('Erreur lors de la recherche des destinataires:', error);
logger.error('Erreur lors de la recherche des destinataires:', error);
setSuggestions([]);
}
} else {
@ -37,8 +39,8 @@ export default function RecipientInput({
handleSuggestionClick(suggestions[selectedIndex]);
} else {
const trimmedValue = inputValue.trim();
if (trimmedValue && !recipients.some((r) => r.email === trimmedValue)) {
setRecipients([...recipients, { email: trimmedValue }]);
if (trimmedValue && !recipients.includes(trimmedValue)) {
setRecipients([...recipients, trimmedValue]);
setInputValue('');
setSuggestions([]);
}
@ -57,39 +59,44 @@ export default function RecipientInput({
};
const handleSuggestionClick = (suggestion) => {
if (!recipients.some((r) => r.email === suggestion.email)) {
setRecipients([...recipients, suggestion]);
if (!recipients.includes(suggestion.email)) {
setRecipients([...recipients, suggestion.email]);
}
setInputValue('');
setSuggestions([]);
};
const handleRemoveRecipient = (email) => {
setRecipients(recipients.filter((recipient) => recipient.email !== email));
setRecipients(recipients.filter((recipient) => recipient !== email));
};
return (
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700">{label}</label>
<div className="flex flex-wrap items-center gap-2 p-2 border rounded">
{recipients.map((recipient, index) => (
<label className="block text-sm font-medium text-gray-700">
{label}
{required && <span className="text-red-500 ml-1">*</span>}
</label>
<div
className={`
mt-1 flex flex-wrap items-center gap-2 border rounded-md
border-gray-200 hover:border-gray-400 focus-within:border-gray-500
transition-colors
`}
>
{recipients.map((email, index) => (
<div
key={index}
className="flex items-center bg-gray-100 text-gray-700 px-2 py-1 rounded-full"
>
<img
src={getGravatarUrl(recipient.email)}
alt={recipient.email}
src={getGravatarUrl(email)}
alt={email}
className="w-6 h-6 rounded-full mr-2"
/>
<span className="mr-2">
{recipient.first_name && recipient.last_name
? `${recipient.first_name} ${recipient.last_name}`
: recipient.email}
</span>
<span className="mr-2">{email}</span>
<button
type="button"
onClick={() => handleRemoveRecipient(recipient.email)}
onClick={() => handleRemoveRecipient(email)}
className="text-gray-500 hover:text-gray-700"
>
&times;
@ -102,7 +109,8 @@ export default function RecipientInput({
onChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder="Rechercher des destinataires"
className="flex-1 p-1 outline-none"
className="flex-1 px-3 py-2 block w-full sm:text-sm border-none focus:ring-0 outline-none rounded-md"
required={required}
/>
</div>
{suggestions.length > 0 && (

View File

@ -52,7 +52,7 @@ export default function FileUploadDocuSeal({
setToken(data.token);
})
.catch((error) =>
console.error('Erreur lors de la génération du token:', error)
logger.error('Erreur lors de la génération du token:', error)
);
}, [fileToEdit]);
@ -129,7 +129,7 @@ export default function FileUploadDocuSeal({
master: templateMaster?.id,
registration_form: guardian.registration_form,
};
console.log('creation : ', data);
logger.debug('creation : ', data);
createRegistrationSchoolFileTemplate(data, csrfToken)
.then((response) => {
logger.debug('Template enregistré avec succès:', response);
@ -166,13 +166,13 @@ export default function FileUploadDocuSeal({
<div className="flex flex-col items-center justify-center h-full text-center space-y-6">
{/* Description de l'étape */}
<p className="text-gray-700 text-base font-medium mb-4">
Étape 1 - Sélectionner au moins un dossier d'inscription
Étape 1 - Sélectionner au moins un dossier d&apos;inscription
</p>
{/* Section centrée pour la sélection des groupes */}
<div className="bg-gray-50 p-8 rounded-lg shadow-md border border-gray-300 transform transition-transform hover:scale-105">
<h3 className="text-xl font-semibold text-gray-800 mb-4 text-center">
Dossiers d'inscription
Dossiers d&apos;inscription
</h3>
<MultiSelect
name="groups"
@ -190,7 +190,7 @@ export default function FileUploadDocuSeal({
{/* Section Dossiers d'inscription repositionnée sur le côté */}
<div className="col-span-2 bg-white p-4 rounded-lg shadow-md border border-gray-200">
<h3 className="text-lg font-medium text-gray-800 mb-4">
Dossiers d'inscription
Dossiers d&apos;inscription
</h3>
<MultiSelect
name="groups"

View File

@ -97,7 +97,7 @@ export default function FilesGroupsManagement({
}
)
.catch((err) => {
console.log(err.message);
logger.debug(err.message);
})
.finally(() => {
setReloadTemplates(false);
@ -155,7 +155,7 @@ export default function FilesGroupsManagement({
}
})
.catch((error) => {
console.error('Error deleting file from database:', error);
logger.error('Error deleting file from database:', error);
showNotification(
`Erreur lors de la suppression du document "${templateMaster.name}".`,
'error',
@ -175,7 +175,7 @@ export default function FilesGroupsManagement({
}
})
.catch((error) => {
console.error('Error removing template from DocuSeal:', error);
logger.error('Error removing template from DocuSeal:', error);
showNotification(
`Erreur lors de la suppression du document "${templateMaster.name}".`,
'error',
@ -207,7 +207,7 @@ export default function FilesGroupsManagement({
return response;
})
.catch((error) => {
console.error('Error removing template:', error);
logger.error('Error removing template:', error);
throw error;
});
};
@ -235,7 +235,7 @@ export default function FilesGroupsManagement({
setIsModalOpen(false);
})
.catch((error) => {
console.error('Error uploading file:', error);
logger.error('Error uploading file:', error);
});
};
@ -258,7 +258,7 @@ export default function FilesGroupsManagement({
setIsModalOpen(false);
})
.catch((error) => {
console.error('Error editing file:', error);
logger.error('Error editing file:', error);
showNotification(
'Erreur lors de la modification du fichier',
'error',
@ -280,7 +280,7 @@ export default function FilesGroupsManagement({
setIsGroupModalOpen(false);
})
.catch((error) => {
console.error('Error handling group:', error);
logger.error('Error handling group:', error);
showNotification(
"Erreur lors de l'opération sur le groupe",
'error',
@ -300,7 +300,7 @@ export default function FilesGroupsManagement({
setIsGroupModalOpen(false);
})
.catch((error) => {
console.error('Error handling group:', error);
logger.error('Error handling group:', error);
showNotification(
"Erreur lors de l'opération sur le groupe",
'error',
@ -349,7 +349,7 @@ export default function FilesGroupsManagement({
showNotification('Groupe supprimé avec succès.', 'success', 'Succès');
})
.catch((error) => {
console.error('Error deleting group:', error);
logger.error('Error deleting group:', error);
setRemovePopupVisible(false);
setIsLoading(false);
showNotification(

View File

@ -54,7 +54,7 @@ const FeesManagement = ({
<div className="w-4/5 mx-auto flex items-center mt-8">
<hr className="flex-grow border-t-2 border-gray-300" />
<span className="mx-4 text-gray-600 font-semibold">
Frais d'inscription
Frais d&apos;inscription
</span>
<hr className="flex-grow border-t-2 border-gray-300" />
</div>

View File

@ -257,9 +257,7 @@ const FeesSection = ({
onClick={() => {
setRemovePopupVisible(true);
setRemovePopupMessage(
'Attentions ! \nVous êtes sur le point de supprimer un ' +
labelTypeFrais +
".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?"
`Attentions ! \nVous êtes sur le point de supprimer un ${labelTypeFrais} .\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?`
);
setRemovePopupOnConfirm(() => () => {
handleRemoveFee(fee.id)

View File

@ -0,0 +1,61 @@
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });
export default function WisiwigTextArea({
label = 'Mail',
value,
onChange,
placeholder = 'Ecrivez votre mail ici...',
className = 'h-64',
required = false,
errorMsg,
errorLocalMsg,
enable = true,
}) {
return (
<div className={`mb-4 ${className}`}>
<label className="block text-sm font-medium text-gray-700">
{label}
{required && <span className="text-red-500 ml-1">*</span>}
</label>
<div
className={`
mt-1 border rounded-md
${
errorMsg || errorLocalMsg
? 'border-red-500 hover:border-red-700'
: 'border-gray-200 hover:border-gray-400'
}
${!errorMsg && !errorLocalMsg ? 'focus-within:border-gray-500' : ''}
${!enable ? 'bg-gray-100 cursor-not-allowed' : ''}
`}
>
<ReactQuill
theme="snow"
value={value}
onChange={enable ? onChange : undefined}
placeholder={placeholder}
readOnly={!enable}
className={`bg-white rounded-md border-0 shadow-none !border-0 !outline-none ${!enable ? 'bg-gray-100 cursor-not-allowed' : ''}`}
style={{ minHeight: 250, border: 'none', boxShadow: 'none' }}
/>
</div>
{errorMsg && <p className="mt-2 text-sm text-red-600">{errorMsg}</p>}
{errorLocalMsg && (
<p className="mt-2 text-sm text-red-600">{errorLocalMsg}</p>
)}
<style jsx global>{`
.ql-toolbar.ql-snow {
border: none !important;
border-bottom: 1px solid #e5e7eb !important; /* gray-200 */
border-radius: 0.375rem 0.375rem 0 0 !important; /* rounded-t-md */
}
.ql-container.ql-snow {
border: none !important;
}
`}</style>
</div>
);
}

View File

@ -1,6 +1,7 @@
import { getRequestConfig } from 'next-intl/server';
import { routing } from '@/i18n/routing';
import { getAvailableNamespaces } from '@/utils/i18n';
import logger from '@/utils/logger';
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale;
@ -22,7 +23,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
).default;
messages[namespace] = translations;
} catch (error) {
console.warn(
logger.warn(
`Erreur de chargement pour ${namespace} en ${locale}:`,
error
);

View File

@ -1,3 +1,4 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_CLONE_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
@ -25,11 +26,11 @@ export default function handler(req, res) {
return response.json();
})
.then((data) => {
console.log('Template cloned successfully:', data);
logger.debug('Template cloned successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
console.error('Error cloning template:', error);
logger.error('Error cloning template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {

View File

@ -1,9 +1,10 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_DOWNLOAD_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
if (req.method === 'GET') {
const { slug } = req.query;
console.log('slug : ', slug);
logger.debug('slug : ', slug);
fetch(`${BE_DOCUSEAL_DOWNLOAD_TEMPLATE}/${slug}`, {
method: 'GET',
@ -20,11 +21,11 @@ export default function handler(req, res) {
return response.json();
})
.then((data) => {
console.log('Template downloaded successfully:', data);
logger.debug('Template downloaded successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
console.error('Error downloading template:', error);
logger.error('Error downloading template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {

View File

@ -1,3 +1,4 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_GET_JWT } from '@/utils/Url';
export default function handler(req, res) {
@ -11,17 +12,17 @@ export default function handler(req, res) {
body: JSON.stringify(req.body),
})
.then((response) => {
console.log('Response status:', response.status);
logger.debug('Response status:', response.status);
return response
.json()
.then((data) => ({ status: response.status, data }));
})
.then(({ status, data }) => {
console.log('Response data:', data);
logger.debug('Response data:', data);
res.status(status).json(data);
})
.catch((error) => {
console.error('Error:', error);
logger.error('Error:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {

View File

@ -1,3 +1,4 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_REMOVE_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
@ -19,11 +20,11 @@ export default function handler(req, res) {
return response.json();
})
.then((data) => {
console.log('Template removed successfully:', data);
logger.debug('Template removed successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
console.error('Error removing template:', error);
logger.error('Error removing template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {

View File

@ -60,58 +60,62 @@ export const BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL = `${BASE_URL}/GestionMe
export const BE_SETTINGS_SMTP_URL = `${BASE_URL}/Settings/smtp-settings`;
// URL FRONT-END
export const FE_HOME_URL = `/`;
export const FE_HOME_URL = '/';
// USERS
export const FE_USERS_LOGIN_URL = `/users/login`;
export const FE_USERS_SUBSCRIBE_URL = `/users/subscribe`;
export const FE_USERS_RESET_PASSWORD_URL = `/users/password/reset`;
export const FE_USERS_NEW_PASSWORD_URL = `/users/password/new`;
export const FE_USERS_LOGIN_URL = '/users/login';
export const FE_USERS_SUBSCRIBE_URL = '/users/subscribe';
export const FE_USERS_RESET_PASSWORD_URL = '/users/password/reset';
export const FE_USERS_NEW_PASSWORD_URL = '/users/password/new';
// ADMIN
export const FE_ADMIN_HOME_URL = `/admin`;
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/editSubscription`;
export const FE_ADMIN_SUBSCRIPTIONS_VALIDATE_URL = `/admin/subscriptions/validateSubscription`;
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/editSubscription';
export const FE_ADMIN_SUBSCRIPTIONS_VALIDATE_URL =
'/admin/subscriptions/validateSubscription';
//ADMIN/CLASSES URL
export const FE_ADMIN_CLASSES_URL = `/admin/classes`;
export const FE_ADMIN_CLASSES_URL = '/admin/classes';
//ADMIN/STRUCTURE URL
export const FE_ADMIN_STRUCTURE_URL = `/admin/structure`;
export const FE_ADMIN_STRUCTURE_SCHOOLCLASS_MANAGEMENT_URL = `/admin/structure/SchoolClassManagement`;
export const FE_ADMIN_STRUCTURE_URL = '/admin/structure';
export const FE_ADMIN_STRUCTURE_SCHOOLCLASS_MANAGEMENT_URL =
'/admin/structure/SchoolClassManagement';
//ADMIN/DIRECTORY URL
export const FE_ADMIN_DIRECTORY_URL = `/admin/directory`;
export const FE_ADMIN_DIRECTORY_URL = '/admin/directory';
//ADMIN/GRADES URL
export const FE_ADMIN_GRADES_URL = `/admin/grades`;
export const FE_ADMIN_GRADES_URL = '/admin/grades';
//ADMIN/TEACHERS URL
export const FE_ADMIN_TEACHERS_URL = `/admin/teachers`;
export const FE_ADMIN_TEACHERS_URL = '/admin/teachers';
//ADMIN/PLANNING URL
export const FE_ADMIN_PLANNING_URL = `/admin/planning`;
export const FE_ADMIN_PLANNING_URL = '/admin/planning';
//ADMIN/SETTINGS URL
export const FE_ADMIN_SETTINGS_URL = `/admin/settings`;
export const FE_ADMIN_SETTINGS_URL = '/admin/settings';
//ADMIN/MESSAGERIE URL
export const FE_ADMIN_MESSAGERIE_URL = `/admin/messagerie`;
export const FE_ADMIN_MESSAGERIE_URL = '/admin/messagerie';
// PARENT HOME
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_SUBSCRIPTION_URL = `/parents/editSubscription`;
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_SUBSCRIPTION_URL = '/parents/editSubscription';
// API DOCUSEAL
export const FE_API_DOCUSEAL_GENERATE_TOKEN = `/api/docuseal/generateToken`;
export const FE_API_DOCUSEAL_CLONE_URL = `/api/docuseal/cloneTemplate`;
export const FE_API_DOCUSEAL_DOWNLOAD_URL = `/api/docuseal/downloadTemplate`;
export const FE_API_DOCUSEAL_GENERATE_TOKEN = '/api/docuseal/generateToken';
export const FE_API_DOCUSEAL_CLONE_URL = '/api/docuseal/cloneTemplate';
export const FE_API_DOCUSEAL_DOWNLOAD_URL = '/api/docuseal/downloadTemplate';
/**
* Fonction pour obtenir l'URL de redirection en fonction du rôle

View File

@ -15,6 +15,7 @@ export async function getAvailableNamespaces(locale) {
.filter((file) => file.endsWith('.json'))
.map((file) => file.replace('.json', ''));
} catch (error) {
// eslint-disable-next-line no-console
console.warn(`Impossible de lire les namespaces pour ${locale}:`, error);
return ['common']; // Namespace par défaut
}

View File

@ -15,21 +15,24 @@ const getCallerInfo = () => {
const logger = {
debug: (...args) => {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.log.apply(console, ['[DEBUG]', `${getCallerInfo()}`, ...args]);
}
},
error: (...args) => {
// Les erreurs sont toujours loguées
// eslint-disable-next-line no-console
console.error.apply(console, ['[ERROR]', `${getCallerInfo()}`, ...args]);
},
warn: (...args) => {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn.apply(console, ['[WARN]', `${getCallerInfo()}`, ...args]);
}
},
info: (...args) => {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.info.apply(console, ['[INFO]', `${getCallerInfo()}`, ...args]);
}
},

View File

@ -1,26 +1,39 @@
const fs = require('fs');
const path = require('path');
const fs = require("fs");
const path = require("path");
// Chemins vers les fichiers
const rootPackageJsonPath = path.resolve(__dirname, '../package.json');
const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath, 'utf8'));
const rootPackageJsonPath = path.resolve(__dirname, "../package.json");
const rootPackageJson = JSON.parse(
fs.readFileSync(rootPackageJsonPath, "utf8")
);
// Lire la version actuelle du package.json principal
const newVersion = rootPackageJson.version;
const frontendPackageJsonPath = path.resolve(__dirname, '../Front-End/package.json');
const frontendPackageJsonPath = path.resolve(
__dirname,
"../Front-End/package.json"
);
// Lire et mettre à jour le package.json du sous-module
const frontendPackageJson = JSON.parse(fs.readFileSync(frontendPackageJsonPath, 'utf8'));
const frontendPackageJson = JSON.parse(
fs.readFileSync(frontendPackageJsonPath, "utf8")
);
frontendPackageJson.version = newVersion;
// Écrire les changements dans le fichier frontend/package.json
fs.writeFileSync(frontendPackageJsonPath, JSON.stringify(frontendPackageJson, null, 2), 'utf8');
fs.writeFileSync(
frontendPackageJsonPath,
JSON.stringify(frontendPackageJson, null, 2),
"utf8"
);
// eslint-disable-next-line no-console
console.log(`Version mise à jour dans frontend/package.json : ${newVersion}`);
// Chemin vers le fichier Python de version
const versionFilePath = path.resolve(__dirname, '../Back-End/__version__.py');
const versionFilePath = path.resolve(__dirname, "../Back-End/__version__.py");
// Mettre à jour le fichier Python
const versionContent = `__version__ = "${newVersion}"\n`;
fs.writeFileSync(versionFilePath, versionContent, 'utf8');
console.log(`Version du backend mise à jour dans ${versionFilePath} : ${newVersion}`);
fs.writeFileSync(versionFilePath, versionContent, "utf8");
// eslint-disable-next-line no-console
console.log(
`Version du backend mise à jour dans ${versionFilePath} : ${newVersion}`
);