✨ feat(FormulesController): Ajoute la page et formulaire de création de formules
Ajoute la route, le controller et le formulaire pour créer des formules
(packs ou formules libres). Inclut la gestion de l'upload d'image.
```
//todo add seleted produit inclus and option pack if packmode selected, if free selected add line ("X structure") avec liste des produit allow in line
152 lines
5.4 KiB
JavaScript
152 lines
5.4 KiB
JavaScript
import './admin.scss';
|
|
import * as Sentry from "@sentry/browser";
|
|
import * as Turbo from "@hotwired/turbo";
|
|
|
|
import { RepeatLine } from "./libs/RepeatLine.js";
|
|
import { DevisManager } from "./libs/DevisManager.js";
|
|
import { initTomSelect } from "./libs/initTomSelect.js";
|
|
import { SearchProduct,SearchOptions } from "./libs/SearchProduct.js";
|
|
import { SearchProductDevis,SearchOptionsDevis } from "./libs/SearchProductDevis.js";
|
|
// --- INITIALISATION SENTRY ---
|
|
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"],
|
|
replaysSessionSampleRate: 0.1,
|
|
replaysOnErrorSampleRate: 1.0
|
|
});
|
|
|
|
function initImagePreview() {
|
|
const input = document.getElementById('product_image_input');
|
|
const preview = document.getElementById('product-image-preview');
|
|
const placeholder = document.getElementById('product-image-placeholder');
|
|
|
|
if (input && preview) {
|
|
input.addEventListener('change', function(event) {
|
|
const file = event.target.files[0];
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
reader.onload = function(e) {
|
|
preview.src = e.target.result;
|
|
preview.classList.remove('hidden');
|
|
if (placeholder) placeholder.classList.add('hidden');
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gère le filtrage dynamique des listes (Contrats, Devis, etc.)
|
|
*/
|
|
function initDynamicSearch() {
|
|
const searchInput = document.getElementById('searchContrat');
|
|
const listContainer = document.getElementById('contratsList');
|
|
|
|
if (searchInput && listContainer) {
|
|
searchInput.addEventListener('input', function() {
|
|
const filter = this.value.toLowerCase();
|
|
const cards = listContainer.querySelectorAll('.contrat-card');
|
|
|
|
cards.forEach(card => {
|
|
// On récupère tout le texte de la carte pour une recherche globale
|
|
const content = card.textContent.toLowerCase();
|
|
|
|
if (content.includes(filter)) {
|
|
card.classList.remove('hidden');
|
|
// Optionnel : petite animation de ré-apparition
|
|
card.style.opacity = "1";
|
|
card.style.transform = "scale(1)";
|
|
} else {
|
|
card.classList.add('hidden');
|
|
card.style.opacity = "0";
|
|
card.style.transform = "scale(0.95)";
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Initialise les composants de l'interface d'administration.
|
|
*/
|
|
function initAdminLayout() {
|
|
initDynamicSearch();
|
|
initImagePreview();
|
|
// Enregistrement des Custom Elements
|
|
if (!customElements.get('repeat-line')) {
|
|
customElements.define('repeat-line', RepeatLine, { extends: 'div' });
|
|
}
|
|
if (!customElements.get('devis-manager')) {
|
|
customElements.define('devis-manager', DevisManager, { extends: 'div' });
|
|
}
|
|
|
|
if (!customElements.get('search-product')) {
|
|
customElements.define('search-product', SearchProduct, { extends: 'button' });
|
|
}
|
|
if (!customElements.get('search-options')) {
|
|
customElements.define('search-options', SearchOptions, { extends: 'button' });
|
|
}
|
|
if (!customElements.get('search-productdevis')) {
|
|
customElements.define('search-productdevis', SearchProductDevis, { extends: 'button' });
|
|
}
|
|
if (!customElements.get('search-optionsdevis')) {
|
|
customElements.define('search-optionsdevis', SearchOptionsDevis, { extends: 'button' });
|
|
}
|
|
// S
|
|
// Sidebar & UI
|
|
const sidebar = document.getElementById('sidebar');
|
|
const overlay = document.getElementById('sidebar-overlay');
|
|
const toggleBtn = document.getElementById('sidebar-toggle');
|
|
|
|
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');
|
|
};
|
|
}
|
|
|
|
// Dropdown Paramètres
|
|
const settingsToggle = document.getElementById('settings-toggle');
|
|
const settingsSubmenu = document.getElementById('settings-submenu');
|
|
if (settingsToggle && settingsSubmenu) {
|
|
settingsToggle.onclick = (e) => {
|
|
e.preventDefault();
|
|
settingsSubmenu.classList.toggle('hidden');
|
|
const isOpen = !settingsSubmenu.classList.contains('hidden');
|
|
localStorage.setItem('admin_settings_open', isOpen);
|
|
};
|
|
}
|
|
|
|
// Flash messages
|
|
document.querySelectorAll('.flash-message').forEach((flash) => {
|
|
setTimeout(() => {
|
|
flash.classList.add('opacity-0', 'translate-x-10');
|
|
setTimeout(() => flash.remove(), 500);
|
|
}, 5000);
|
|
});
|
|
}
|
|
|
|
// Turbo Hooks
|
|
document.addEventListener('turbo:load', () => {
|
|
initAdminLayout();
|
|
initTomSelect(); // Init au chargement de la page
|
|
});
|
|
|
|
document.addEventListener("turbo:click", (event) => {
|
|
const message = event.target.closest("[data-turbo-confirm]")?.getAttribute("data-turbo-confirm");
|
|
if (message && !confirm(message)) {
|
|
event.preventDefault();
|
|
}
|
|
});
|