feat(Product.php): Ajoute ProductDoc pour gérer les documents.
 feat(Contrats.php): Gère les fichiers du contrat via VichUploader.
 feat(templates): Crée template mail signature contrat.
 feat(SignatureController): Ajoute la signature du contrat.
 feat(ContratsController): Crée contrat depuis devis et liste contrats.
 feat(Client): Crée soumission contrat Docuseal.
 feat(DevisPdfService): Corrige l'assurance RC Pro.
 feat(.env): Ajoute CONTRAT_BASEURL.
 feat(ProductDocType): Crée formulaire pour les documents produit.
 feat(contrats/list.twig): Liste et actions pour les contrats.
 feat(UtmEvent.js): Track click document produit.
 feat(ContratEvent.php): Crée event pour envoi contrat.
 feat(admin.js): Initialise la recherche dynamique des contrats.
 feat(ContratPdfService): Génère le PDF du contrat DocuSeal.
 feat(products/add.twig): Ajoute gestion des documents produits.
 feat(ContratController): Crée controlleur contrat.
 feat(ContratSubscriber.php): Envoi du contrat par email.
 feat(reservation/produit.twig): Affiche les documents produit.
 feat(ProductController.php): Refactorisation et ajout des documents.
```
This commit is contained in:
Serreau Jovann
2026-01-22 15:58:57 +01:00
parent 9eafbbe2d9
commit afa6133907
32 changed files with 2263 additions and 286 deletions

View File

@@ -21,14 +21,41 @@ Sentry.init({
replaysOnErrorSampleRate: 1.0
});
// Cache global pour éviter de fetch les produits à chaque nouvelle ligne
let productCache = null;
/**
* 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();
// Enregistrement des Custom Elements
if (!customElements.get('repeat-line')) {
customElements.define('repeat-line', RepeatLine, { extends: 'div' });