Files
ludikevent_crm/assets/admin.js
Serreau Jovann 4c14932fee ```
 feat(Devis.php): Ajoute adresses de facturation et de livraison au devis.

🔒️ fix(IntranetLocked.php): Autorise l'accès à la route st_control en mode debug.

 feat(CustomerAddress.php): Gère les adresses de facturation et livraison.

 feat: Ajoute la console superadmin pour le contrôle système.

 feat(DevisController.php): Supprime la génération PDF temporaire.

 feat(st_control.js): Ajoute la logique de contrôle système via JS.

 feat: Crée les templates CGV, Cookies, Hébergement et RGPD.

🎨 style(app.scss): Ajoute un style de fond pour la console.

 feat: Ajoute le template pour les informations d'hébergement.

 feat: Crée un template de mail d'alerte pour les accès root.

 feat: Crée le template RGPD (données personnelles).

🐛 fix(ErrorListener.php): Gère les erreurs 404 en prod (JSON/HTML).

 feat: Ajoute les mentions légales.

 feat(DevisPdfService.php): Améliore la génération PDF du devis.

 feat(admin.js): Charge dynamiquement les produits dans le select.

 feat(add.twig): Ajoute un sélecteur de produit et d'autres champs.

 chore(config): Ajoute INTRANET_LOCK à l'env.
```
2026-01-19 13:52:41 +01:00

186 lines
6.9 KiB
JavaScript

import './admin.scss'
import * as Sentry from "@sentry/browser";
import * as Turbo from "@hotwired/turbo";
import TomSelect from "tom-select";
import {RepeatLine} from "./libs/RepeatLine.js";
import {DevisManager} from "./libs/DevisManager.js";
// --- INITIALISATION SENTRY (En premier !) ---
Sentry.init({
dsn: "https://803814be6540031b1c37bf92ba9c0f79@sentry.esy-web.dev/24",
tunnel: "/sentry-tunnel",
sendDefaultPii: true,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration()
],
tracesSampleRate: 1.0,
tracePropagationTargets: ["localhost", "esy-web.dev"], // Remplace par ton domaine réel
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0
});
/**
* Initialise les composants de l'interface d'administration.
*/
function initAdminLayout() {
if (!customElements.get('copy-text')) {
customElements.define('repeat-line', RepeatLine, {extends: 'div'})
customElements.define('devis-manager', DevisManager, {extends: 'div'})
}
document.querySelectorAll('select').forEach((el) => {
if (!el.tomselect) { // Éviter la double initialisation avec Turbo
if(el.getAttribute('data-load') == "product") {
fetch("/crm/product/json")
.then(r=>r.json())
.then(products=>{
})
} else {
new TomSelect(el, {
controlInput: null,
allowEmptyOption: true,
highlight: true,
plugins: ['dropdown_input'], // Permet d'avoir la recherche dans le dropdown
render: {
option: function (data, escape) {
return `<div class="py-2 px-3">
<div class="text-[13px] font-bold text-white">${escape(data.text)}</div>
</div>`;
},
item: function (data, escape) {
return `<div class="text-blue-400 font-bold">${escape(data.text)}</div>`;
}
}
});
}
}
});
const imageInput = document.getElementById('product_image_input');
const previewImage = document.getElementById('product-image-preview');
const placeholderIcon = document.getElementById('product-image-placeholder');
if (imageInput) {
imageInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
previewImage.src = e.target.result;
previewImage.classList.remove('hidden');
if (placeholderIcon) {
placeholderIcon.classList.add('hidden');
}
};
reader.readAsDataURL(file);
}
});
}
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebar-overlay');
const toggleBtn = document.getElementById('sidebar-toggle');
const settingsToggle = document.getElementById('settings-toggle');
const settingsSubmenu = document.getElementById('settings-submenu');
// --- 1. GESTION DE LA SIDEBAR (MOBILE) ---
if (toggleBtn && sidebar && overlay) {
toggleBtn.onclick = () => {
sidebar.classList.toggle('-translate-x-full');
overlay.classList.toggle('hidden');
};
overlay.onclick = () => {
sidebar.classList.add('-translate-x-full');
overlay.classList.add('hidden');
};
}
// --- 2. GESTION DU DROPDOWN (PARAMÈTRES) ---
if (settingsToggle && settingsSubmenu) {
const settingsChevron = settingsToggle.querySelector('svg:last-child');
const toggleDropdown = (show, animate = true) => {
if (!animate) settingsSubmenu.style.transition = 'none';
if (show) {
settingsSubmenu.classList.remove('hidden');
settingsSubmenu.style.maxHeight = settingsSubmenu.scrollHeight + "px";
settingsChevron?.classList.add('rotate-180');
localStorage.setItem('admin_settings_open', 'true');
} else {
settingsSubmenu.style.maxHeight = "0px";
settingsChevron?.classList.remove('rotate-180');
localStorage.setItem('admin_settings_open', 'false');
if (animate) {
setTimeout(() => {
if (settingsSubmenu.style.maxHeight === "0px") {
settingsSubmenu.classList.add('hidden');
}
}, 300);
} else {
settingsSubmenu.classList.add('hidden');
}
}
if (!animate) {
settingsSubmenu.offsetHeight; // force redraw
settingsSubmenu.style.transition = '';
}
};
settingsToggle.onclick = (e) => {
e.preventDefault();
const isClosed = settingsSubmenu.style.maxHeight === "0px" || settingsSubmenu.classList.contains('hidden');
toggleDropdown(isClosed);
};
// PERSISTANCE
const isSettingsRoute = window.location.pathname.includes('/crm/administrateur') ||
window.location.pathname.includes('/crm/logs');
const wasOpen = localStorage.getItem('admin_settings_open') === 'true';
if (isSettingsRoute || wasOpen) {
toggleDropdown(true, false);
}
// HIGHLIGHT
settingsSubmenu.querySelectorAll('a').forEach(link => {
if (window.location.pathname === link.getAttribute('href')) {
link.classList.add('text-blue-600', 'dark:text-blue-400', 'font-semibold');
link.classList.remove('text-slate-500');
}
});
}
// --- 3. GESTION DES MESSAGES FLASH ---
document.querySelectorAll('.flash-message').forEach((flash) => {
setTimeout(() => {
flash.classList.add('opacity-0', 'translate-x-10');
setTimeout(() => flash.remove(), 500);
}, 8000);
});
}
// --- CORRECTIF DATA-TURBO-CONFIRM ---
document.addEventListener("turbo:click", (event) => {
const message = event.target.closest("[data-turbo-confirm]")?.getAttribute("data-turbo-confirm");
if (message && !confirm(message)) {
event.preventDefault();
}
});
document.addEventListener('turbo:load', initAdminLayout);
document.addEventListener('turbo:before-cache', () => {
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebar-overlay');
if (sidebar) sidebar.classList.add('-translate-x-full');
if (overlay) overlay.classList.add('hidden');
});