Compare commits

..

No commits in common. "Lm" and "main" have entirely different histories.
Lm ... main

218 changed files with 2338 additions and 2867 deletions

View File

@ -1,5 +0,0 @@
DB_URL=http://127.0.0.1:8091/
DB_ADMIN=admin@axa.fr
DB_PASSWORD=DTadmin123TT
NODE_ENV=developpement
PORT=8082

33
ecole/.gitignore vendored
View File

@ -1,33 +0,0 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Classique
package-lock.json
# Logs
logs/
*.log
# Environment variables
.env
.env.local
.env.*.local
# OS files
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# Build outputs
dist/
build/

View File

@ -1,279 +0,0 @@
// Module IIFE pour éviter la pollution de l'espace global
(function () {
// Variables globales du module
let parcours, contrat, client, matricule;
// Initialisation du formulaire et des données
function init() {
const token = localStorage.getItem('jwtToken');
if (token) {
const decoded = jwt_decode(token);
matricule = decoded.userMatricule;
}
// Accéder aux informations stockées du parcours
parcours = JSON.parse(sessionStorage.getItem('parcours'));
contrat = JSON.parse(sessionStorage.getItem('contrat'));
client = contrat?.["@expand"]?.client || null;
console.log("Matricule user actuel:", matricule);
console.log("Initialisation pour formulaire client :", contrat);
// Materialize init Modal
var modals = document.querySelectorAll('.modal');
M.Modal.init(modals);
// Appel des différentes fonctions d'initialisation
setupEventListeners();
populateFormData();
updateSubmitButtonState('clientForm');
}
// Configuration des écouteurs d'événements
function setupEventListeners() {
document.getElementById('clientFormBtn').addEventListener('click', handleSubmitForm);
document.getElementById('creditsafe').addEventListener('click', (event) => handleOpenLink(event, 'creditsafeURL'));
document.getElementById('easyQP').addEventListener('click', (event) => handleOpenLink(event, 'easyQPURL'));
document.getElementById('refNoteFi').addEventListener('click', (event) => handleOpenLink(event, 'refNoteFiURL'));
document.getElementById('cl063-client').addEventListener('click', (event) => handleExtractClient(event));
document.getElementById('modalExtraireClient').addEventListener('click', (event) => handleModalExtract(event));
// Controle de saisie et format sur les champs du formulaire
document.getElementById('noteFinanciereClient').addEventListener('input', function () {
validateField('noteFinanciereClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('numClient').addEventListener('input', function () {
validateField('numClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('nomClient').addEventListener('input', function () {
validateField('nomClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('emailClient').addEventListener('input', function () {
validateField('emailClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('adresseClient').addEventListener('input', function () {
validateField('adresseClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('codePostalClient').addEventListener('input', function () {
validateField('codePostalClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('villeClient').addEventListener('input', function () {
validateField('villeClient', true);
updateSubmitButtonState('clientForm');
});
document.getElementById('modalNumClient').addEventListener('input', function () {
validateField('modalNumClient', true);
updateSubmitButtonState('modalExtraireClient');
});
}
// Peupler le formulaire avec les données
function populateFormData() {
const clientStorage = JSON.parse(sessionStorage.getItem('tmp'));
if (client) {
document.getElementById('nomClient').value = client.nom || '';
document.getElementById('numClient').value = client.numClient || '';
document.getElementById('adresseClient').value = client.adresse || '';
document.getElementById('emailClient').value = client.mail || '';
document.getElementById('codePostalClient').value = client.codePostal || '';
document.getElementById('villeClient').value = client.ville || '';
document.getElementById('noteFinanciereClient').value = client.noteFinanciere || '';
}
if (clientStorage) {
document.getElementById('nomClient').value = clientStorage.nomClient || '';
document.getElementById('numClient').value = clientStorage.numClient || '';
document.getElementById('adresseClient').value = clientStorage.adresseClient || '';
document.getElementById('codePostalClient').value = clientStorage.postalClient || '';
document.getElementById('villeClient').value = clientStorage.villeClient || '';
}
}
// Gérer l'ouverture de liens externes
function handleOpenLink(event, urlType) {
event.preventDefault();
let url = '';
switch (urlType) {
case 'creditsafeURL':
url = 'https://www.creditsafe.fr/csfr?UserName=735265dorothee&Password=UH04EuLocXZMxIRqY19w6A%3d%3d&BackOfficeCountry=FR&origincountry=FR&linkages=Y';
break;
case 'easyQPURL':
if (document.getElementById('numClient').value != "") {
url = `https://qualite-portefeuille-iard-ent.axa-fr.intraxa/client/${document.getElementById('numClient').value}`;
} else {
url = `https://qualite-portefeuille-iard-ent.axa-fr.intraxa/`;
}
break;
case 'refNoteFiURL':
url = 'https://app.powerbi.com/groups/me/apps/7b48f9a2-bd97-4178-bc1a-a5f7ef6e985f/reports/d29a9f83-cafe-4a0f-bc38-0929921e8cd3/ReportSection?ctid=396b38cc-aa65-492b-bb0e-3d94ed25a97b';
break;
}
window.open(url, '_blank');
}
// Gérer l'extraction axaPAC
async function handleExtractClient(event) {
event.preventDefault();
// Affiche le modal
const elem = document.getElementById('modalExtractAxAPAC');
const instance = M.Modal.getInstance(elem);
instance.open();
}
async function handleModalExtract() {
document.getElementById('modalExtraireClient').disabled = true;
const response = await fetch(`/client/extract`, {
method: 'POST',
body: JSON.stringify({
"matricule": matricule,
"numClient": document.getElementById("modalNumClient").value
}),
headers: {
'Content-Type': 'application/json',
},
});
const res = await response.json();
if (res.valid) {
document.getElementById("error-extract").style.display = "none";
document.getElementById('modalExtraireClient').disabled = false;
console.log(res);
// Save sessionStorage for Intermediaire
sessionStorage.setItem('tmp', JSON.stringify(res.data));
// Populate data
document.getElementById("numClient").value = (res.data.numClient) ? res.data.numClient : null;
document.getElementById("nomClient").value = (res.data.nomClient) ? res.data.nomClient : null;
document.getElementById("adresseClient").value = (res.data.adresseClient) ? res.data.adresseClient : null;
document.getElementById("codePostalClient").value = (res.data.postalClient) ? res.data.postalClient : null;
document.getElementById("villeClient").value = (res.data.villeClient) ? res.data.villeClient : null;
validateField('numClient', true);
validateField('nomClient', true);
validateField('adresseClient', true);
validateField('codePostalClient', true);
validateField('villeClient', true);
updateSubmitButtonState('clientForm');
// close le modal
const elem = document.getElementById('modalExtractAxAPAC');
const instance = M.Modal.getInstance(elem);
instance.close();
} else {
document.getElementById("error-extract").style.display = "block";
document.getElementById('modalExtraireClient').disabled = false;
console.log("Problème rencontré lors de l'extraction cl063 AxA PAC :", res.error);
}
}
// Gérer la soumission du formulaire
async function handleSubmitForm(event) {
event.preventDefault();
let idClient = client?.id;
const numClient = document.getElementById('numClient').value;
let responseClient;
if (numClient) {
responseClient = await fetch(`/client/read/${numClient}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
}
const dataClient = await responseClient.json();
if (dataClient.valid) {
idClient = dataClient.idClient;
} else {
// Créez le client ici si non trouvé
const responseCreateClient = await fetch(`/client/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
});
const dataCreateClient = await responseCreateClient.json();
if (dataCreateClient.valid) {
idClient = dataCreateClient.client.id;
}
}
// Mettre à jour le contrat avec l'ID du client
if (idClient) {
const response = await fetch(`/client/update/${idClient}`, {
method: 'POST',
body: JSON.stringify({
"nom": document.getElementById('nomClient').value.toUpperCase(),
"numClient": document.getElementById('numClient').value,
"adresse": document.getElementById('adresseClient').value.toUpperCase(),
"mail": document.getElementById('emailClient').value,
"codePostal": document.getElementById('codePostalClient').value,
"ville": document.getElementById('villeClient').value.toUpperCase(),
"noteFinanciere": document.getElementById('noteFinanciereClient').value
}),
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
if (data.valid) {
const idContrat = contrat?.id;
fetch(`/contrat/update/client/${idContrat}/${idClient}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => {
if (data.valid) {
// Update Session storage
const clientStorage = JSON.parse(sessionStorage.getItem('tmp'));
if (clientStorage) {
clientStorage.nomClient = document.getElementById('nomClient').value.toUpperCase();
clientStorage.numClient = document.getElementById('numClient').value;
clientStorage.adresseClient = document.getElementById('adresseClient').value.toUpperCase();
clientStorage.postalClient = document.getElementById('codePostalClient').value;
clientStorage.villeClient = document.getElementById('villeClient').value.toUpperCase();
sessionStorage.setItem('tmp', JSON.stringify(clientStorage))
}
// Redirect vers intermédiaire
window.location.href = `/navParcours?numParcours=${getNumParcoursFromURL()}&submenu=intermediaire`;
} else {
console.log('Echec lors de la mise à jour de la relation id contrat - id client :', data);
}
});
}
}
}
// Exposer init globalement pour y accéder depuis l'extérieur
window.initSubmenuForm = init;
})();

View File

@ -1,129 +0,0 @@
document.addEventListener("DOMContentLoaded", () => {
let activateTimeout = null;
let timeoutWarning = null;
let currentPageLoad = null;
let safetyTimeout = null; // Timeout de sécurité pour éviter que le loader reste bloqué
/**
* Active le loader et le rend visible
* Affiche un message d'annulation après 8 secondes
*/
window.showLoader = function() {
const loader = document.getElementById("loader-overlay");
if (!loader) return; // Protection : si l'élément n'existe pas, on ne fait rien
const timeoutMessage = document.getElementById("timeout-message");
const errorMessage = document.getElementById("error-message");
// Nettoyer les timeouts précédents
clearTimeout(activateTimeout);
clearTimeout(timeoutWarning);
// Réinitialiser l'affichage
if (errorMessage) errorMessage.style.display = "none";
if (timeoutMessage) timeoutMessage.style.display = "none";
loader.classList.remove("hidden");
// Afficher le loader après 500ms (évite le flash sur les chargements rapides)
activateTimeout = setTimeout(() => {
if (loader && !loader.classList.contains("hidden")) {
loader.classList.add("active");
}
}, 500);
// Afficher le message de timeout après 8 secondes
timeoutWarning = setTimeout(() => {
if (loader && loader.classList.contains("active") && !loader.classList.contains("hidden")) {
if (timeoutMessage) {
timeoutMessage.style.display = "block";
}
}
}, 8000);
// Protection : cacher automatiquement le loader après 30 secondes maximum
// Au cas où hideLoader ne serait jamais appelé (page qui ne charge pas, erreur, etc.)
if (safetyTimeout) clearTimeout(safetyTimeout);
safetyTimeout = setTimeout(() => {
if (loader && !loader.classList.contains("hidden")) {
hideLoader();
}
}, 30000); // 30 secondes max
};
/**
* Désactive et cache le loader
*/
window.hideLoader = function() {
const loader = document.getElementById("loader-overlay");
if (!loader) return; // Protection : si l'élément n'existe pas, on ne fait rien
const timeoutMessage = document.getElementById("timeout-message");
clearTimeout(activateTimeout);
clearTimeout(timeoutWarning);
if (safetyTimeout) {
clearTimeout(safetyTimeout);
safetyTimeout = null;
}
loader.classList.remove("active");
if (timeoutMessage) timeoutMessage.style.display = "none";
setTimeout(() => {
if (loader) {
loader.classList.add("hidden");
}
}, 500);
};
/**
* Affiche un message d'erreur dans le loader
* @param {string} msg - Message d'erreur à afficher
*/
window.showError = function(msg) {
const errorMessage = document.getElementById("error-message");
const timeoutMessage = document.getElementById("timeout-message");
if (!errorMessage) return; // Protection : si l'élément n'existe pas, on ne fait rien
clearTimeout(activateTimeout);
clearTimeout(timeoutWarning);
if (timeoutMessage) timeoutMessage.style.display = "none";
errorMessage.textContent = msg;
errorMessage.style.display = "block";
};
/**
* Annule le chargement en cours et cache le loader
*/
const cancelLoadingLink = document.getElementById("cancel-loading-link");
if (cancelLoadingLink) {
cancelLoadingLink.addEventListener("click", () => {
// Annuler le chargement de la page en cours si possible
if (currentPageLoad && currentPageLoad.abort) {
currentPageLoad.abort();
}
hideLoader();
// Afficher une notification discrète
if (typeof M !== 'undefined' && M.toast) {
M.toast({
html: 'Chargement annulé',
classes: 'rounded grey darken-3',
displayLength: 2500
});
}
});
}
/**
* Permet de stocker l'abort controller du chargement en cours
* @param {AbortController} controller - Controller de la requête fetch
*/
window.setCurrentPageLoad = function(controller) {
currentPageLoad = controller;
};
});

View File

@ -1,40 +0,0 @@
/**
* Affiche le loader lors des navigations entre pages (localhost)
* Comme on est en localhost, on peut se permettre d'afficher le loader
* au clic sur un lien, il disparaîtra automatiquement au chargement de la nouvelle page
*/
document.addEventListener("DOMContentLoaded", () => {
// Intercepter les clics sur les liens internes pour afficher le loader
document.body.addEventListener("click", (e) => {
const link = e.target.closest("a");
// Si c'est un lien interne (commence par /) et pas un lien spécial
if (link &&
link.getAttribute("href") &&
link.getAttribute("href").startsWith("/") &&
!link.classList.contains("modal-close") &&
!link.getAttribute("href").startsWith("/#")) {
// Afficher le loader avant la navigation
if (typeof showLoader === 'function') {
showLoader();
}
}
});
// Afficher le loader lors du rechargement (F5, Cmd+R)
window.addEventListener("beforeunload", () => {
if (typeof showLoader === 'function') {
showLoader();
}
});
// Cacher le loader quand la page est complètement chargée
window.addEventListener("load", () => {
if (typeof hideLoader === 'function') {
// Petit délai pour éviter le flash
setTimeout(hideLoader, 100);
}
});
});

View File

@ -1,2 +0,0 @@
Pocketbase_0.7.5.exe serve --http="127.0.0.1:8091"
pause

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

13
etv2/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Ignore files type
*.log
*.env
*.exe
*.wbk
*.cmd
*~*
# Ignore directory
**/vbs/
**/node_modules/
**/logs/
**/.vscode/

2
etv2/README.md Normal file
View File

@ -0,0 +1,2 @@
Description
EasyTransport est une application en cours de transition technologique, destinée à la plateforme AxA IARD Transport. Le backend est écrit en Node.js avec une base de données embarquée PocketBase, et le frontend utilise EJS et Materialize CSS. L'application propose divers modules tels que la tarification, la génération de contrats à partir de formulaires, l'authentification via JWT, et la génération d'attestations.

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,9 @@
"test": "jest"
},
"pkg": {
"assets": ["public/**"]
"assets": [
"public/**"
]
},
"keywords": [],
"author": "cyril.ducaffy@axa.fr",

View File

@ -512,49 +512,3 @@ a.grille-garanties:hover{
@keyframes l13 {
100% { transform: rotate(1turn); }
}
/* Message d'erreur du loader */
#error-message {
display: none;
color: #ff4444;
font-weight: bold;
text-align: center;
margin-top: 20px;
white-space: pre-line;
font-size: 16px;
}
/* Message de timeout du loader */
#timeout-message {
display: none;
margin-top: 30px;
text-align: center;
color: #d0d0d0;
font-size: 14px;
max-width: 420px;
line-height: 1.6;
padding: 0 20px;
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Lien cliquable pour annuler le chargement */
#cancel-loading-link {
color: #66B2FF;
text-decoration: underline;
text-underline-offset: 3px;
text-decoration-thickness: 1px;
cursor: pointer;
transition: all 0.2s ease;
font-weight: 500;
}
#cancel-loading-link:hover {
color: #90CAF9;
text-decoration-thickness: 2px;
text-shadow: 0 0 10px rgba(102, 178, 255, 0.6);
}

View File

@ -0,0 +1,66 @@
/* Overlay loader (css pris du site https://css-loaders.com/)*/
#loader-overlay {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: linear-gradient(
rgba(10, 20, 60, 0.2),
rgba(0, 0, 0, 0.4)
);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
font-family: 'Roboto', sans-serif;
opacity: 0;
backdrop-filter: blur(0px);
pointer-events: none;
transition: opacity 0.5s ease, backdrop-filter 0.5s ease;
}
#loader-overlay.active {
opacity: 1;
backdrop-filter: blur(3px);
pointer-events: all;
}
#loader-overlay.hidden {
display: none;
}
/* Spinner wrapper (fade/slide) */
.loader-spin-wrap {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.5s ease, transform 0.5s ease;
transition-delay: 0.5s; /* apparaît après 0.5s */
}
#loader-overlay.active .loader-spin-wrap {
opacity: 1;
transform: translateY(0);
}
/* Spinner circulaire */
.loader-spin {
width: 50px;
aspect-ratio: 1;
border-radius: 50%;
mask:1;
background:
radial-gradient(farthest-side,darkblue 94%,transparent) top/8px 8px no-repeat,
conic-gradient(transparent 30%,darkblue);
-webkit-mask: radial-gradient(farthest-side,transparent calc(100% - 8px),#000 0);
animation: l13 1s infinite linear;
}
@keyframes l13 {
100% { transform: rotate(1turn); }
}
/* Erreur */
#error-message {
display: none;
color: red;
font-weight: bold;
text-align: center;
margin-top: 20px;
white-space: pre-line;
}

Some files were not shown because too many files have changed in this diff Show More