first commit

This commit is contained in:
mrtoine 2025-09-20 13:18:04 +02:00
commit e6c52820cd
227 changed files with 16156 additions and 0 deletions

190
static/js/main.js Normal file
View file

@ -0,0 +1,190 @@
// Suite Consultance - Script principal
document.addEventListener('DOMContentLoaded', function() {
// Gestion du mode sombre
const darkModeSwitch = document.getElementById('darkModeSwitch');
if (darkModeSwitch) {
// Initialisation du mode sombre selon la préférence enregistrée
if (localStorage.getItem('darkMode') === 'enabled') {
document.body.classList.add('dark-mode');
darkModeSwitch.checked = true;
updateDarkModeIcon(true);
} else {
updateDarkModeIcon(false);
}
// Écouteur d'événement pour le changement de mode
darkModeSwitch.addEventListener('change', function() {
const isDarkMode = this.checked;
document.body.classList.toggle('dark-mode', isDarkMode);
localStorage.setItem('darkMode', isDarkMode ? 'enabled' : 'disabled');
updateDarkModeIcon(isDarkMode);
// Mettre à jour un attribut de données pour que d'autres scripts puissent détecter le mode
document.body.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
// Déclencher un événement personnalisé pour informer d'autres scripts du changement
const event = new CustomEvent('themeChanged', { detail: { darkMode: isDarkMode } });
document.dispatchEvent(event);
});
}
// Gestion des couleurs de modules
setModuleColors();
// Mise à jour de l'icône du mode sombre
function updateDarkModeIcon(isDarkMode) {
const darkModeLabel = document.querySelector('label[for="darkModeSwitch"]');
if (darkModeLabel) {
darkModeLabel.innerHTML = isDarkMode ?
'<i class="fas fa-moon"></i>' :
'<i class="fas fa-sun"></i>';
}
}
// Initialisation des tooltips Bootstrap
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// Initialisation des popovers Bootstrap
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl);
});
// Fermeture automatique des alertes après 5 secondes
setTimeout(function() {
var alerts = document.querySelectorAll('.alert');
alerts.forEach(function(alert) {
var bsAlert = new bootstrap.Alert(alert);
bsAlert.close();
});
}, 5000);
// Activation des onglets via URL hash
if (window.location.hash) {
const hash = window.location.hash.substring(1);
const tabEl = document.querySelector(`#${hash}-tab`);
if (tabEl) {
const tab = new bootstrap.Tab(tabEl);
tab.show();
}
}
// Navigation entre les onglets avec historique
document.querySelectorAll('[data-bs-toggle="tab"]').forEach(tabEl => {
tabEl.addEventListener('shown.bs.tab', function(event) {
const id = event.target.getAttribute('data-bs-target').substring(1).replace('-tab-pane', '');
history.replaceState(null, null, `#${id}`);
});
});
// Gestion de la recherche dynamique dans les tableaux
document.querySelectorAll('.search-input').forEach(input => {
input.addEventListener('keyup', function() {
const searchTerm = this.value.toLowerCase();
const tableId = this.getAttribute('data-table');
const table = document.getElementById(tableId);
if (table) {
const rows = table.querySelectorAll('tbody tr');
rows.forEach(row => {
const text = row.textContent.toLowerCase();
if (text.indexOf(searchTerm) > -1) {
row.style.display = "";
} else {
row.style.display = "none";
}
});
}
});
});
// Confirmation pour les actions de suppression
document.querySelectorAll('.delete-confirm').forEach(btn => {
btn.addEventListener('click', function(e) {
if (!confirm('Êtes-vous sûr de vouloir supprimer cet élément ? Cette action est irréversible.')) {
e.preventDefault();
}
});
});
// Sélection automatique d'un client depuis l'URL
const urlParams = new URLSearchParams(window.location.search);
const clientId = urlParams.get('client_id');
if (clientId) {
const clientSelect = document.getElementById('client_select');
if (clientSelect) {
// Sélectionner le client dans la liste déroulante
Array.from(clientSelect.options).forEach(option => {
if (option.value === clientId) {
option.selected = true;
// Déclencher un événement change
const event = new Event('change');
clientSelect.dispatchEvent(event);
}
});
}
}
// Fonction pour définir les couleurs des modules en fonction de la page active
function setModuleColors() {
const navbar = document.querySelector('.navbar');
const currentPath = window.location.pathname;
// Récupérer le module défini dans le HTML via l'attribut data-module
const moduleFromBody = document.body.getAttribute('data-module');
let activeModule = 'default';
// Si le module est défini dans le corps, l'utiliser
if (moduleFromBody && moduleFromBody !== 'default') {
activeModule = moduleFromBody;
}
// Sinon, l'inférer à partir du chemin
else if (currentPath.startsWith('/crm')) {
activeModule = 'crm';
} else if (currentPath.startsWith('/propositions')) {
activeModule = 'propositions';
} else if (currentPath.startsWith('/devis')) {
activeModule = 'devis';
}
// Mettre à jour l'attribut data-module si nécessaire
if (document.body.getAttribute('data-module') !== activeModule) {
document.body.setAttribute('data-module', activeModule);
}
// Réinitialiser toutes les classes de modules
navbar.classList.remove('navbar-module-crm', 'navbar-module-propositions', 'navbar-module-devis');
// Ajouter les classes en fonction du module actif
if (activeModule === 'crm') {
navbar.classList.add('navbar-module-crm');
updateButtonsForModule('crm');
} else if (activeModule === 'propositions') {
navbar.classList.add('navbar-module-propositions');
updateButtonsForModule('propositions');
} else if (activeModule === 'devis') {
navbar.classList.add('navbar-module-devis');
updateButtonsForModule('devis');
}
}
// Mise à jour des boutons pour le module actif
function updateButtonsForModule(moduleName) {
// Remplacer les classes des boutons primaires par les classes du module
document.querySelectorAll('.btn-primary').forEach(btn => {
btn.classList.remove('btn-primary');
btn.classList.add(`btn-${moduleName}`);
});
document.querySelectorAll('.btn-outline-primary').forEach(btn => {
btn.classList.remove('btn-outline-primary');
btn.classList.add(`btn-outline-${moduleName}`);
});
}
});