Analyse des templates pour l'internationalisation =================================================== 📄 admin/annonce/index.html.twig ------------------------------------------------------------ • Administration des Petites Annonces • Retour Dashboard • Nouvelle Annonce • Total annonces • Actives • En attente • Rejetées • Premium • Expirées • Recherche • Statut • Tous • Active • Rejetée • Expirée • Catégorie • Toutes • Prix min • Prix max • Sélectionner tout • Approuver • Rejeter • Supprimer • Annonce • Auteur • Prix • Expiration • Actions • Membre supprimé • Non classé • Prix non spécifié • (Expirée) • (Bientôt) • Permanente • Aucune annonce trouvée • Les petites annonces apparaîtront ici une fois créées. • Confirmer la suppression • Êtes-vous sûr de vouloir supprimer l'annonce • Cette action est irréversible. • Annuler • Titre, description... • Voir • Modifier 📄 admin/dashboard.html.twig ------------------------------------------------------------ • Tableau de bord - AEF Administration • Utilisateurs • Membres • Articles • Commandes • Activité récente • Dernières actions sur le site • Nouveaux utilisateurs aujourd'hui • Articles publiés cette semaine • Commandes en attente • Actions rapides • Ajouter un utilisateur • Ajouter un article • Gérer les membres 📄 admin/email_test/index.html.twig ------------------------------------------------------------ • Test des emails • Administration • Email de test simple • Envoie un email de test basique pour vérifier la configuration du mailer. • Email de destination : • Envoyer test • Formulaire de contact • Teste l'envoi des emails de contact (admin + confirmation). • Information générale • Problème technique • Autre • Ceci est un message de test pour vérifier le système d'emails. • Tester contact • Emails pour membres • Sélectionner un membre : • Chargement des membres... • Types d'emails à tester : • Bienvenue • Échec paiement 1 • Échec paiement 2 • Échec paiement 3 • Suspension • Récupération • Informations importantes : • Les emails sont envoyés via le système de notification configuré • Vérifiez les logs en cas d'erreur d'envoi • Les emails de test utilisent les vraies adresses des membres • En environnement de développement, les emails peuvent être interceptés • { const select = document.getElementById('memberSelect'); select.innerHTML = ' • -- Sélectionner un membre -- • { console.error('Erreur lors du chargement des membres:', error); document.getElementById('memberSelect').innerHTML = ' • Erreur de chargement • Nom • Email • Message de test 📄 admin/fair/index.html.twig ------------------------------------------------------------ • Administration des Salons & Foires • Retour Dashboard • Nouveau Salon • Salons actifs • À venir • Terminés • Organisateurs • Recherche • Statut • Tous • Actif • Terminé • Annulé • Ville • Date début • Date fin • Salon • Organisateur • Lieu • Dates • Participants • Actions • Non assigné • Aucune date • Aucun salon trouvé • Commencez par créer votre premier salon d'antiquités. • Créer un salon • Confirmer la suppression • Êtes-vous sûr de vouloir supprimer le salon • Cette action est irréversible. • Annuler • Supprimer • Nom du salon... • Ville... • Voir • Modifier 📄 admin/gdpr/dashboard.html.twig ------------------------------------------------------------ • Administration RGPD & Sécurité • Gestion centralisée de la conformité RGPD, audit des données et traçabilité des actions sensibles. • Comptes anonymisés • Objets supprimés • Abonnements orphelins • Logs critiques récents • Actions de maintenance RGPD • Nettoyage des comptes supprimés • Supprimer définitivement les comptes anonymisés anciens pour optimiser l'espace de stockage. • Plus de 30 jours • Plus de 60 jours • Plus de 90 jours • Plus de 1 an • Nettoyer • Export de conformité • Générer un rapport de conformité RGPD pour audit externe. • Générer rapport • Statistiques • Voir tous les logs • Comptes supprimés récents • Email • Suppression • Actions • Aucun compte supprimé récemment • Date • Action • Membre • Détails • Membre supprimé • Voir tous les logs → • // Nettoyage des comptes document.getElementById('cleanupForm').addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); const daysOld = formData.get('days_old'); if (!confirm(`Êtes-vous sûr de vouloir supprimer définitivement tous les comptes anonymisés depuis plus de ${daysOld} jours ?`)) { return; } const btn = this.querySelector('button'); const originalText = btn.innerHTML; btn.disabled = true; btn.innerHTML = ' • { const resultDiv = document.getElementById('cleanupResult'); if (data.success) { resultDiv.innerHTML = ` • location.reload(), 2000); } else { resultDiv.innerHTML = ` • { document.getElementById('cleanupResult').innerHTML = ` • Erreur: ${error.message} • { btn.disabled = false; btn.innerHTML = originalText; }); }); // Export de conformité document.getElementById('exportCompliance').addEventListener('click', function() { this.disabled = true; this.innerHTML = ' • { alert('Fonctionnalité d\'export en cours de développement'); this.disabled = false; this.innerHTML = ' • Générer rapport'; }, 2000); }); // Suppression définitive d'un membre function hardDeleteMember(memberId) { if (!confirm('Êtes-vous ABSOLUMENT sûr de vouloir supprimer définitivement ce membre ?\n\nCette action est IRRÉVERSIBLE.')) { return; } // À implémenter : appel AJAX pour suppression définitive alert('Fonctionnalité de suppression définitive en cours d\'implémentation'); } • Suppression définitive 📄 admin/infrastructure/status.html.twig ------------------------------------------------------------ • État de l'Infrastructure • Actualiser • {# Résumé global #} • État des Services • Elasticsearch: • Base de données: • Stockage: • Dernière mise à jour: 📄 admin/mag/index.html.twig ------------------------------------------------------------ • Administration du Magazine • Retour Dashboard • Nouvel Article • Total articles • Publiés • Brouillons • Programmés • Vues totales • Catégories • Recherche • Statut • Tous • Publié • Brouillon • Programmé • Archivé • Catégorie • Toutes • Auteur • Date • Sélectionner tout • Publier • Archiver • Supprimer • Article • Publication • Vues • Actions • À la une • Auteur supprimé • Non classé • Programmé pour: • Non publié • Aucun article trouvé • Commencez par créer votre premier article de magazine. • Créer un article • Confirmer la suppression • Êtes-vous sûr de vouloir supprimer l'article • Cette action est irréversible et supprimera toutes les vues et commentaires associés. • Annuler • Titre, contenu... • Article populaire • Voir • Modifier • Dépublier • Voir sur le site 📄 admin/members/advanced_detail.html.twig ------------------------------------------------------------ • Jours d'ancienneté • Abonnements • Objets créés • Revenus générés • Échecs paiement • Historique des Abonnements • Aucun abonnement trouvé. • Périodes d'Essai • Aucune période d'essai trouvée. • Échecs de Paiement • Aucun échec de paiement. • Journal d'Audit • Aucune entrée d'audit. • Voir les changements • Avant: • Après: • Actions Rapides • Modifier les Informations • Changer le Plan • Suspendre le Membre • Réactiver le Membre • Traiter un Remboursement • Exporter les Données (RGPD) • Historique Complet • Informations Système • ID Membre: • Créé le: • Dernière connexion: • Email vérifié: • Non vérifié • Changer le Plan d'Abonnement • Nouveau Plan * • Gratuit • Premium • Raison du changement * • Proratiser la facturation • Annuler • Montant à rembourser (€) * • Devise • ID Payment Intent Stripe (optionnel) • Raison du remboursement * • Traiter le Remboursement • { if (data.success) { alert('Remboursement traité avec succès. ID: ' + data.refund_id); location.reload(); } else { alert('Erreur: ' + data.message); } }); } 📄 admin/members/advanced_index.html.twig ------------------------------------------------------------ • .stats-card { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px; padding: 1.5rem; margin-bottom: 1rem; } .stats-card h3 { margin: 0; font-size: 2rem; font-weight: bold; } .stats-card p { margin: 0.5rem 0 0 0; opacity: 0.9; } .search-form { background: #f8f9fa; padding: 2rem; border-radius: 10px; margin-bottom: 2rem; } .member-card { border: 1px solid #dee2e6; border-radius: 8px; padding: 1.5rem; margin-bottom: 1rem; transition: all 0.3s ease; } .member-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); transform: translateY(-2px); } .status-badge { padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.875rem; font-weight: 500; } .status-active { background: #d4edda; color: #155724; } .status-suspended { background: #f8d7da; color: #721c24; } .status-pending { background: #fff3cd; color: #856404; } .plan-badge { padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.875rem; font-weight: 500; } .plan-premium { background: #ffd700; color: #333; } .plan-free { background: #e9ecef; color: #495057; } .quick-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; } .quick-actions .btn { padding: 0.25rem 0.75rem; font-size: 0.875rem; } • Gestion Avancée des Membres • Actions Critiques • Statistiques Audit • Total Membres • Actifs • Premium • Suspendus • Nouveaux (30j) • Taux Premium • Recherche Avancée • Email • Nom/Prénom/Société • Statut • Tous les statuts • Plan • Tous les plans • Rechercher • Créé après • Créé avant • Avec abonnement actif • Avec échecs de paiement • Effacer la recherche • Inscrit le • Détails • Modifier • Suspendre • Réactiver • Aucun résultat • Suspendre le Membre • Raison de la suspension * • Suspension jusqu'au (optionnel) • Masquer les objets du membre • Annuler • Réactiver le Membre • Raison de la réactivation * • { // Implémentation de l'auto-complétion si nécessaire console.log('Search results:', data); }); } }); • Rechercher par email... • Rechercher par nom... 📄 admin/payment_failures/details.html.twig ------------------------------------------------------------ • Membre : • ← Retour à la liste • Résoudre • ⚠️ Attention ! • 🚫 Compte Suspendu • Ce compte a été suspendu suite à l'expiration de la période de grâce. • ✅ Résolu • Informations Générales • Statut • Date de l'échec • Raison • Nombre de tentatives • Critique • Élevé • Prochaine tentative • Informations Membre • Email • Nom • Plan actuel • Non défini • Statut membre • Période de Grâce • Date de début • Date de fin • Jours restants • Objets masqués • ✓ Oui • Non • Informations Stripe • ID Facture Stripe • ID Client Stripe • Code erreur Stripe • Chronologie • Échec de paiement initial • Tentatives de relance • Période de grâce démarrée • Les objets du membre ont été masqués • Compte suspendu • Suite à l'expiration de la période de grâce • Problème résolu • Actions Administrateur • ✅ Résoudre l'échec • 👤 Voir le profil membre • �� Voir l'abonnement • { alert('Erreur de communication avec le serveur'); }); } } 📄 admin/payment_failures/index.html.twig ------------------------------------------------------------ • Gestion des Échecs de Paiement • Traiter les Périodes Expirées • Total Échecs • En Attente • Période de Grâce • Grâce Expirée • Taux d'Échec • Échecs Récents (En Attente) • Membre • Date Échec • Raison • Tentatives • Statut • Actions • Résoudre • Détails • Périodes de Grâce Actives • Fin de Grâce • Jours Restants • Objets Masqués • ✓ Masqués • Non • Jours Dépassés • 🎉 Aucun échec de paiement en cours ! • Tous les paiements sont à jour. • { alertDiv.remove(); }, 5000); } 📄 admin/paypal/index.html.twig ------------------------------------------------------------ • Administration PayPal • Retour Dashboard • Webhooks • Paiements total • Montant total • En attente • Échoués • Évolution des revenus PayPal (12 derniers mois) • Répartition par statut • Recherche • Statut • Tous • Complété • Échoué • Annulé • Remboursé • Montant min • Montant max • Date début • Exporter • Actualiser • ID PayPal • Objet • Acheteur • Vendeur • Montant • Date • Actions • Objet supprimé • Vendeur supprimé • Aucun paiement PayPal trouvé • Les paiements PayPal apparaîtront ici une fois effectués. • Détails du paiement PayPal • Chargement des détails... • { document.getElementById('paymentDetailsContent').innerHTML = ' • Erreur lors du chargement des détails. • ID PayPal, email... • Détails • Vérifier statut • Rembourser 📄 admin/performance/index.html.twig ------------------------------------------------------------ • Monitoring des Performances • Retour Dashboard • Actualiser • Temps de réponse moyen • Utilisation mémoire • Utilisation CPU • Requêtes lentes • Temps de réponse (24 dernières heures) • Répartition des erreurs • Alertes critiques • Aucune alerte critique • Recommandations • Action • Performances optimales • Requête • Durée • Occurrences • Dernière exécution • Actions • Aucune requête lente détectée • Toutes les requêtes s'exécutent rapidement. • Outils d'optimisation • Nettoyage cache • Vider tous les caches • Nettoyer • Optimiser BDD • Réorganiser les tables • Optimiser • Réindexer • Elasticsearch • Logs système • Nettoyer les logs • Détails de la requête • { // Mettre à jour les cartes de métriques updateMetrics(data); }); }, 30000); function updateMetrics(data) { // Mise à jour des métriques en temps réel // Cette fonction peut être développée pour mettre à jour les valeurs sans recharger la page } 📄 admin/seo/index.html.twig ------------------------------------------------------------ • Administration SEO • Dashboard • Sitemap XML • Gérez et visualisez le sitemap XML de votre site. • Prévisualiser • Voir le sitemap • Robots.txt • Configuration des directives pour les robots d'indexation. • Voir robots.txt • Meta Tags • Testez et prévisualisez les meta tags générés automatiquement. • Tester les meta tags • Google Analytics • Configuration et suivi Google Analytics. • Configuration • Script JS • Outils SEO • Outils avancés • Search Console • Bing Webmaster • Aperçu SEO • Généré automatiquement • Configuré par environnement • Dynamiques par page • Schema.org • Données structurées 📄 admin/seo/meta_test.html.twig ------------------------------------------------------------ • Test des Meta Tags • Dashboard • Meta Tags • Meta Tags de Base • Données générées : • Rendu HTML : • Aperçu Google : • Données Structurées Schema.org : • Antiquaire • Catégorie • Outils de Validation • Test Rich Results • Facebook Debugger • Twitter Card Validator 📄 admin/translations/index.html.twig ------------------------------------------------------------ • Système de Traduction Automatique • Gérez les traductions automatiques des objets avec OpenAI • Objets Total • Avec Traductions • Sans Traductions • Langues Supportées • Actions de Traduction • Traduire 10 Objets Récents • Mettre à Jour Traductions Obsolètes • Langue Source • Statistiques par Langue • Aucune traduction disponible • Traductions Récentes • Objet • Langue • Titre Traduit • Date • Actions • Chargement... • Traduction en cours... • { $('#loadingModal').modal('hide'); alert('Erreur réseau: ' + error.message); }); } • Voir détails 📄 base.html.twig ------------------------------------------------------------ • /* Styles personnalisés pour le header */ .navbar .nav-link { font-weight: bold !important; } .navbar .dropdown-toggle { font-weight: bold !important; } .aef-logo-container { background: none !important; border-radius: 0 !important; padding: 0 !important; } .aef-logo { background: none !important; } /* Z-index pour la navbar - CORRIGÉ POUR ÉVITER CONFLITS AVEC MODALES */ .navbar { z-index: 10 !important; position: relative; } /* Styles pour la barre de recherche - Z-INDEX RÉDUIT */ .search-bar { background-color: #f8f9fa !important; border-top: 1px solid #e9ecef; border-bottom: none; z-index: 9 !important; position: relative; margin-bottom: 0; } .search-bar .form-control { border-radius: 0.375rem 0 0 0.375rem; border-right: none; border-color: #ced4da; font-size: 0.9rem; padding: 0.5rem 0.75rem; } .search-bar .btn { border-radius: 0 0.375rem 0.375rem 0; border-color: #ced4da; padding: 0.5rem 0.75rem; } .search-bar .input-group { max-width: 400px; margin: 0 auto; } .search-bar .form-control:focus { border-color: #86b7fe; box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); } @media (max-width: 768px) { .search-bar .input-group { max-width: 100%; } } /* Styles pour les langues RTL (arabe, hébreu) */ .rtl { direction: rtl; text-align: right; } .rtl .navbar-nav { flex-direction: row-reverse; } .rtl .navbar-brand { margin-right: 0; margin-left: auto; } .rtl .dropdown-menu { right: 0; left: auto; } .rtl .search-bar .form-control { border-radius: 0 0.375rem 0.375rem 0; border-left: none; border-right: 1px solid #ced4da; text-align: right; } .rtl .search-bar .btn { border-radius: 0.375rem 0 0 0.375rem; order: -1; } .rtl .nav-link i { margin-left: 0.5rem; margin-right: 0; } .rtl .dropdown-item i { margin-left: 0.5rem; margin-right: 0; } .rtl .me-2 { margin-right: 0 !important; margin-left: 0.5rem !important; } .rtl .me-3 { margin-right: 0 !important; margin-left: 1rem !important; } .rtl .text-end { text-align: left !important; } .rtl .text-start { text-align: right !important; } /* Fix pour les dropdowns - z-index RÉDUIT pour éviter conflits avec modales */ .navbar .dropdown-menu { z-index: 15 !important; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; border: 1px solid rgba(0, 0, 0, 0.15) !important; } .navbar .dropdown { position: relative; z-index: 12; } .navbar .dropdown.show { z-index: 15; } /* Assurer que les dropdowns sont toujours visibles */ .navbar-nav .dropdown-menu { position: absolute !important; transform: none !important; will-change: auto !important; } • AEF Logo 📄 blog/index.html.twig ------------------------------------------------------------ • Blog & • Actualités • Découvrez les dernières tendances, les histoires fascinantes et les conseils d'experts du monde des antiquités françaises. • Lire l'article • Équipe AEF • AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 100 }); 📄 blog/show.html.twig ------------------------------------------------------------ • :root { --primary-color: #667eea; --secondary-color: #764ba2; --accent-color: #f8b500; --text-dark: #2c3e50; --text-light: #6c757d; --surface: #ffffff; --background: #f8fafc; --success: #10b981; --info: #3b82f6; } .article-page { background: var(--background); min-height: 100vh; } /* Hero Section */ .hero-section { background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%); position: relative; padding: 8rem 0 4rem; overflow: hidden; } .hero-section::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 20% 80%, rgba(255,255,255,0.1) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(255,255,255,0.08) 0%, transparent 50%); animation: shimmer 4s ease-in-out infinite alternate; } @keyframes shimmer { 0% { opacity: 0.7; } 100% { opacity: 1; } } .breadcrumb-nav { position: relative; z-index: 10; margin-bottom: 3rem; } .breadcrumb { background: rgba(255,255,255,0.1); border-radius: 25px; padding: 0.5rem 1.5rem; backdrop-filter: blur(10px); } .breadcrumb-item a { color: rgba(255,255,255,0.8); text-decoration: none; transition: color 0.3s ease; } .breadcrumb-item a:hover { color: white; } .breadcrumb-item.active { color: var(--accent-color); } .article-header { position: relative; z-index: 10; color: white; text-align: center; } .article-title { font-size: 3rem; font-weight: 900; margin-bottom: 1.5rem; text-shadow: 0 4px 30px rgba(0,0,0,0.4); letter-spacing: -0.02em; line-height: 1.2; max-width: 800px; margin-left: auto; margin-right: auto; } .article-meta { display: flex; justify-content: center; gap: 2rem; margin-bottom: 2rem; flex-wrap: wrap; } .meta-item { display: flex; align-items: center; gap: 0.5rem; color: rgba(255,255,255,0.9); font-size: 1rem; } .meta-item i { color: var(--accent-color); } /* Content Section */ .content-section { padding: 6rem 0; } .article-content { background: var(--surface); border-radius: 20px; padding: 4rem; box-shadow: 0 15px 40px rgba(0,0,0,0.08), 0 0 0 1px rgba(0,0,0,0.02); margin-bottom: 3rem; max-width: 800px; margin-left: auto; margin-right: auto; } .article-content h1, .article-content h2, .article-content h3, .article-content h4, .article-content h5, .article-content h6 { color: var(--text-dark); font-weight: 700; margin-top: 2rem; margin-bottom: 1rem; } .article-content h2 { font-size: 2rem; border-bottom: 3px solid var(--accent-color); padding-bottom: 0.5rem; } .article-content h3 { font-size: 1.5rem; color: var(--primary-color); } .article-content p { color: var(--text-light); font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.5rem; } .article-content ul, .article-content ol { color: var(--text-light); font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.5rem; padding-left: 2rem; } .article-content blockquote { background: linear-gradient(135deg, #f8fafc, #e2e8f0); border-left: 4px solid var(--accent-color); padding: 1.5rem 2rem; margin: 2rem 0; border-radius: 10px; font-style: italic; color: var(--text-dark); } .article-content img { width: 100%; border-radius: 15px; margin: 2rem 0; box-shadow: 0 15px 40px rgba(0,0,0,0.15); } /* Related Articles */ .related-section { background: linear-gradient(135deg, #f8fafc, #e2e8f0); padding: 4rem 0; } .section-title { text-align: center; font-size: 2.5rem; font-weight: 900; color: var(--text-dark); margin-bottom: 3rem; } .related-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem; } .related-card { background: var(--surface); border-radius: 15px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.08), 0 0 0 1px rgba(0,0,0,0.02); transition: all 0.3s ease; } .related-card:hover { transform: translateY(-8px); box-shadow: 0 20px 50px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.02); } .related-image { height: 200px; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); display: flex; align-items: center; justify-content: center; color: white; font-size: 3rem; opacity: 0.7; } .related-info { padding: 1.5rem; } .related-title { font-size: 1.2rem; font-weight: 700; color: var(--text-dark); margin-bottom: 0.5rem; line-height: 1.4; } .related-excerpt { color: var(--text-light); font-size: 0.9rem; line-height: 1.5; margin-bottom: 1rem; } .read-more-btn { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; border: none; padding: 8px 16px; border-radius: 15px; font-weight: 600; text-decoration: none; font-size: 0.9rem; transition: all 0.3s ease; } .read-more-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3); color: white; text-decoration: none; } /* Navigation Buttons */ .nav-buttons { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3rem; max-width: 800px; margin-left: auto; margin-right: auto; } .nav-btn { background: rgba(255,255,255,0.15); color: white; border: 2px solid rgba(255,255,255,0.3); padding: 12px 24px; border-radius: 25px; font-weight: 600; text-decoration: none; transition: all 0.3s ease; backdrop-filter: blur(10px); display: flex; align-items: center; gap: 0.5rem; } .nav-btn:hover { background: rgba(255,255,255,0.25); border-color: rgba(255,255,255,0.5); transform: translateY(-3px); box-shadow: 0 10px 30px rgba(0,0,0,0.2); color: white; text-decoration: none; } @media (max-width: 768px) { .article-title { font-size: 2rem; } .article-content { padding: 2rem; } .article-meta { flex-direction: column; gap: 1rem; } .nav-buttons { flex-direction: column; } .related-grid { grid-template-columns: 1fr; } } • Accueil • Blog • Article • Retour au Blog • Articles Similaires • La dorure au mercure • représente l'une des techniques les plus fascinantes et périlleuses de l'art décoratif français. Utilisée principalement aux XVIIIe et XIXe siècles, cette méthode permettait d'obtenir des dorures d'une qualité et d'un éclat exceptionnels sur les bronzes d'art. • L'Histoire d'une Technique Révolutionnaire • Développée au milieu du XVIIIe siècle, la dorure au mercure, également appelée • dorure à l'amalgame • , révolutionna l'art du bronze décoratif. Cette technique permettait d'appliquer l'or de manière uniforme et durable sur des pièces complexes, donnant naissance aux magnifiques bronzes dorés qui ornent encore aujourd'hui châteaux et musées. • "La dorure au mercure transformait le bronze le plus ordinaire en un objet d'une splendeur royale, rivalisant avec l'or massif par son éclat." - André-Charles Boulle • Le Processus Technique • Le processus était d'une complexité remarquable : • Préparation de l'amalgame • : L'or était mélangé au mercure dans des proportions précises • Application • : L'amalgame était étalé sur le bronze préalablement nettoyé • Chauffage • : La pièce était chauffée pour faire évaporer le mercure • Brunissage • : L'or restant était poli pour obtenir l'éclat final • Les Maîtres de l'Art • Les plus grands bronziers français maîtrisaient cette technique : Pierre Gouthière, André-Charles Boulle, ou encore les ateliers de la manufacture royale. Leurs créations, pendules, candélabres et ornements divers, témoignent encore aujourd'hui de leur savoir-faire exceptionnel. • L'Héritage et la Reconnaissance • Bien que cette technique ait été abandonnée au XIXe siècle en raison de sa toxicité, les pièces dorées au mercure demeurent parmi les plus recherchées par les collectionneurs. Leur reconnaissance passe par l'observation de caractéristiques spécifiques : l'uniformité de la dorure, sa résistance au temps, et cette patine particulière que seul le mercure pouvait conférer. • Aujourd'hui, la restauration de ces pièces d'exception demande une expertise particulière, alliant connaissance historique et techniques modernes de conservation. • Lire la suite • AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 100 }); 📄 bundles/TwigBundle/Exception/error404.html.twig ------------------------------------------------------------ • .error-page { animation: fadeIn 0.8s ease-in; } @keyframes fadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } .display-1 { font-size: 8rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.1); } 📄 bundles/TwigBundle/Exception/error500.html.twig ------------------------------------------------------------ • .error-page { animation: fadeIn 0.8s ease-in; } @keyframes fadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } .display-1 { font-size: 8rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.1); } 📄 cart/_cart_item.html.twig ------------------------------------------------------------ • Quantité • Prix modifié • Supprimer • Cet article n'est plus disponible à la vente. • Le prix de cet article a été modifié depuis son ajout au panier. • Supprimer du panier 📄 cart/_cart_summary.html.twig ------------------------------------------------------------ • Récapitulatif • Frais de livraison • À calculer • Total • Estimation frais livraison : • Sélectionnez un pays • France • Belgique • Suisse • Espagne • Italie • Allemagne • États-Unis • Paiement sécurisé • Retour possible sous 14 jours • Support client disponible • Finaliser ma commande • Corriger les erreurs • Continuer mes achats • Appliquer • Vendeur • Voir le profil • Les frais seront calculés à l'étape suivante • Code promo 📄 cart/_empty_cart.html.twig ------------------------------------------------------------ • Votre panier est vide • Découvrez notre sélection d'antiquités uniques et ajoutez vos coups de cœur à votre panier. • Découvrir les antiquités • Parcourir le catalogue • Articles populaires • Mobilier d'époque • Découvrez notre collection de meubles authentiques • Explorer • Bijoux anciens • Bijoux rares et pièces de collection • Œuvres d'art • Tableaux, sculptures et objets d'art • Pourquoi choisir AEF ? • Authenticité garantie • Tous nos objets sont authentifiés par des experts • Paiement sécurisé • Transactions protégées par Stripe Connect • Livraison soignée • Emballage professionnel et suivi de livraison • Support expert • Équipe spécialisée en antiquités à votre service • Ne manquez aucune nouveauté • Inscrivez-vous à notre newsletter et soyez le premier informé des nouvelles acquisitions. • Votre email 📄 cart/index.html.twig ------------------------------------------------------------ • Accueil • Mon panier • Vider le panier • Attention ! • Votre panier contient des erreurs : • Tous les articles de votre panier proviennent de ce vendeur • Êtes-vous sûr de vouloir vider votre panier ? Cette action est irréversible. • Annuler • { console.error('Erreur:', error); alert('Une erreur est survenue'); }); // Fermer le modal bootstrap.Modal.getInstance(clearCartModal).hide(); }); } } }); • Close 📄 catalog/_breadcrumb.html.twig ------------------------------------------------------------ • Filtres actifs : • - Page • Effacer tous les filtres 📄 catalog/_items.html.twig ------------------------------------------------------------ • Voir l'objet 📄 catalog/_pagination.html.twig ------------------------------------------------------------ • Chargement des résultats... 📄 catalog/index.html.twig ------------------------------------------------------------ • Catalogue d'Antiquités • Découvrez notre sélection exceptionnelle d'antiquités françaises • Objets • Catégories • Catégorie • Toutes les catégories • Style • Tous les styles • Époque • Toutes les époques • Tri • Plus récents • Prix croissant • Prix décroissant • Nom A-Z • Appliquer les filtres • Réinitialiser • Filtres actifs : • - Page • Effacer tous les filtres • Aucun objet trouvé • Essayez de modifier vos critères de recherche • Voir l'objet • AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 100 }); • { if (this.filters[key] && this.filters[key].toString().trim() !== '') { params.set(key, this.filters[key]); } }); const apiUrl = `/api/catalog/items?${params.toString()}`; console.log('🌐 API request to:', apiUrl); const response = await fetch(apiUrl, { method: 'GET', headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' } }); console.log('📡 Response status:', response.status, response.statusText); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`); } const data = await response.json(); console.log('📊 Response data:', data); if (data.success) { // Mettre à jour le contenu des objets if (this.container) { this.container.innerHTML = data.itemsHtml; console.log('✅ Container updated with new items'); } // Mettre à jour la pagination - CORRECTION CRITIQUE const paginationWrapper = document.querySelector('.pagination-wrapper'); if (paginationWrapper) { // Sauvegarder l'élément loading avant destruction const loadingElement = document.getElementById('catalogLoading'); if (data.paginationHtml && data.paginationHtml.trim() !== '') { // Remplacer seulement si on a du contenu valide paginationWrapper.outerHTML = data.paginationHtml; // Re-obtenir les références après mise à jour du DOM this.pagination = document.getElementById('catalogPagination'); this.loading = document.getElementById('catalogLoading'); // Si l'élément loading a été perdu, le recréer if (!this.loading && loadingElement) { const newPaginationWrapper = document.querySelector('.pagination-wrapper'); if (newPaginationWrapper) { newPaginationWrapper.appendChild(loadingElement); this.loading = loadingElement; } } console.log('✅ Pagination updated'); } else { // Pas de pagination - garder juste l'élément loading const paginationModern = paginationWrapper.querySelector('.pagination-modern'); if (paginationModern) { paginationModern.innerHTML = ''; this.pagination = paginationModern; } console.log('✅ Pagination cleared (no results)'); } } // Mettre à jour le breadcrumb if (data.breadcrumbHtml) { let breadcrumbSection = document.querySelector('.breadcrumb-section'); if (breadcrumbSection) { breadcrumbSection.outerHTML = data.breadcrumbHtml; } else { const itemsSection = document.querySelector('.items-section'); if (itemsSection) { itemsSection.insertAdjacentHTML('beforebegin', data.breadcrumbHtml); } } console.log('✅ Breadcrumb updated'); } this.currentPage = page; // Mettre à jour l'URL sans recharger la page if (updateUrl) { this.updateUrl(page); } // Auto-scroll vers les filtres this.scrollToFilters(); // Réinitialiser les animations AOS if (typeof AOS !== 'undefined') { AOS.refresh(); } console.log(`✅ Catalog updated: Page ${page}, ${data.totalItems} items found`); } else { throw new Error(data.message || 'Erreur lors du chargement des données'); } } catch (error) { console.error('❌ Loading error:', error); if (this.container) { this.container.innerHTML = ` • Erreur lors du chargement: ${error.message} • Veuillez réessayer ou recharger la page. • { console.log('🔄 Auto-scroll to filters...'); // CORRECTION : Utiliser this.form au lieu de form const filtersSection = document.getElementById('filters') || document.querySelector('.filters-section') || document.querySelector('#catalogFilters') || this.form; if (filtersSection) { console.log('✅ Filters section found, scrolling...'); const rect = filtersSection.getBoundingClientRect(); // Calcul dynamique de l'offset basé sur la navbar let offset = 20; // Offset minimal de base const navbar = document.querySelector('.navbar'); if (navbar) { // Ajouter la hauteur de la navbar + une petite marge offset = navbar.offsetHeight + 20; console.log(`📏 Hauteur navbar détectée: ${navbar.offsetHeight}px, offset utilisé: ${offset}px`); } else { // Fallback si la navbar n'est pas trouvée offset = 80; console.log(`⚠️ Navbar non trouvée, utilisation offset par défaut: ${offset}px`); } const scrollTop = window.pageYOffset + rect.top - offset; window.scrollTo({ top: Math.max(0, scrollTop), behavior: 'smooth' }); console.log('✅ Auto-scroll completed to position:', Math.max(0, scrollTop)); } else { console.log('❌ Filters section not found, scrolling to top'); window.scrollTo({ top: 0, behavior: 'smooth' }); } }, 200); // Délai pour laisser le DOM se mettre à jour } resetFilters() { if (this.isLoading) { console.log('⏳ Already loading, skipping reset'); return; } try { if (this.form) { this.form.reset(); console.log('🔄 Form reset'); } this.filters = {}; this.loadPage(1); } catch (error) { console.error('❌ Error in resetFilters:', error); } } } // Initialiser le gestionnaire si les éléments requis sont présents if (form && container) { window.catalogManager = new CatalogManager(); console.log('✅ CatalogManager initialized and exposed on window'); } else { console.error('❌ Required elements missing:', { form: !!form, container: !!container }); console.log('ℹ️ Catalog page initialization failed - missing required elements'); } console.log('🚀 App initialization completed'); }); 📄 catalog/item_show.html.twig ------------------------------------------------------------ • /* Actions rapides */ .quick-actions { display: flex; gap: 0.75rem; align-items: center; padding: 1rem 0; border-top: 1px solid #e9ecef; border-bottom: 1px solid #e9ecef; background-color: #f8f9fa; border-radius: 8px; padding: 1rem; margin: 1rem 0; } .quick-actions .btn { width: 45px; height: 45px; display: flex; align-items: center; justify-content: center; border-radius: 50%; position: relative; border-width: 2px; font-size: 1.1rem; transition: all 0.3s ease; } .quick-actions .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,123,255,0.3); } .quick-actions .btn-group .btn { border-radius: 50% !important; } .quick-actions .dropdown-menu { border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.15); } /* Métadonnées */ .item-metadata { background-color: #f8f9fa; border-radius: 8px; padding: 1rem; } .metadata-grid { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; } .metadata-item { display: flex; align-items: center; } /* Tags */ .tags-section { margin-bottom: 1.5rem; } .tags-container .badge { margin: 0.25rem; padding: 0.5rem 0.75rem; font-size: 0.875rem; border-radius: 20px; } .spec-value .badge { margin-right: 0.25rem; margin-bottom: 0.25rem; } .badge[title] { cursor: help; } • Accueil • Catalogue • Aucune image disponible • Prix sur demande • Partager • Par email • Description • Caractéristiques • Catégories • Catégorie • Périodes • Époque • Styles • Style • Matériau • Dimensions • État • Provenance • Tags • Informations • Objet en vedette • Ajouter au panier • Demander un devis • Contacter le vendeur • Objet vendu • Objet réservé • Vendeur • Voir le profil • Profil en préparation • Site web • Objets similaires • Découvrez d'autres pièces qui pourraient vous intéresser • Voir l'objet • Votre nom * • Votre email * • Votre téléphone (optionnel) • Votre message * • Protégé par reCAPTCHA - • Confidentialité • Conditions • Annuler • Envoyer • Votre téléphone • Adresse de livraison * • Message ou informations complémentaires • t.classList.remove('active')); this.classList.add('active'); } }); }); // Contact form avec reCAPTCHA v3 const contactForm = document.getElementById('contactForm'); if (contactForm) { contactForm.addEventListener('submit', function(e) { e.preventDefault(); e.stopPropagation(); if (!this.checkValidity()) { this.classList.add('was-validated'); return; } const submitBtn = document.querySelector('#contactModal [type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.disabled = true; submitBtn.innerHTML = ' • { const alertDiv = document.createElement('div'); const modalBody = document.querySelector('#contactModal .modal-body'); if (data.success) { alertDiv.className = 'alert alert-success alert-dismissible fade show'; alertDiv.innerHTML = `${data.message} • { const modalElement = document.getElementById('contactModal'); const modal = bootstrap.Modal.getInstance(modalElement); if (modal) { modal.hide(); } }, 3000); } else { alertDiv.className = 'alert alert-danger alert-dismissible fade show'; alertDiv.innerHTML = `${data.message} • Ajouter aux favoris • Close • Adresse complète pour estimer les frais de livraison • Décrivez vos besoins spécifiques, questions sur l'objet, etc. 📄 checkout/confirmation.html.twig ------------------------------------------------------------ • Accueil • Panier • Confirmation • 1. Livraison • 2. Paiement • 3. Confirmation • Demande de devis envoyée ! • Votre demande de devis a bien été transmise au vendeur. Vous recevrez une réponse sous 24-48h. • Commande confirmée ! • Merci pour votre achat ! Votre paiement a été traité avec succès. • Commande enregistrée ! • Votre commande a été enregistrée et est en cours de traitement. • Prochaines étapes • Le vendeur va préparer un devis de livraison personnalisé • Vous recevrez un email avec le devis sous 24-48h • Vous pourrez alors valider et payer la commande • Un email de confirmation vous a été envoyé • Le vendeur va préparer votre commande • Vous recevrez un email avec les informations de suivi • Détails de la commande • Informations de commande • Date : • Statut : • En attente de devis • Payée • En attente de paiement • Email : • Vendeur • Contacter le vendeur • Articles commandés • Adresses • Adresse de livraison • Adresse de facturation • Notes de commande • Récapitulatif financier • Sous-total articles • Frais de livraison • Devis en cours • Remise • Total • Actions • Mes commandes • Retour à l'accueil • Continuer mes achats • Imprimer • Informations utiles • Paiement sécurisé • Vos données sont protégées par cryptage SSL • Retour possible • Sous conditions, dans les 14 jours • Support client • Nous contacter • Email de confirmation • Vérifiez votre boîte mail et vos spams • /* Styles pour l'impression */ @media print { .checkout-progress, .breadcrumb, .btn, .card-header, .alert { display: none !important; } .confirmation-header { page-break-after: avoid; } .card { border: 1px solid #ddd !important; box-shadow: none !important; page-break-inside: avoid; margin-bottom: 20px !important; } body { font-size: 12px; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } } /* Styles pour la confirmation */ .checkout-container { padding: 20px 0; } .checkout-progress { display: flex; justify-content: center; margin-bottom: 2rem; } .checkout-progress .step { display: flex; align-items: center; padding: 0.5rem 1rem; margin: 0 0.5rem; border-radius: 25px; background-color: #f8f9fa; color: #6c757d; font-weight: 500; position: relative; } .checkout-progress .step.completed { background-color: #d4edda; color: #155724; } .checkout-progress .step.active { background-color: #0d6efd; color: white; } .success-icon { animation: successBounce 0.6s ease-out; } @keyframes successBounce { 0% { transform: scale(0); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .order-number-badge { margin-top: 1rem; } .placeholder-image { background-color: #f8f9fa; border: 2px dashed #dee2e6; } /* Responsive */ @media (max-width: 768px) { .checkout-progress { flex-direction: column; align-items: center; } .checkout-progress .step { margin: 0.25rem 0; width: 200px; justify-content: center; } .confirmation-header h1 { font-size: 1.75rem; } .card-body .row .col-md-2, .card-body .row .col-md-7, .card-body .row .col-md-3 { margin-bottom: 1rem; } } 📄 checkout/payment.html.twig ------------------------------------------------------------ • Accueil • Panier • Paiement • 1. Livraison • 2. Paiement • 3. Confirmation • Devis de livraison requis • Le vendeur doit vous fournir un devis personnalisé pour les frais de livraison de cette commande. • Commande créée • Vos informations ont été enregistrées • En attente du devis • Le vendeur prépare votre devis de livraison • Validation et paiement • Vous pourrez valider et payer • Que se passe-t-il maintenant ? • Le vendeur a 15 jours pour vous envoyer un devis • Vous recevrez un email dès que le devis sera disponible • Le devis sera valable 30 jours • Vous pourrez négocier le prix si nécessaire • Demander le devis • Paiement sécurisé • Paiement sécurisé SSL • Propulsé par Stripe • Données cryptées • J'accepte les • conditions générales de vente • politique de confidentialité • Traitement du paiement en cours... • Récapitulatif de commande • Vendeur • Livraison • Sous-total • Frais de livraison • Devis requis • Total • Commande n° • { submitButton.disabled = !termsCheckbox.checked || this.isProcessing; }); form.addEventListener('submit', this.handleSubmit.bind(this)); } async handleSubmit(event) { event.preventDefault(); if (this.isProcessing) return; const termsCheckbox = document.getElementById('terms-checkbox'); if (!termsCheckbox.checked) { alert('Veuillez accepter les conditions générales'); return; } this.setLoading(true); this.showLoadingOverlay(); const {error} = await this.stripe.confirmPayment({ elements: this.elements, confirmParams: { return_url: window.location.origin + '/checkout/confirmation/' + this.orderNumber, } }); if (error) { this.handlePaymentError(error); } else { // Le paiement sera traité par le return_url } } handlePaymentError(error) { this.setLoading(false); this.hideLoadingOverlay(); let message = 'Une erreur inattendue s\'est produite.'; if (error.type === "card_error" || error.type === "validation_error") { message = error.message; } else if (error.type === "invalid_request_error") { message = 'Requête invalide. Veuillez réessayer.'; } this.displayError(message); // Log pour débogage console.error('Erreur de paiement:', error); } displayError(message) { const errorElement = document.getElementById('payment-errors'); if (message) { errorElement.textContent = message; errorElement.style.display = 'block'; } else { errorElement.style.display = 'none'; } } setLoading(isLoading) { this.isProcessing = isLoading; const submitButton = document.getElementById('submit-payment'); const buttonText = document.getElementById('button-text'); const spinner = document.getElementById('spinner'); const termsCheckbox = document.getElementById('terms-checkbox'); if (isLoading) { submitButton.disabled = true; buttonText.style.display = 'none'; spinner.style.display = 'inline-block'; } else { const termsChecked = termsCheckbox.checked; submitButton.disabled = !termsChecked; buttonText.style.display = 'inline'; spinner.style.display = 'none'; } } enablePaymentButton() { const termsCheckbox = document.getElementById('terms-checkbox'); const submitButton = document.getElementById('submit-payment'); if (termsCheckbox.checked) { submitButton.disabled = false; } } showLoadingOverlay() { document.getElementById('payment-loading').style.display = 'flex'; } hideLoadingOverlay() { document.getElementById('payment-loading').style.display = 'none'; } } class QuoteRequest { constructor(options) { this.orderNumber = options.orderNumber; this.bindEvents(); } bindEvents() { const requestButton = document.getElementById('request-quote-btn'); if (requestButton) { requestButton.addEventListener('click', this.handleQuoteRequest.bind(this)); } } async handleQuoteRequest(event) { event.preventDefault(); const button = event.target; const originalText = button.innerHTML; button.disabled = true; button.innerHTML = ' • Envoi en cours...'; try { const response = await fetch(button.closest('form').action, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' } }); if (response.ok) { window.location.href = `/checkout/confirmation/${this.orderNumber}`; } else { throw new Error('Erreur lors de la demande de devis'); } } catch (error) { console.error('Erreur:', error); alert('Une erreur est survenue lors de la demande de devis'); button.disabled = false; button.innerHTML = originalText; } } } • Visa • Mastercard • American Express 📄 checkout/shipping.html.twig ------------------------------------------------------------ • .checkout-container { max-width: 1200px; margin: 0 auto; padding: 2rem 1rem; } .checkout-progress { display: flex; justify-content: center; margin-bottom: 2rem; gap: 1rem; } .step { padding: 0.75rem 1.5rem; border: 2px solid #dee2e6; border-radius: 2rem; background: #f8f9fa; color: #6c757d; font-weight: 500; position: relative; min-width: 120px; text-align: center; } .step.active { background: #0d6efd; color: white; border-color: #0d6efd; } .step.completed { background: #198754; color: white; border-color: #198754; } .step::after { content: ''; position: absolute; top: 50%; right: -1rem; width: 0; height: 0; border-left: 10px solid #0d6efd; border-top: 10px solid transparent; border-bottom: 10px solid transparent; transform: translateY(-50%); display: none; } .step.active::after { display: block; } .address-section { background: white; border: 1px solid #e9ecef; border-radius: 0.5rem; padding: 1.5rem; margin-bottom: 1.5rem; } .same-address-checkbox { background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 0.375rem; padding: 1rem; margin-bottom: 1rem; } .order-summary { background: #f8f9fa; border-radius: 0.5rem; padding: 1.5rem; position: sticky; top: 20px; } .shipping-calculator { border: 1px solid #e9ecef; border-radius: 0.375rem; padding: 1rem; margin-top: 1rem; background: white; } .shipping-options { margin-top: 1rem; } .shipping-option { border: 1px solid #e9ecef; border-radius: 0.375rem; padding: 1rem; margin-bottom: 0.5rem; cursor: pointer; transition: all 0.3s ease; } .shipping-option:hover { border-color: #0d6efd; background-color: #f8f9ff; } .shipping-option.selected { border-color: #0d6efd; background-color: #e7f3ff; } .shipping-option.quote-required { border-color: #ffc107; background-color: #fff8e1; } .secure-indicators { display: flex; align-items: center; gap: 1rem; margin-top: 1rem; padding: 1rem; background: #e7f3ff; border-radius: 0.375rem; border: 1px solid #b3d9ff; } .form-floating label { color: #6c757d; } @media (max-width: 768px) { .checkout-progress { flex-direction: column; align-items: center; } .step { min-width: 200px; } .order-summary { position: static; margin-top: 2rem; } } • Accueil • Panier • Commande • 1. Livraison • 2. Paiement • 3. Confirmation • Adresse de facturation • Adresse de livraison • Notes de commande (optionnel) • Récapitulatif • Frais de livraison • À calculer • Total • Calcul en cours... • Commande sécurisée • Livraison soignée • Continuer vers le paiement • this.calculateShipping(), 100); } initShippingCalculator() { // Calculer automatiquement si un pays est déjà sélectionné const countrySelect = document.getElementById('shipping-country-select'); if (countrySelect && countrySelect.value) { this.calculateShipping(); } } async calculateShipping() { const countrySelect = document.getElementById('shipping-country-select'); const shippingOptions = document.getElementById('shipping-options'); const shippingLoading = document.getElementById('shipping-loading'); const shippingCost = document.getElementById('shipping-cost'); if (!countrySelect || !countrySelect.value) { shippingOptions.style.display = 'none'; shippingCost.textContent = 'À calculer'; return; } shippingLoading.style.display = 'block'; shippingOptions.style.display = 'none'; try { const response = await fetch('/checkout/api/shipping-cost', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }, body: JSON.stringify({ country: countrySelect.value }) }); const data = await response.json(); shippingLoading.style.display = 'none'; if (data.success) { if (data.requires_quote) { this.displayQuoteRequired(data.message); } else { this.displayShippingCost(data); } } else { this.displayError('Erreur lors du calcul'); } } catch (error) { console.error('Erreur calcul frais:', error); shippingLoading.style.display = 'none'; this.displayError('Erreur de connexion'); } } displayShippingCost(data) { const shippingOptions = document.getElementById('shipping-options'); const shippingCost = document.getElementById('shipping-cost'); const totalAmount = document.getElementById('total-amount'); shippingCost.textContent = data.formatted_cost; shippingCost.classList.remove('text-muted'); shippingCost.classList.add('text-success'); // Mettre à jour le total (temporaire, sera fait côté serveur) const currentTotal = parseFloat(document.querySelector('.summary-totals [data-amount]')?.dataset.amount || 0); const newTotal = currentTotal + data.cost; if (totalAmount) { totalAmount.textContent = newTotal.toLocaleString('fr-FR', { minimumFractionDigits: 2 }) + ' €'; } shippingOptions.innerHTML = ` • ${data.rule_name || 'Livraison standard'} • Délai estimé: ${data.estimated_days} jours • `; shippingOptions.style.display = 'block'; } displayQuoteRequired(message) { const shippingOptions = document.getElementById('shipping-options'); const shippingCost = document.getElementById('shipping-cost'); shippingCost.textContent = 'Devis requis'; shippingCost.classList.remove('text-muted'); shippingCost.classList.add('text-warning'); shippingOptions.innerHTML = ` • Devis de livraison requis • `; shippingOptions.style.display = 'block'; } displayError(message) { const shippingOptions = document.getElementById('shipping-options'); shippingOptions.innerHTML = ` • { if (!field.value.trim()) { field.classList.add('is-invalid'); isValid = false; } else { field.classList.remove('is-invalid'); } }); if (!isValid) { e.preventDefault(); alert('Veuillez remplir tous les champs obligatoires.'); } } } 📄 components/_cart_widget.html.twig ------------------------------------------------------------ • Mon panier • Chargement... • Chargement du panier... • { console.error('Erreur mise à jour widget panier:', error); const contentElement = document.getElementById('cart-dropdown-content'); if (contentElement) { contentElement.innerHTML = ' • Erreur de chargement • '; } }); } function updateCartDropdownContent(dropdownContent, cartData) { // Vérifier que cartData est défini et valide if (!cartData || cartData.empty || cartData.count === 0 || !cartData.items || !Array.isArray(cartData.items)) { dropdownContent.innerHTML = ` • Votre panier est vide • Découvrir • ${displayTitle} • ${price.toLocaleString('fr-FR', { minimumFractionDigits: 2 })} € • Et ${itemCount - 3} autre(s) article(s)... • ` : ''; dropdownContent.innerHTML = ` • ${itemsHtml} ${moreItemsHtml} • Total: • ${total.toLocaleString('fr-FR', { minimumFractionDigits: 2 })} € • Voir le panier • Commander • { console.error('Erreur:', error); alert('Une erreur est survenue'); }); } } }); }); • Supprimer 📄 components/_cart_widget_content.html.twig ------------------------------------------------------------ • Total: • Voir le panier • Commander • Supprimer 📄 components/_cart_widget_empty.html.twig ------------------------------------------------------------ • Votre panier est vide • Découvrir 📄 contact/index.html.twig ------------------------------------------------------------ • Nous contacter • Envoyez-nous un message, nous vous répondrons rapidement • Envoyer le message • Email • Téléphone • Horaires • Lun-Ven: 9h-18h • .contact-info-card { padding: 2rem; border-radius: 10px; background: #f8f9fa; height: 100%; transition: transform 0.3s ease; } .contact-info-card:hover { transform: translateY(-5px); } .contact-form .form-control:focus { border-color: #667eea; box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25); } 📄 contact/member.html.twig ------------------------------------------------------------ • Contacter • {# En-tête avec informations du membre #} • Informations importantes : • Votre adresse email sera visible pour la réponse • Soyez courtois et précis dans votre demande • Les messages sont archivés pour le suivi des échanges • {# Formulaire de contact #} • Votre message • Conseil : • Plus votre message sera détaillé et précis, plus vous obtiendrez une réponse pertinente. • Envoyer le message • {# Liens de retour #} • Retour au profil • Retour aux membres • { const counter = document.createElement('div'); counter.className = 'char-counter'; counter.innerHTML = ' • 1950) { counter.className = 'char-counter danger'; } }; messageTextarea.addEventListener('input', updateCounter); updateCounter(); }; createCounter(); } // Auto-resize du textarea if (messageTextarea) { messageTextarea.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = (this.scrollHeight) + 'px'; }); } }); 📄 contact/success.html.twig ------------------------------------------------------------ • Message envoyé ! • Votre message a été transmis avec succès • Votre message a été transmis avec succès. Vous devriez recevoir une réponse dans les plus brefs délais. • Prochaines étapes : • Un email de confirmation vous a été envoyé • Le destinataire sera notifié de votre message • Vous recevrez sa réponse directement par email • Retour à l'accueil • Parcourir l'annuaire 📄 dashboard/_dashboard_header_menu.html.twig ------------------------------------------------------------ • Accueil • Mes Objets • Messages • Profil • Abonnement • Branding • Position GPS • Statistiques • /* Dashboard Header Menu - Style AEF - Pleine largeur - Collé sous la barre de recherche */ .dashboard-header-menu-full { position: relative; width: 100vw; margin-left: calc(-50vw + 50%); background: linear-gradient(to bottom, #0088cc, #0055cc) !important; border-bottom: 4px solid #cc8822; box-shadow: 0 4px 12px rgba(0, 136, 204, 0.3); padding: 1rem 2rem; z-index: 1040; margin-top: 0 !important; margin-bottom: 1.5rem !important; /* Suppression de tout espacement supérieur pour coller à la barre de recherche */ border-top: none; } .dashboard-header-menu-full::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-image: url('/assets/texture-content-2.png'); background-repeat: repeat; opacity: 0.1; z-index: 0; } .dashboard-nav-content-full { position: relative; z-index: 1; display: flex; justify-content: center; align-items: center; flex-wrap: nowrap; max-width: 1400px; margin: 0 auto; gap: 0.5rem; } .btn-dashboard-nav { background-color: rgba(255, 255, 255, 0.1) !important; border: 1px solid rgba(255, 255, 255, 0.2) !important; color: white !important; transition: all 0.3s ease; min-height: 70px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0.75rem 0.5rem !important; border-radius: 8px !important; flex: 1; min-width: 0; } .btn-dashboard-nav:hover { background-color: rgba(255, 255, 255, 0.2) !important; color: #cc8822 !important; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); border-color: rgba(204, 136, 34, 0.5) !important; } .btn-dashboard-nav.active { background-color: rgba(204, 136, 34, 0.2) !important; color: #cc8822 !important; border-color: #cc8822 !important; font-weight: 600; } .btn-dashboard-nav i { font-size: 1.4rem; margin-bottom: 0.25rem; transition: all 0.3s ease; } .btn-dashboard-nav:hover i { transform: scale(1.1); color: #cc8822 !important; } .btn-dashboard-nav small { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; line-height: 1; white-space: nowrap; } /* Responsive adjustments */ @media (max-width: 992px) { .dashboard-nav-content-full { flex-direction: column; gap: 1rem; } .dashboard-nav-content-full .row { margin: 0; width: 100%; } .dashboard-header-menu-full { padding: 1rem; } } @media (max-width: 768px) { .btn-dashboard-nav { min-height: 60px; padding: 0.5rem 0.25rem !important; } .btn-dashboard-nav i { font-size: 1.2rem; } .btn-dashboard-nav small { font-size: 0.65rem; } .dashboard-header-menu-full { padding: 0.75rem 1rem; } } 📄 dashboard/_infrastructure_alerts.html.twig ------------------------------------------------------------ • Service de recherche indisponible • La recherche et l'indexation automatique sont temporairement désactivées. Vos données sont sauvegardées normalement. • Performance réduite • La base de données répond plus lentement que d'habitude. Les opérations peuvent prendre plus de temps. • Maintenance programmée • Espace de stockage faible • Close 📄 dashboard/_sidebar.html.twig ------------------------------------------------------------ • Commandes • Devis • Statistiques Avancées • Espace Vendeur • En cours • Non configuré • Encaissement CB 📄 dashboard/base.html.twig ------------------------------------------------------------ • /* Integration avec le reste du dashboard */ .dashboard-layout { background: #f8f9fa; min-height: calc(100vh - 140px); } /* Amélioration sidebar pour s'harmoniser */ .dashboard-sidebar { background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%); border-right: 2px solid #e9ecef; box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05); } /* Suppression de l'espacement entre la barre de recherche et le menu dashboard */ .search-bar { margin-bottom: 0 !important; } /* Coller le menu dashboard directement sous la barre de recherche */ .dashboard-header-menu-full { margin-top: 0 !important; } • Close 📄 dashboard/branding/index.html.twig ------------------------------------------------------------ • Profil en préparation • Recadrer • Après avoir sélectionné votre image, cliquez sur "Recadrer" pour ajuster la zone du logo. • Supprimer • Après avoir sélectionné votre image, cliquez sur "Recadrer" pour ajuster la zone de la bannière. • Facebook • Twitter • YouTube • Instagram • LinkedIn • document.addEventListener('DOMContentLoaded', function() { // Mise à jour en temps réel des aperçus de couleurs const primaryColorInput = document.querySelector('input[name$="[primaryColor]"]'); const secondaryColorInput = document.querySelector('input[name$="[secondaryColor]"]'); const primaryPreview = document.getElementById('primary-preview'); const secondaryPreview = document.getElementById('secondary-preview'); if (primaryColorInput && primaryPreview) { primaryColorInput.addEventListener('input', function() { primaryPreview.style.backgroundColor = this.value; }); } if (secondaryColorInput && secondaryPreview) { secondaryColorInput.addEventListener('input', function() { secondaryPreview.style.backgroundColor = this.value; }); } // Gestion de la collection de certificats const addCertificateBtn = document.querySelector('[data-collection-add-btn]'); if (addCertificateBtn) { addCertificateBtn.addEventListener('click', function() { // Logique d'ajout dynamique des certificats }); } // Gestion du recadrage d'images const logoUpload = document.getElementById('logo-upload'); const bannerUpload = document.getElementById('banner-upload'); const cropLogoBtn = document.getElementById('crop-logo-btn'); const cropBannerBtn = document.getElementById('crop-banner-btn'); // Logo upload handler if (logoUpload && cropLogoBtn) { logoUpload.addEventListener('change', function() { if (this.files && this.files[0]) { cropLogoBtn.disabled = false; cropLogoBtn.textContent = 'Recadrer logo'; cropLogoBtn.classList.remove('btn-outline-primary'); cropLogoBtn.classList.add('btn-warning'); } }); cropLogoBtn.addEventListener('click', function() { const file = logoUpload.files[0]; if (file) { uploadTempImage(file, 'logo'); } }); } // Banner upload handler if (bannerUpload && cropBannerBtn) { bannerUpload.addEventListener('change', function() { if (this.files && this.files[0]) { cropBannerBtn.disabled = false; cropBannerBtn.textContent = 'Recadrer bannière'; cropBannerBtn.classList.remove('btn-outline-primary'); cropBannerBtn.classList.add('btn-warning'); } }); cropBannerBtn.addEventListener('click', function() { const file = bannerUpload.files[0]; if (file) { uploadTempImage(file, 'banner'); } }); } // Fonction pour upload temporaire function uploadTempImage(file, type) { const formData = new FormData(); formData.append('file', file); formData.append('type', type); // Afficher un indicateur de chargement const btn = type === 'logo' ? cropLogoBtn : cropBannerBtn; const originalText = btn.innerHTML; btn.innerHTML = ' • { console.error('Erreur:', error); alert('Erreur lors de la suppression'); }); } • Logo • Bannière 📄 dashboard/crop/base.html.twig ------------------------------------------------------------ • Instructions d'utilisation • Glissez-déposez votre image ou cliquez sur la zone pour la sélectionner • Utilisez les outils de zoom et rotation pour ajuster l'image • Déplacez et redimensionnez la zone de sélection • Prévisualisez le résultat en temps réel • Cliquez sur "Sauvegarder" pour finaliser • Glissez votre image ici ou cliquez pour sélectionner • Annuler • Sauvegarder • Aperçu • Largeur • Hauteur • Retour • Image à recadrer 📄 dashboard/index.html.twig ------------------------------------------------------------ • Sécurisé par Stripe • Commission 5% • Transferts automatiques • ✓ Activé • ⚠ Configuration requise • Mes Commandes • Gérer les ventes • Devis Livraison • Proposer des tarifs • Finances • Revenus & Bilans • 0 € ce mois • Configuration • Paramètres vendeur • Action requise • ✓ Configuré • Transactions terminées • Taux de conversion • Objets publiés • Par catégories • Aucun objet encore • Actions rapides • Ajouter un objet • Gérer mes objets • Modifier le profil • Profil public • Profil en préparation • Vous avez ajouté • Close 📄 dashboard/item_form.html.twig ------------------------------------------------------------ • .image-upload-container { border: 2px dashed #dee2e6; border-radius: 8px; padding: 2rem; text-align: center; transition: all 0.3s ease; background-color: #f8f9fa; position: relative; min-height: 200px; } .image-upload-container.dragover { border-color: #0d6efd; background-color: #e7f3ff; transform: scale(1.02); } .image-upload-container:hover { border-color: #adb5bd; background-color: #f1f3f4; } .upload-icon { font-size: 3rem; color: #6c757d; margin-bottom: 1rem; } .image-preview-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; margin-top: 1rem; } .image-preview-item { position: relative; border-radius: 8px; overflow: hidden; background: #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: transform 0.2s ease; } .image-preview-item:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.15); } .image-preview { width: 100%; height: 120px; object-fit: cover; display: block; } .image-preview-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.7); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s ease; } .image-preview-item:hover .image-preview-overlay { opacity: 1; } .image-remove-btn { background: #dc3545; border: none; color: white; border-radius: 50%; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background-color 0.2s ease; } .image-remove-btn:hover { background: #c82333; } .progress-container { margin-top: 0.5rem; } .progress { height: 4px; background-color: #e9ecef; border-radius: 2px; overflow: hidden; } .progress-bar { background: linear-gradient(90deg, #0d6efd, #0056b3); transition: width 0.3s ease; } .image-info { padding: 0.5rem; font-size: 0.8rem; color: #6c757d; background: #f8f9fa; } .file-input-hidden { display: none; } .upload-button { background: #0d6efd; color: white; border: none; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; transition: background-color 0.2s ease; margin-top: 1rem; } .upload-button:hover { background: #0056b3; } .error-message { color: #dc3545; font-size: 0.875rem; margin-top: 0.5rem; } • Principal • Astuce : • Vous pouvez réorganiser vos images en les glissant-déposant. La première image sera utilisée comme image principale. • this.maxSize) { this.showError(`Fichier trop volumineux: ${file.name} (max 5MB)`); return false; } return true; } createPreview(file) { const reader = new FileReader(); const previewItem = document.createElement('div'); previewItem.className = 'image-preview-item'; const img = document.createElement('img'); img.className = 'image-preview'; const overlay = document.createElement('div'); overlay.className = 'image-preview-overlay'; const removeBtn = document.createElement('button'); removeBtn.className = 'image-remove-btn'; removeBtn.innerHTML = ' • this.removeFile(file, previewItem)); const info = document.createElement('div'); info.className = 'image-info'; info.innerHTML = ` • ${this.formatFileSize(file.size)} • `; const progressContainer = document.createElement('div'); progressContainer.className = 'progress-container'; progressContainer.innerHTML = ` • { console.log(`Adding file ${index}:`, file.name, file.size); dt.items.add(file); }); this.fileInput.files = dt.files; console.log('FileInput files after assignment:', this.fileInput.files.length); // Vérification supplémentaire console.log('Final verification - fileInput.files:'); for (let i = 0; i • { const existingBadge = imageDiv.querySelector('.badge.bg-success'); if (index === 0) { // Première image = principale if (!existingBadge) { const badgeContainer = document.createElement('div'); badgeContainer.className = 'position-absolute top-0 start-0 p-1'; badgeContainer.innerHTML = ' • '; imageDiv.querySelector('.position-relative').appendChild(badgeContainer); } } else { // Supprimer le badge principal des autres images if (existingBadge) { existingBadge.parentElement.remove(); } } }); } // Fonction pour afficher des alertes function showAlert(type, message) { const alertContainer = document.createElement('div'); alertContainer.className = `alert alert-${type === 'success' ? 'success' : 'danger'} alert-dismissible fade show position-fixed`; alertContainer.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;'; alertContainer.innerHTML = ` • { if (alertContainer.parentNode) { alertContainer.remove(); } }, 5000); } // Validation du formulaire (function() { 'use strict'; window.addEventListener('load', function() { var forms = document.getElementsByClassName('needs-validation'); var validation = Array.prototype.filter.call(forms, function(form) { form.addEventListener('submit', function(event) { if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }, false); }); }, false); })(); • Supprimer cette image 📄 dashboard/item_form_ajax.html.twig ------------------------------------------------------------ • .modern-form-container { background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); border: 1px solid #e9ecef; } .form-title { color: #495057; font-weight: 600; margin-bottom: 25px; display: flex; align-items: center; gap: 10px; } .image-reorder-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; margin-top: 15px; } .existing-image-item { position: relative; border-radius: 12px; overflow: hidden; cursor: move; transition: all 0.3s ease; background: white; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .existing-image-item:hover { transform: translateY(-4px); box-shadow: 0 8px 25px rgba(0,0,0,0.15); } .existing-image-item.sortable-chosen { transform: scale(1.05); box-shadow: 0 12px 30px rgba(0,123,255,0.3); } .existing-image-item.sortable-ghost { opacity: 0.5; transform: scale(0.95); } .badge-primary-image { position: absolute; top: 8px; left: 8px; background: linear-gradient(135deg, #28a745, #20c997); border: none; box-shadow: 0 2px 8px rgba(40,167,69,0.3); } .delete-existing-btn { position: absolute; top: 8px; right: 8px; background: rgba(220,53,69,0.9); border: none; width: 32px; height: 32px; border-radius: 50%; color: white; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; backdrop-filter: blur(10px); } .delete-existing-btn:hover { background: #dc3545; transform: scale(1.1); } .image-info-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.8)); color: white; padding: 10px; font-size: 0.75rem; } .sortable-helper { transform: rotate(5deg); box-shadow: 0 15px 35px rgba(0,0,0,0.3); z-index: 1000; } • 20 ? image.originalName[:20] ~ '...' : image.originalName }} • { // Si pas d'item ID (nouveau), on doit gérer les images temporaires if (!itemId) { // Vérifier s'il y a des uploads en cours if (uploader.hasActiveUploads()) { e.preventDefault(); // Afficher un message stylé const toast = document.createElement('div'); toast.className = 'alert alert-warning alert-dismissible fade show position-fixed'; toast.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;'; toast.innerHTML = ` • ${translations.uploadInProgress} • ${translations.waitUploads} • { if (toast.parentNode) { toast.remove(); } }, 5000); return; } // Stocker les noms de fichiers uploadés const filenames = uploader.getUploadedFilenames(); uploadedFilenamesInput.value = JSON.stringify(filenames); console.log('Formulaire soumis avec images:', filenames); } // Désactiver le bouton pendant la soumission submitBtn.disabled = true; submitBtn.innerHTML = ` • { console.error('Erreur:', error); showToast(translations.connectionError, 'danger'); }); } // Afficher un toast message function showToast(message, type = 'info') { const toast = document.createElement('div'); toast.className = `alert alert-${type} alert-dismissible fade show position-fixed`; toast.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 250px;'; toast.innerHTML = ` • { if (toast.parentNode) { toast.remove(); } }, 3000); } // Fonction globale pour supprimer les images existantes window.deleteExistingImage = function(imageId, filename) { if (!confirm(`${translations.deleteConfirm} "${filename}" ?`)) { return; } const button = event.target.closest('button'); const imageContainer = button.closest('.existing-image-item'); const originalContent = button.innerHTML; button.disabled = true; button.innerHTML = ' • { console.error('Erreur:', error); button.disabled = false; button.innerHTML = originalContent; showToast(translations.connectionError, 'danger'); }); }; 📄 dashboard/items/form.html.twig ------------------------------------------------------------ • Dashboard • Accueil • Mes Objets • Profil • Retour • Informations de l'objet • Annuler • Conseils • Photos de qualité • Éclairage naturel optimal • Plusieurs angles de vue • Détails importants • Résolution 800x600px min 📄 dashboard/messages/index.html.twig ------------------------------------------------------------ • Profil en préparation • Pagination des messages 📄 dashboard/messages/show.html.twig ------------------------------------------------------------ • // Faire défiler vers le bas de la conversation document.addEventListener('DOMContentLoaded', function() { const messageContainer = document.querySelector('.message-container'); if (messageContainer) { messageContainer.scrollTop = messageContainer.scrollHeight; } }); // Auto-réajuster la hauteur du textarea document.getElementById('reply_content')?.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 200) + 'px'; }); 📄 dashboard/profile.html.twig ------------------------------------------------------------ • Mettre à jour le profil • Informations du compte • Membre depuis : • Type de compte : • Statut : • Vérifié • En attente • Statistiques : 📄 dashboard/profile/_gps_map_modal.html.twig ------------------------------------------------------------ • Close 📄 dashboard/profile/_streetview_modal.html.twig ------------------------------------------------------------ • Close 📄 dashboard/statistics/detailed.html.twig ------------------------------------------------------------ • Statistiques Détaillées • Vue détaillée des statistiques pour la période sélectionnée 📄 dashboard/statistics/index.html.twig ------------------------------------------------------------ • Mes Statistiques • Vue détaillée • Exporter • Période : • Ce mois • Mois dernier • Vues ce mois • Clics ce mois • Messages reçus • Interactions cette semaine • Vue d'ensemble • Total des vues • Total des clics • Répartition par langue • Top 5 objets • Métriques de performance • Taux de conversion profil • Taux de conversion objets • Taux d'engagement global • Conversion moyenne objets • Pas encore assez de données pour calculer les métriques de conversion. • Comparaison avec la période précédente 📄 dashboard/stripe_connect/bank_account.html.twig ------------------------------------------------------------ • Espace Vendeur • Compte bancaire • Compte bancaire (RIB) • Compte bancaire enregistré • Votre IBAN se terminant par • est configuré. • Les paiements seront virés automatiquement sur ce compte. • IBAN français • Saisissez votre IBAN complet (27 caractères) sans espaces. • Exemple : FR7612345678901234567890123 • Information importante • Seuls les comptes bancaires français (IBAN commençant par FR) sont acceptés • Le compte doit être à votre nom (identique aux informations personnelles) • Les virements sont effectués automatiquement selon la fréquence définie par Stripe • Une commission de 5% est prélevée sur chaque vente avant le virement • Retour • Sécurité • Paiements sécurisés • Stripe Connect garantit la sécurité de vos informations bancaires et la conformité aux normes PCI DSS. • Fréquence des virements • Par défaut, Stripe effectue les virements quotidiennement (jours ouvrés) avec un délai de 2 jours ouvrés. • Calcul des revenus • Prix de vente • Commission (5%) • Vous recevez • 29) { e.target.setCustomValidity('L\'IBAN français ne peut pas dépasser 27 caractères'); } else { e.target.setCustomValidity(''); } e.target.value = value; }); 📄 dashboard/stripe_connect/documents.html.twig ------------------------------------------------------------ • Espace Vendeur • Documents • Documents d'identité • Documents uploadés • Vos documents sont en cours de vérification par Stripe. • Recto de la pièce d'identité • Verso de la pièce d'identité • Formats acceptés : JPG, PNG, PDF (max 10MB) • Document déjà uploadé • Exigences importantes • Pièces acceptées : • Carte d'identité, passeport ou permis de conduire français • Qualité : • Photos nettes, lisibles, sans reflets • Intégrité : • Document entier visible, non rogné • Validité : • Document en cours de validité • Correspondance : • Nom et prénom identiques aux informations personnelles • Retour • Conseils photo • ✓ Bonne photo • Éclairage uniforme • Document à plat • Texte lisible • Couleurs naturelles • Haute résolution • ✗ Éviter • Photos floues ou pixelisées • Reflets ou ombres • Document plié ou abîmé • Partie du document coupée • Mauvais éclairage • Traitement • La vérification de vos documents prend généralement entre quelques minutes et 24 heures. • Sécurité des données • Vos documents sont transmis de manière sécurisée à Stripe pour vérification. Ils ne sont utilisés que dans le cadre de la conformité KYC et ne sont jamais partagés avec des tiers. • 10 * 1024 * 1024) { // 10MB alert('Le fichier est trop volumineux. Taille maximum : 10MB'); e.target.value = ''; } }); }); 📄 dashboard/stripe_connect/index.html.twig ------------------------------------------------------------ • Espace Vendeur • Devenir Vendeur • Devenez vendeur sur notre marketplace • Vendez vos objets et recevez automatiquement 95% du montant payé • Transformez votre compte en espace vendeur et commencez à vendre vos objets directement sur la marketplace. Nous prenons seulement 5% de commission. • Commission de seulement 5% • Vous gardez 95% de chaque vente • Paiements automatiques • Virements directs sur votre compte • Paiements sécurisés • Géré par Stripe Connect • Tableau de bord complet • Suivez vos ventes et revenus • Pour devenir vendeur, vous devrez : • Fournir vos informations personnelles (nom, prénom, date de naissance) • Ajouter votre RIB (IBAN français) • Télécharger une pièce d'identité valide • Statut de votre compte vendeur • Compte Vérifié • Félicitations ! Votre compte vendeur est actif. • Vous pouvez maintenant recevoir des paiements. • En cours de vérification • Votre compte est en cours de vérification. • Veuillez compléter les informations demandées ci-dessous. • En attente • Configuration de votre compte en cours. • Complétez les étapes ci-dessous pour activer votre compte. • Prêt à vendre • Configuration • Informations personnelles • Nom, prénom, date de naissance, adresse • Gérer • Compte bancaire • RIB pour recevoir vos paiements • Documents • Pièce d'identité recto/verso • Mes ventes • Statistiques et revenus • Voir • Bientôt disponible • Solde actuel • Disponible • Revenus totaux • Depuis le début 📄 dashboard/stripe_connect/personal_info.html.twig ------------------------------------------------------------ • Espace Vendeur • Informations personnelles • Prénom • Modifiez dans votre profil principal • Nom • Date de naissance • Jour • Mois • Année • Vous devez être majeur pour devenir vendeur • Téléphone • Format : +33123456789 ou 01 23 45 67 89 • Adresse • Code postal • Ville • Retour • Enregistrer • Informations importantes • Protection des données • Vos informations personnelles sont protégées et utilisées uniquement pour la vérification de votre identité conformément aux exigences de Stripe. • Vérification KYC • Ces informations doivent correspondre exactement à celles de votre pièce d'identité. • Exigences restantes : 📄 dashboard/stripe_connect/sales.html.twig ------------------------------------------------------------ • Espace Vendeur • Mes ventes • Revenus totaux • Disponible • En attente • Commission • Évolution des revenus • Le graphique des revenus sera disponible prochainement une fois que vous aurez effectué vos premières ventes. • Cette semaine • Ce mois • Cette année • Prochains virements • Montant disponible • Les virements sont effectués automatiquement par Stripe selon la fréquence configurée (généralement quotidienne avec un délai de 2 jours ouvrés). • Aucun virement en attente • Historique des transactions • Aucune transaction pour le moment • Vos ventes et virements apparaîtront ici une fois que vous commencerez à vendre. • Ajouter un objet à vendre • Comment ça marche ? • Vente d'un objet • Un acheteur paie votre objet par carte bancaire • Commission automatique • 5% sont prélevés, vous recevez 95% du montant • Virement automatique • L'argent est viré sur votre compte bancaire • Simulateur de revenus • Prix de vente • Prix de vente : • Commission (5%) : • Vous recevez : • // Simulateur de revenus document.getElementById('simulation_price').addEventListener('input', function() { const price = parseFloat(this.value) || 0; const commission = price * 0.05; const earnings = price - commission; document.getElementById('sim_price').textContent = price.toFixed(2) + '€'; document.getElementById('sim_commission').textContent = '-' + commission.toFixed(2) + '€'; document.getElementById('sim_earnings').textContent = earnings.toFixed(2) + '€'; }); 📄 dashboard/templates.html.twig ------------------------------------------------------------ • 100 ? template.templateDescription|slice(0, 100) ~ '...' : template.templateDescription }} • { console.error('Error:', error); alert(translations.delete_error); }); bootstrap.Modal.getInstance(document.getElementById('deleteTemplateModal')).hide(); }; new bootstrap.Modal(document.getElementById('deleteTemplateModal')).show(); } 📄 directory/index.html.twig ------------------------------------------------------------ • Annuaire des Antiquaires • Découvrez les meilleurs professionnels des antiquités partout en France • Antiquaires • Régions • Spécialités • Recherche • Région • Toutes les régions • Spécialité • Toutes les spécialités • Tri • Nom A-Z • Nom Z-A • Ville A-Z • Plus récents • Rechercher • Réinitialiser • Voir le profil • Aucun antiquaire trouvé • Essayez de modifier vos critères de recherche. • document.addEventListener('DOMContentLoaded', function() { // Initialisation AOS optimisée AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 50, disable: function() { // Désactiver sur mobile pour les performances return window.innerWidth • { const filtersSection = document.getElementById('filters'); if (filtersSection) { const rect = filtersSection.getBoundingClientRect(); const offset = 20; // Espace au-dessus des filtres const scrollTop = window.pageYOffset + rect.top - offset; window.scrollTo({ top: scrollTop, behavior: 'smooth' }); } }, 100); } }); • Nom, ville, spécialité... • Pagination antiquaires 📄 directory/member_show.html.twig ------------------------------------------------------------ • Accueil • Antiquaires • Localiser • Street View • Téléphone • Message • Site Web • RÉSERVÉ • Prix sur demande • Chargement... • Galerie avec pagination disponible • Voir la galerie complète • Galerie en préparation • Aucun objet en ligne • Ce membre n'a pas encore d'objets en ligne. • À propos • Notre Histoire • Ce membre n'a pas encore renseigné de description. • Spécialités • Nom * • Email * • Sujet * • Choisir un sujet • Demande d'information • Achat d'un objet • Demande d'expertise • Autre • Message * • J'accepte que mes données soient utilisées pour traiter ma demande * • Annuler • Envoyer • /* Styles pour les boutons de contact en une ligne */ .contact-buttons-single-row { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 1rem; } .contact-btn-narrow { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 12px 8px; text-decoration: none; border: 2px solid #e3f2fd; border-radius: 12px; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); color: #495057; font-size: 0.85rem; font-weight: 500; transition: all 0.3s ease; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .contact-btn-narrow:hover { background: linear-gradient(135deg, #007bff 0%, #0056b3 100%); color: white; border-color: #007bff; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3); } .contact-btn-narrow i { font-size: 1.2rem; margin-bottom: 4px; } .contact-btn-narrow span { font-size: 0.8rem; line-height: 1.2; text-align: center; } /* Responsive pour mobile */ @media (max-width: 768px) { .contact-buttons-single-row { flex-direction: column; gap: 12px; } .contact-btn-narrow { flex-direction: row; min-height: 50px; padding: 12px 16px; } .contact-btn-narrow i { margin-bottom: 0; margin-right: 8px; font-size: 1rem; } .contact-btn-narrow span { font-size: 0.9rem; } } /* Animation pour le téléphone révélé */ .phone-reveal .phone-shown { animation: fadeIn 0.3s ease-in-out; } @keyframes fadeIn { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: scale(1); } } • document.addEventListener('DOMContentLoaded', function() { // Initialize AOS AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 100 }); // Phone reveal functionality document.querySelectorAll('.phone-reveal').forEach(function(btn) { btn.addEventListener('click', function() { const hiddenSpan = this.querySelector('.phone-hidden'); const shownSpan = this.querySelector('.phone-shown'); hiddenSpan.classList.add('d-none'); shownSpan.classList.remove('d-none'); }); }); // Contact form submission const contactForm = document.getElementById('contactForm'); if (contactForm) { contactForm.addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); const submitBtn = this.querySelector('[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.innerHTML = ' • Voir sur Google Maps • Vue Street View • Révéler le téléphone • Fermer 📄 directory/region.html.twig ------------------------------------------------------------ • :root { --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); --accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); --dark-gradient: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); --green-gradient: linear-gradient(135deg, #a8e6cf 0%, #3d8b37 100%); } .region-page { min-height: 100vh; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); position: relative; overflow-x: hidden; padding: 2rem 0; } .region-page::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 40% 80%, rgba(120, 200, 255, 0.3) 0%, transparent 50%); z-index: -1; animation: backgroundShift 20s ease-in-out infinite; } @keyframes backgroundShift { 0%, 100% { transform: translateX(0) translateY(0); } 25% { transform: translateX(-20px) translateY(-10px); } 50% { transform: translateX(20px) translateY(10px); } 75% { transform: translateX(-10px) translateY(20px); } } /* Breadcrumb */ .breadcrumb-custom { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem 1.5rem; margin-bottom: 2rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .breadcrumb-custom .breadcrumb { margin-bottom: 0; background: none; padding: 0; } /* Region Header */ .region-header { background: var(--green-gradient); color: white; padding: 4rem 0; margin-bottom: 3rem; position: relative; overflow: hidden; clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%); } .region-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Cpolygon points='30 10 10 50 50 50'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") repeat; animation: patternMove 30s linear infinite; } @keyframes patternMove { 0% { background-position: 0 0; } 100% { background-position: 60px 60px; } } .region-content { position: relative; z-index: 2; text-align: center; } .region-title { font-size: 3rem; font-weight: 800; margin-bottom: 1rem; background: linear-gradient(45deg, #ffffff, #f8f9fa); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; text-shadow: 0 4px 8px rgba(0,0,0,0.2); position: relative; } .region-title::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 120px; height: 4px; background: var(--accent-gradient); border-radius: 2px; animation: shimmer 2s ease-in-out infinite; } @keyframes shimmer { 0%, 100% { opacity: 1; transform: translateX(-50%) scaleX(1); } 50% { opacity: 0.7; transform: translateX(-50%) scaleX(1.2); } } .region-subtitle { font-size: 1.3rem; margin-bottom: 2rem; opacity: 0.95; font-weight: 300; } .region-icon { font-size: 4rem; margin-bottom: 2rem; background: rgba(255,255,255,0.2); width: 120px; height: 120px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 2rem; backdrop-filter: blur(10px); border: 2px solid rgba(255,255,255,0.3); animation: float 4s ease-in-out infinite; } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } /* Stats Section */ .region-stats { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; padding: 2rem; margin-bottom: 3rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; text-align: center; } .stat-card { background: var(--green-gradient); color: white; padding: 1.5rem; border-radius: 15px; box-shadow: 0 8px 25px rgba(168, 230, 207, 0.4); transition: transform 0.3s ease; } .stat-card:hover { transform: translateY(-5px); } .stat-number { font-size: 2.5rem; font-weight: 800; display: block; margin-bottom: 0.5rem; } .stat-label { font-size: 1rem; opacity: 0.9; font-weight: 500; } /* Member Cards - Same as directory index but with green accent */ .member-card { background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 20px; padding: 0; margin-bottom: 2rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.8); border: 1px solid rgba(255,255,255,0.6); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); position: relative; overflow: hidden; } .member-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--green-gradient); transform: scaleX(0); transition: transform 0.3s ease; } .member-card:hover::before { transform: scaleX(1); } .member-card:hover { transform: translateY(-8px); box-shadow: 0 20px 60px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.9); } .member-card-header { padding: 2rem 2rem 1rem; display: flex; align-items: center; gap: 1.5rem; position: relative; } .member-avatar { width: 100px; height: 100px; border-radius: 20px; background: var(--green-gradient); display: flex; align-items: center; justify-content: center; color: white; font-size: 2.5rem; box-shadow: 0 8px 25px rgba(168, 230, 207, 0.4), inset 0 1px 0 rgba(255,255,255,0.3); position: relative; overflow: hidden; } .member-avatar::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); transform: rotate(45deg); animation: avatarShine 3s ease-in-out infinite; } @keyframes avatarShine { 0%, 100% { transform: translateX(-200%) translateY(-200%) rotate(45deg); } 50% { transform: translateX(200%) translateY(200%) rotate(45deg); } } .member-basic-info { flex: 1; } .member-name { font-size: 1.6rem; font-weight: 700; margin-bottom: 0.5rem; background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .member-location { color: #6c757d; font-weight: 500; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0; } .member-location i { color: #3d8b37; } .member-card-body { padding: 0 2rem 1rem; } .member-specialties { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.5rem; } .specialty-tag { background: var(--accent-gradient); color: white; padding: 0.4rem 0.8rem; border-radius: 20px; font-size: 0.85rem; font-weight: 600; box-shadow: 0 2px 8px rgba(79, 172, 254, 0.3); transition: transform 0.2s ease; } .specialty-tag:hover { transform: translateY(-2px); } .specialty-tag.more { background: var(--secondary-gradient); box-shadow: 0 2px 8px rgba(240, 147, 251, 0.3); } .member-description { color: #5a6c7d; line-height: 1.6; margin-bottom: 1.5rem; font-size: 0.95rem; } .member-contact { margin-bottom: 1.5rem; } .contact-item { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; color: #5a6c7d; font-size: 0.9rem; } .contact-item i { width: 18px; color: #3d8b37; font-size: 1rem; } .contact-item a { color: #3d8b37; text-decoration: none; font-weight: 500; transition: color 0.2s ease; } .contact-item a:hover { color: #2d6b2f; } .member-card-footer { padding: 1rem 2rem 2rem; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid rgba(61, 139, 55, 0.1); margin-top: 1rem; } .member-stats { display: flex; gap: 1.5rem; } .stat-item { display: flex; align-items: center; gap: 0.5rem; color: #6c757d; font-size: 0.85rem; font-weight: 500; } .stat-item i { color: #3d8b37; } .btn-profile { background: var(--green-gradient); border: none; color: white; padding: 0.6rem 1.5rem; border-radius: 12px; font-weight: 600; text-decoration: none; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(168, 230, 207, 0.4); position: relative; overflow: hidden; } .btn-profile::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.6s ease; } .btn-profile:hover::before { left: 100%; } .btn-profile:hover { color: white; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(168, 230, 207, 0.6); } /* No Results */ .no-results { text-align: center; padding: 4rem 2rem; background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .no-results i { color: #3d8b37; margin-bottom: 1.5rem; animation: float 3s ease-in-out infinite; } .no-results h4 { background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1rem; } .no-results p { color: #6c757d; margin-bottom: 2rem; } /* Pagination */ .pagination-custom { margin-top: 3rem; margin-bottom: 2rem; } .pagination { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .page-link { border: none; background: transparent; color: #3d8b37; font-weight: 500; padding: 0.75rem 1rem; border-radius: 8px; margin: 0 0.25rem; transition: all 0.3s ease; } .page-link:hover { background: var(--green-gradient); color: white; transform: translateY(-2px); } .page-item.active .page-link { background: var(--green-gradient); color: white; box-shadow: 0 4px 15px rgba(168, 230, 207, 0.4); } /* Responsive Design */ @media (max-width: 768px) { .region-title { font-size: 2rem; } .stats-grid { grid-template-columns: 1fr; gap: 1rem; } .member-card-header { flex-direction: column; text-align: center; gap: 1rem; } .member-card-footer { flex-direction: column; gap: 1rem; align-items: stretch; } .member-stats { justify-content: center; } } • Accueil • Annuaire • Villes couvertes • Objets en moyenne • Qualité régionale • Voir le site web • Voir le profil • Précédent • Suivant • Aucun antiquaire trouvé • Retour à l'annuaire • document.addEventListener('DOMContentLoaded', function() { // Initialize AOS AOS.init({ duration: 800, easing: 'ease-out-quart', once: true }); }); 📄 directory/search.html.twig ------------------------------------------------------------ • :root { --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); --accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); --dark-gradient: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); } .search-page { min-height: 100vh; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); position: relative; overflow-x: hidden; padding: 2rem 0; } .search-page::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 40% 80%, rgba(120, 200, 255, 0.3) 0%, transparent 50%); z-index: -1; animation: backgroundShift 20s ease-in-out infinite; } @keyframes backgroundShift { 0%, 100% { transform: translateX(0) translateY(0); } 25% { transform: translateX(-20px) translateY(-10px); } 50% { transform: translateX(20px) translateY(10px); } 75% { transform: translateX(-10px) translateY(20px); } } /* Breadcrumb */ .breadcrumb-custom { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem 1.5rem; margin-bottom: 2rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .breadcrumb-custom .breadcrumb { margin-bottom: 0; background: none; padding: 0; } /* Search Header */ .search-header { background: var(--primary-gradient); color: white; padding: 3rem 0; margin-bottom: 3rem; position: relative; overflow: hidden; clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%); } .search-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") repeat; animation: patternMove 30s linear infinite; } @keyframes patternMove { 0% { background-position: 0 0; } 100% { background-position: 60px 60px; } } .search-content { position: relative; z-index: 2; text-align: center; } .search-title { font-size: 2.5rem; font-weight: 800; margin-bottom: 1rem; background: linear-gradient(45deg, #ffffff, #f8f9fa); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; text-shadow: 0 4px 8px rgba(0,0,0,0.2); } .search-subtitle { font-size: 1.2rem; margin-bottom: 2rem; opacity: 0.95; font-weight: 300; } .search-form-container { max-width: 600px; margin: 0 auto; } .search-form { display: flex; gap: 1rem; background: rgba(255,255,255,0.1); padding: 1rem; border-radius: 15px; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.2); } .search-form input { flex: 1; border: none; background: rgba(255,255,255,0.9); border-radius: 10px; padding: 0.75rem 1rem; font-size: 1rem; } .search-form input:focus { outline: none; background: white; box-shadow: 0 0 0 3px rgba(255,255,255,0.3); } .search-form button { background: var(--accent-gradient); border: none; color: white; padding: 0.75rem 1.5rem; border-radius: 10px; font-weight: 600; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(79, 172, 254, 0.4); } .search-form button:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(79, 172, 254, 0.6); } /* Results Section */ .results-section { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; padding: 2rem; margin-bottom: 2rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .results-count { font-size: 1.4rem; font-weight: 700; background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1.5rem; display: flex; align-items: center; gap: 0.5rem; } .results-count i { color: #667eea; } /* Member Cards - Same as directory index */ .member-card { background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 20px; padding: 0; margin-bottom: 2rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.8); border: 1px solid rgba(255,255,255,0.6); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); position: relative; overflow: hidden; } .member-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--primary-gradient); transform: scaleX(0); transition: transform 0.3s ease; } .member-card:hover::before { transform: scaleX(1); } .member-card:hover { transform: translateY(-8px); box-shadow: 0 20px 60px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.9); } .member-card-header { padding: 2rem 2rem 1rem; display: flex; align-items: center; gap: 1.5rem; position: relative; } .member-avatar { width: 100px; height: 100px; border-radius: 20px; background: var(--primary-gradient); display: flex; align-items: center; justify-content: center; color: white; font-size: 2.5rem; box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3), inset 0 1px 0 rgba(255,255,255,0.3); position: relative; overflow: hidden; } .member-avatar::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); transform: rotate(45deg); animation: avatarShine 3s ease-in-out infinite; } @keyframes avatarShine { 0%, 100% { transform: translateX(-200%) translateY(-200%) rotate(45deg); } 50% { transform: translateX(200%) translateY(200%) rotate(45deg); } } .member-basic-info { flex: 1; } .member-name { font-size: 1.6rem; font-weight: 700; margin-bottom: 0.5rem; background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .member-location { color: #6c757d; font-weight: 500; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0; } .member-location i { color: #667eea; } .member-card-body { padding: 0 2rem 1rem; } .member-specialties { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.5rem; } .specialty-tag { background: var(--accent-gradient); color: white; padding: 0.4rem 0.8rem; border-radius: 20px; font-size: 0.85rem; font-weight: 600; box-shadow: 0 2px 8px rgba(79, 172, 254, 0.3); transition: transform 0.2s ease; } .specialty-tag:hover { transform: translateY(-2px); } .specialty-tag.more { background: var(--secondary-gradient); box-shadow: 0 2px 8px rgba(240, 147, 251, 0.3); } .member-description { color: #5a6c7d; line-height: 1.6; margin-bottom: 1.5rem; font-size: 0.95rem; } .member-contact { margin-bottom: 1.5rem; } .contact-item { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; color: #5a6c7d; font-size: 0.9rem; } .contact-item i { width: 18px; color: #667eea; font-size: 1rem; } .contact-item a { color: #667eea; text-decoration: none; font-weight: 500; transition: color 0.2s ease; } .contact-item a:hover { color: #5a67d8; } .member-card-footer { padding: 1rem 2rem 2rem; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid rgba(102, 126, 234, 0.1); margin-top: 1rem; } .member-stats { display: flex; gap: 1.5rem; } .stat-item { display: flex; align-items: center; gap: 0.5rem; color: #6c757d; font-size: 0.85rem; font-weight: 500; } .stat-item i { color: #667eea; } .btn-profile { background: var(--primary-gradient); border: none; color: white; padding: 0.6rem 1.5rem; border-radius: 12px; font-weight: 600; text-decoration: none; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); position: relative; overflow: hidden; } .btn-profile::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.6s ease; } .btn-profile:hover::before { left: 100%; } .btn-profile:hover { color: white; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(102, 126, 234, 0.6); } /* No Results */ .no-results { text-align: center; padding: 4rem 2rem; background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .no-results i { color: #667eea; margin-bottom: 1.5rem; animation: float 3s ease-in-out infinite; } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } .no-results h4 { background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1rem; } .no-results p { color: #6c757d; margin-bottom: 2rem; } /* Pagination */ .pagination-custom { margin-top: 3rem; margin-bottom: 2rem; } .pagination { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .page-link { border: none; background: transparent; color: #667eea; font-weight: 500; padding: 0.75rem 1rem; border-radius: 8px; margin: 0 0.25rem; transition: all 0.3s ease; } .page-link:hover { background: var(--primary-gradient); color: white; transform: translateY(-2px); } .page-item.active .page-link { background: var(--primary-gradient); color: white; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); } /* Responsive Design */ @media (max-width: 768px) { .search-title { font-size: 2rem; } .search-form { flex-direction: column; } .member-card-header { flex-direction: column; text-align: center; gap: 1rem; } .member-card-footer { flex-direction: column; gap: 1rem; align-items: stretch; } .member-stats { justify-content: center; } } • Accueil • Annuaire • Recherche • Recherche d'Antiquaires • Trouvez l'antiquaire parfait selon vos critères • Rechercher • Voir le site web • Voir le profil • Précédent • Suivant • Aucun antiquaire trouvé • Retour à l'annuaire • Saisissez votre recherche • Entrez au moins 2 caractères pour effectuer une recherche. • document.addEventListener('DOMContentLoaded', function() { // Initialize AOS AOS.init({ duration: 800, easing: 'ease-out-quart', once: true }); // Auto-focus search input const searchInput = document.querySelector('.search-form input'); if (searchInput && !searchInput.value) { searchInput.focus(); } // Search form enhancements const searchForm = document.querySelector('.search-form'); searchForm.addEventListener('submit', function() { const submitBtn = this.querySelector('button'); const originalText = submitBtn.innerHTML; submitBtn.innerHTML = ' • { const filtersSection = document.getElementById('filters'); if (filtersSection) { filtersSection.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); } }, 100); // Petit délai pour laisser la page se charger } }); • Nom, ville, spécialité... 📄 directory/specialty.html.twig ------------------------------------------------------------ • :root { --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); --accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); --dark-gradient: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); --gold-gradient: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); } .specialty-page { min-height: 100vh; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); position: relative; overflow-x: hidden; padding: 2rem 0; } .specialty-page::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 40% 80%, rgba(120, 200, 255, 0.3) 0%, transparent 50%); z-index: -1; animation: backgroundShift 20s ease-in-out infinite; } @keyframes backgroundShift { 0%, 100% { transform: translateX(0) translateY(0); } 25% { transform: translateX(-20px) translateY(-10px); } 50% { transform: translateX(20px) translateY(10px); } 75% { transform: translateX(-10px) translateY(20px); } } /* Breadcrumb */ .breadcrumb-custom { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem 1.5rem; margin-bottom: 2rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .breadcrumb-custom .breadcrumb { margin-bottom: 0; background: none; padding: 0; } /* Specialty Header */ .specialty-header { background: var(--gold-gradient); color: white; padding: 4rem 0; margin-bottom: 3rem; position: relative; overflow: hidden; clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%); } .specialty-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Cpath d='M30 30m-15 0a15,15 0 1,1 30,0a15,15 0 1,1 -30,0'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") repeat; animation: patternMove 30s linear infinite; } @keyframes patternMove { 0% { background-position: 0 0; } 100% { background-position: 60px 60px; } } .specialty-content { position: relative; z-index: 2; text-align: center; } .specialty-title { font-size: 3rem; font-weight: 800; margin-bottom: 1rem; background: linear-gradient(45deg, #ffffff, #f8f9fa); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; text-shadow: 0 4px 8px rgba(0,0,0,0.2); position: relative; } .specialty-title::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 120px; height: 4px; background: var(--accent-gradient); border-radius: 2px; animation: shimmer 2s ease-in-out infinite; } @keyframes shimmer { 0%, 100% { opacity: 1; transform: translateX(-50%) scaleX(1); } 50% { opacity: 0.7; transform: translateX(-50%) scaleX(1.2); } } .specialty-subtitle { font-size: 1.3rem; margin-bottom: 2rem; opacity: 0.95; font-weight: 300; } .specialty-icon { font-size: 4rem; margin-bottom: 2rem; background: rgba(255,255,255,0.2); width: 120px; height: 120px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 2rem; backdrop-filter: blur(10px); border: 2px solid rgba(255,255,255,0.3); animation: float 4s ease-in-out infinite; } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } /* Stats Section */ .specialty-stats { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; padding: 2rem; margin-bottom: 3rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; text-align: center; } .stat-card { background: var(--primary-gradient); color: white; padding: 1.5rem; border-radius: 15px; box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3); transition: transform 0.3s ease; } .stat-card:hover { transform: translateY(-5px); } .stat-number { font-size: 2.5rem; font-weight: 800; display: block; margin-bottom: 0.5rem; } .stat-label { font-size: 1rem; opacity: 0.9; font-weight: 500; } /* Member Cards - Same as directory index */ .member-card { background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 20px; padding: 0; margin-bottom: 2rem; box-shadow: 0 10px 40px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.8); border: 1px solid rgba(255,255,255,0.6); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); position: relative; overflow: hidden; } .member-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--gold-gradient); transform: scaleX(0); transition: transform 0.3s ease; } .member-card:hover::before { transform: scaleX(1); } .member-card:hover { transform: translateY(-8px); box-shadow: 0 20px 60px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.9); } .member-card-header { padding: 2rem 2rem 1rem; display: flex; align-items: center; gap: 1.5rem; position: relative; } .member-avatar { width: 100px; height: 100px; border-radius: 20px; background: var(--gold-gradient); display: flex; align-items: center; justify-content: center; color: white; font-size: 2.5rem; box-shadow: 0 8px 25px rgba(255, 230, 210, 0.5), inset 0 1px 0 rgba(255,255,255,0.3); position: relative; overflow: hidden; } .member-avatar::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); transform: rotate(45deg); animation: avatarShine 3s ease-in-out infinite; } @keyframes avatarShine { 0%, 100% { transform: translateX(-200%) translateY(-200%) rotate(45deg); } 50% { transform: translateX(200%) translateY(200%) rotate(45deg); } } .member-basic-info { flex: 1; } .member-name { font-size: 1.6rem; font-weight: 700; margin-bottom: 0.5rem; background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .member-location { color: #6c757d; font-weight: 500; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0; } .member-location i { color: #667eea; } .member-card-body { padding: 0 2rem 1rem; } .member-specialties { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.5rem; } .specialty-tag { background: var(--accent-gradient); color: white; padding: 0.4rem 0.8rem; border-radius: 20px; font-size: 0.85rem; font-weight: 600; box-shadow: 0 2px 8px rgba(79, 172, 254, 0.3); transition: transform 0.2s ease; } .specialty-tag.current { background: var(--gold-gradient); box-shadow: 0 2px 8px rgba(255, 230, 210, 0.5); } .specialty-tag:hover { transform: translateY(-2px); } .specialty-tag.more { background: var(--secondary-gradient); box-shadow: 0 2px 8px rgba(240, 147, 251, 0.3); } .member-description { color: #5a6c7d; line-height: 1.6; margin-bottom: 1.5rem; font-size: 0.95rem; } .member-contact { margin-bottom: 1.5rem; } .contact-item { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; color: #5a6c7d; font-size: 0.9rem; } .contact-item i { width: 18px; color: #667eea; font-size: 1rem; } .contact-item a { color: #667eea; text-decoration: none; font-weight: 500; transition: color 0.2s ease; } .contact-item a:hover { color: #5a67d8; } .member-card-footer { padding: 1rem 2rem 2rem; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid rgba(102, 126, 234, 0.1); margin-top: 1rem; } .member-stats { display: flex; gap: 1.5rem; } .stat-item { display: flex; align-items: center; gap: 0.5rem; color: #6c757d; font-size: 0.85rem; font-weight: 500; } .stat-item i { color: #667eea; } .btn-profile { background: var(--gold-gradient); border: none; color: white; padding: 0.6rem 1.5rem; border-radius: 12px; font-weight: 600; text-decoration: none; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(255, 230, 210, 0.5); position: relative; overflow: hidden; } .btn-profile::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.6s ease; } .btn-profile:hover::before { left: 100%; } .btn-profile:hover { color: white; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(255, 230, 210, 0.7); } /* No Results */ .no-results { text-align: center; padding: 4rem 2rem; background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .no-results i { color: #667eea; margin-bottom: 1.5rem; animation: float 3s ease-in-out infinite; } .no-results h4 { background: var(--dark-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1rem; } .no-results p { color: #6c757d; margin-bottom: 2rem; } /* Pagination */ .pagination-custom { margin-top: 3rem; margin-bottom: 2rem; } .pagination { background: rgba(255,255,255,0.9); backdrop-filter: blur(20px); border-radius: 15px; padding: 1rem; box-shadow: 0 4px 20px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.6); } .page-link { border: none; background: transparent; color: #667eea; font-weight: 500; padding: 0.75rem 1rem; border-radius: 8px; margin: 0 0.25rem; transition: all 0.3s ease; } .page-link:hover { background: var(--gold-gradient); color: white; transform: translateY(-2px); } .page-item.active .page-link { background: var(--gold-gradient); color: white; box-shadow: 0 4px 15px rgba(255, 230, 210, 0.5); } /* Responsive Design */ @media (max-width: 768px) { .specialty-title { font-size: 2rem; } .stats-grid { grid-template-columns: 1fr; gap: 1rem; } .member-card-header { flex-direction: column; text-align: center; gap: 1rem; } .member-card-footer { flex-direction: column; gap: 1rem; align-items: stretch; } .member-stats { justify-content: center; } } • Accueil • Annuaire • Expertise reconnue • Années d'expérience moyenne • Voir le site web • Voir le profil • Précédent • Suivant • Aucun antiquaire trouvé • Retour à l'annuaire • document.addEventListener('DOMContentLoaded', function() { // Initialize AOS AOS.init({ duration: 800, easing: 'ease-out-quart', once: true }); }); 📄 email/account/password_reset.html.twig ------------------------------------------------------------ • 🔐 Réinitialisation de mot de passe • Vous avez demandé à réinitialiser votre mot de passe sur Antiquités en France. Cliquez sur le lien ci-dessous pour définir un nouveau mot de passe : • Réinitialiser mon mot de passe • ⚠️ Important : Ce lien expire dans 1 heure pour votre sécurité. • 🛡️ Conseils de sécurité • Choisissez un mot de passe fort avec au moins 8 caractères • Utilisez une combinaison de lettres, chiffres et symboles • Évitez d'utiliser des informations personnelles facilement devinables • Si vous n'avez pas demandé cette réinitialisation, vous pouvez ignorer cet email en toute sécurité. Votre mot de passe actuel restera inchangé. • Pour votre sécurité, ne partagez jamais ce lien avec d'autres personnes. 📄 email/account/verification.html.twig ------------------------------------------------------------ • Bienvenue chez Antiquités en France ! • Vérifier mon email • ⏰ Important : Ce lien expire dans 24 heures. • Si vous n'avez pas créé ce compte, vous pouvez ignorer cet email en toute sécurité. • 🏺 Vos prochaines étapes • ✓ Complétez votre profil d'antiquaire • ✓ Ajoutez vos premiers objets • ✓ Personnalisez votre galerie 📄 email/admin/infrastructure_alert.html.twig ------------------------------------------------------------ • body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; background-color: #f4f4f4; } .container { max-width: 600px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .header { background: #dc3545; color: white; padding: 20px; margin: -30px -30px 30px -30px; border-radius: 8px 8px 0 0; text-align: center; } .alert-icon { font-size: 48px; margin-bottom: 10px; } .service-name { font-size: 24px; font-weight: bold; margin: 0; } .timestamp { font-size: 14px; opacity: 0.9; margin: 5px 0 0 0; } .error-section { background: #f8f9fa; border-left: 4px solid #dc3545; padding: 15px; margin: 20px 0; border-radius: 0 4px 4px 0; } .error-title { font-weight: bold; color: #dc3545; margin: 0 0 10px 0; } .error-message { font-family: monospace; background: #fff; padding: 10px; border: 1px solid #dee2e6; border-radius: 4px; word-break: break-all; } .context-section { margin: 20px 0; } .context-title { font-weight: bold; margin: 0 0 10px 0; color: #495057; } .context-item { background: #f8f9fa; padding: 8px 12px; margin: 5px 0; border-radius: 4px; border-left: 3px solid #6c757d; } .action-section { background: #e7f3ff; border: 1px solid #b8daff; padding: 20px; margin: 30px 0; border-radius: 6px; } .action-title { color: #004085; font-weight: bold; margin: 0 0 15px 0; } .action-list { margin: 0; padding-left: 20px; } .action-list li { margin: 8px 0; color: #004085; } .button { display: inline-block; background: #007bff; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; margin: 15px 0; font-weight: bold; } .footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #dee2e6; font-size: 12px; color: #6c757d; text-align: center; } .environment-badge { display: inline-block; padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: bold; text-transform: uppercase; } .env-prod { background: #dc3545; color: white; } .env-dev { background: #ffc107; color: black; } .env-test { background: #28a745; color: white; } • ⚠️ • 🚨 Erreur détectée • 📋 Informations contextuelles • 🔧 Actions recommandées • Vérifier que le service Elasticsearch est démarré • Contrôler les logs : • Vérifier l'espace disque disponible • Redémarrer le service si nécessaire : • Les inscriptions continuent de fonctionner, mais la recherche est désactivée • Contrôler la disponibilité du service • Redémarrer le service si nécessaire • 🔗 Accéder au tableau de bord admin • Antiquités en France - Système de surveillance • Cette alerte a été générée automatiquement par le système de surveillance. • En cas de problème persistant, contactez l'équipe technique. 📄 email/base.html.twig ------------------------------------------------------------ • /* Reset CSS pour emails */ body, table, td, p, a, li, blockquote { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } img { -ms-interpolation-mode: bicubic; } /* Styles de base */ body { margin: 0; padding: 0; width: 100% !important; min-width: 100%; height: 100%; background-color: #f8fafc; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333333; } .email-container { max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .email-header { background: linear-gradient(135deg, #0088cc 0%, #0055cc 100%); padding: 30px 40px; text-align: center; position: relative; } .email-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml, • ') repeat; opacity: 0.3; } .email-header h1 { color: #ffffff; margin: 0; font-size: 28px; font-weight: 700; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); position: relative; z-index: 1; } .email-header .subtitle { color: #f4f4f4; margin: 5px 0 0 0; font-size: 14px; font-style: italic; position: relative; z-index: 1; } .email-body { padding: 40px; } .email-content h2 { color: #0088cc; font-size: 24px; margin: 0 0 20px 0; border-bottom: 2px solid #d4af37; padding-bottom: 10px; } .email-content h3 { color: #0055cc; font-size: 18px; margin: 25px 0 15px 0; } .email-content p { margin: 0 0 15px 0; font-size: 16px; line-height: 1.6; } .btn { display: inline-block; padding: 15px 30px; margin: 20px 0; background-color: #d4af37; color: #ffffff !important; text-decoration: none; border-radius: 5px; font-weight: 600; font-size: 16px; text-align: center; transition: background-color 0.3s ease; } .btn:hover { background-color: #cc8822; } .btn-primary { background-color: #0088cc; } .btn-primary:hover { background-color: #0055cc; } .btn-success { background-color: #10b981; } .btn-success:hover { background-color: #059669; } .btn-warning { background-color: #f39c12; } .btn-warning:hover { background-color: #e67e22; } .btn-danger { background-color: #e74c3c; } .btn-danger:hover { background-color: #c0392b; } .alert { padding: 15px; margin: 20px 0; border-radius: 5px; font-weight: 500; } .alert-info { background-color: #eff4f9; border: 1px solid #cadbeb; color: #0055cc; } .alert-warning { background-color: #fff3cd; border: 1px solid #ffeaa7; color: #856404; } .alert-danger { background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; } .alert-success { background-color: #d1f7d1; border: 1px solid #badbcc; color: #155724; } .highlight-box { background-color: #f8f9fa; border-left: 4px solid #d4af37; padding: 20px; margin: 20px 0; border-radius: 0 5px 5px 0; } .item-card { border: 1px solid #e9ecef; border-radius: 8px; padding: 20px; margin: 15px 0; background-color: #f8f9fa; } .item-card h4 { color: #0088cc; margin: 0 0 10px 0; font-size: 18px; } .item-card .price { color: #d4af37; font-weight: 700; font-size: 20px; } .footer { background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); padding: 30px 40px; text-align: center; border-top: 3px solid #d4af37; position: relative; } .footer::before { content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 100px; height: 3px; background: linear-gradient(90deg, #0088cc 0%, #d4af37 50%, #0055cc 100%); } .footer .company-name { font-size: 18px; font-weight: 700; color: #0088cc; margin: 0 0 10px 0; } .footer .description { color: #6c757d; font-size: 14px; margin: 0 0 20px 0; font-style: italic; } .footer .social-links { margin: 20px 0; } .footer .social-links a { display: inline-block; margin: 0 15px; color: #0088cc; text-decoration: none; font-size: 14px; font-weight: 500; transition: color 0.3s ease; } .footer .social-links a:hover { color: #d4af37; } .footer .contact-info { margin: 20px 0; padding: 15px; background: rgba(0, 136, 204, 0.05); border-radius: 8px; border: 1px solid rgba(0, 136, 204, 0.1); } .footer .contact-info p { margin: 5px 0; font-size: 13px; color: #6c757d; } .footer .contact-info a { color: #0088cc; text-decoration: none; } .footer .contact-info a:hover { color: #d4af37; } .unsubscribe { font-size: 12px; color: #6c757d; margin-top: 20px; padding-top: 15px; border-top: 1px solid #e9ecef; } .unsubscribe a { color: #6c757d; text-decoration: underline; } .unsubscribe a:hover { color: #0088cc; } /* Responsive */ @media screen and (max-width: 600px) { .email-container { width: 100% !important; margin: 0 !important; border-radius: 0 !important; } .email-header, .email-body, .footer { padding: 20px !important; } .email-header h1 { font-size: 24px !important; } .btn { display: block !important; width: 100% !important; box-sizing: border-box !important; } .footer .social-links a { display: block !important; margin: 5px 0 !important; } } • 📧 Email : • 🌐 Site web : • 📍 Adresse : • France - Plateforme nationale d'antiquaires 📄 fair/by_country.html.twig ------------------------------------------------------------ • Accueil • Salons & Foires • Voir détails 📄 fair/by_organizer.html.twig ------------------------------------------------------------ • Accueil • Salons & Foires • Voir détails • Aucune foire trouvée pour cet organisateur. 📄 fair/current.html.twig ------------------------------------------------------------ • Accueil • Salons & Foires • En cours • Foires en Cours • Les événements actuellement ouverts au public • Voir détails • Aucune foire en cours actuellement. 📄 fair/index.html.twig ------------------------------------------------------------ • .fair-card { border: 1px solid #ddd; border-radius: 8px; transition: all 0.3s ease; height: 100%; } .fair-card:hover { transform: translateY(-5px); box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .fair-image { height: 200px; object-fit: cover; border-radius: 8px 8px 0 0; } .fair-status { position: absolute; top: 10px; right: 10px; padding: 4px 8px; border-radius: 12px; font-size: 0.8rem; font-weight: bold; } .status-upcoming { background: #e3f2fd; color: #1976d2; } .status-current { background: #e8f5e8; color: #2e7d32; } .status-featured { background: #fff3e0; color: #f57c00; } .search-filters { background: #f8f9fa; border-radius: 8px; padding: 20px; margin-bottom: 30px; } .featured-section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 12px; padding: 30px; margin-bottom: 40px; } • Accueil • Salons & Foires • Salons et Foires d'Antiquités • Découvrez les événements incontournables du monde de l'antiquité • Voir détails • Aucune foire disponible pour le moment. 📄 fair/show.html.twig ------------------------------------------------------------ • Accueil • Salons & Foires • En vedette • Dates • À venir • En cours • Terminé • Lieu • Organisateur • Tarif d'entrée • Horaires • Informations spéciales • Site web officiel • Localisation • Statistiques • Vues • Foires similaires • Partager • Facebook • Twitter • Copier le lien • ${mapData.title} • ${mapData.address} • { infoWindow.open(map, marker); }); } • { alert('Lien copié dans le presse-papiers !'); }); } 📄 fair/upcoming.html.twig ------------------------------------------------------------ • Accueil • Salons & Foires • À venir • Foires à Venir • Découvrez les prochains événements d'antiquités • Voir détails • Aucune foire à venir pour le moment. 📄 gdpr/consent.html.twig ------------------------------------------------------------ • { sw.addEventListener('change', updateButtons); }); // État initial updateButtons(); }); 📄 gdpr/dashboard.html.twig ------------------------------------------------------------ • // Script pour l'export des données document.addEventListener('DOMContentLoaded', function() { const exportForm = document.querySelector('form[action*="export"]'); if (exportForm) { exportForm.addEventListener('submit', function(e) { const btn = this.querySelector('button'); btn.disabled = true; btn.innerHTML = ' 📄 home/index.html.twig ------------------------------------------------------------ • Découvrez l'Art • Français • d'Exception • Plongez dans l'univers fascinant des antiquités françaises. Notre marketplace exclusive vous connecte aux plus prestigieuses galeries d'antiquaires de France. • Explorer le Catalogue • Nos Antiquaires • Antiquaires • 0 ? totalItems : 12500 }} • Objets d'Art • 0 ? categoryStats|length : 25 }} • Catégories • Dernières Découvertes • Explorez les derniers trésors ajoutés par nos antiquaires partenaires • Découvrir • Voir Tout le Catalogue • Explorez nos Catégories • Découvrez notre sélection organisée par spécialités d'antiquités françaises • AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 100 }); 📄 member/_gallery_items.html.twig ------------------------------------------------------------ • RÉSERVÉ • Prix sur demande 📄 member/index.html.twig ------------------------------------------------------------ • Nos Membres • Voir le profil • Profil en cours de configuration 📄 member/show.html.twig ------------------------------------------------------------ • Localiser • Téléphone • Contact • Site web • Accueil • Antiquaires • À propos • Chargement... • 992px) */ /* Défini ci-dessus avec grid-template-columns: repeat(4, 1fr) */ /* Tablettes (577px à 992px) : boutons sous la carte */ @media (min-width: 577px) and (max-width: 992px) { /* Forcer les colonnes à s'empiler sur tablette */ .row.align-items-end { flex-direction: column !important; align-items: center !important; min-height: auto !important; } .col-lg-6:first-child { order: 1 !important; margin-bottom: 20px !important; width: 100% !important; flex: none !important; } .col-lg-6:last-child { order: 2 !important; width: 100% !important; flex: none !important; } /* Header compact pour tablette */ .member-hero-banner { min-height: 100px !important; padding: 10px 0 !important; } .member-hero-content { padding: 15px 0 !important; min-height: 160px !important; } .member-brand-card { text-align: center !important; margin-bottom: 0 !important; padding: 15px !important; } .member-contact-actions { padding: 10px !important; margin: 0 !important; margin-bottom: 20px !important; } /* Boutons tablettes - ligne centrée */ .contact-buttons-grid { display: flex !important; flex-direction: row !important; justify-content: center !important; gap: 15px !important; padding: 0 !important; } .contact-action-btn { width: 100px !important; height: 80px !important; flex-shrink: 0 !important; } .contact-action-btn .btn-icon i { font-size: 24px !important; } .contact-action-btn .btn-label { font-size: 13px !important; } /* Container avec espacement correct */ .container.py-5 { padding-top: 30px !important; padding-bottom: 25px !important; } } /* Mobile : espacement ultra-minimal sur smartphone */ @media (max-width: 576px) { /* Header ultra-compact sur smartphone */ .member-hero-banner { min-height: 40px !important; padding: 0 !important; } .member-hero-content { padding: 5px 0 !important; min-height: 60px !important; } .row.align-items-end { min-height: 55px !important; margin-bottom: 5px !important; } /* Carte de visite ultra-compacte */ .member-brand-card { margin-bottom: 8px !important; padding: 4px !important; border-radius: 8px !important; } .member-brand-card h1 { font-size: 16px !important; margin-bottom: 2px !important; line-height: 1.1 !important; } .member-brand-card .text-muted { font-size: 11px !important; margin-bottom: 1px !important; line-height: 1.1 !important; } .member-brand-card .badge { font-size: 8px !important; padding: 1px 4px !important; margin: 1px !important; } /* Actions de contact ultra-compactes */ .member-contact-actions { padding: 3px !important; margin: 0 !important; margin-bottom: 15px !important; } .contact-buttons-grid { gap: 3px; padding: 2px; margin: 0; } /* Boutons micro sur smartphone */ .contact-action-btn { width: 65px; height: 50px; padding: 1px; border-radius: 6px; border-width: 1px; } .contact-action-btn .btn-icon { margin-bottom: 1px; } .contact-action-btn .btn-icon i { font-size: 14px; } .contact-action-btn .btn-label { font-size: 8px; line-height: 1; } /* Réduire drastiquement tous les espacements généraux */ .container-fluid { padding-left: 2px !important; padding-right: 2px !important; } .col-12, .col-md-8, .col-md-4 { padding-left: 1px !important; padding-right: 1px !important; } /* Compacter la section galerie */ .member-gallery-section { margin-top: 10px !important; padding-top: 5px !important; } .member-gallery-section h2 { font-size: 18px !important; margin-bottom: 10px !important; } /* S'assurer que le container principal a un espacement correct */ .container.py-5 { padding-top: 20px !important; padding-bottom: 15px !important; } /* Breadcrumb avec marge inférieure pour respirer */ nav.mb-4 { margin-bottom: 20px !important; } } • document.addEventListener('DOMContentLoaded', function() { console.log('✅ Page membre chargée - JavaScript minimal'); }); • Adresse • Carte • Street View • Ouvrir dans Google Maps • Fermer • Cliquez pour appeler directement • Appeler maintenant • Votre nom * • Votre email * • Sujet • Votre message * • J'accepte que mes données soient utilisées pour répondre à ma demande * • Annuler • Envoyer le message • Voir la localisation • Afficher le numéro • Envoyer un message • Visiter le site web • Close • Carte de localisation • Vue Street View • Demande d'information sur vos antiquités • Bonjour, je souhaiterais obtenir des informations sur... 📄 member/test_services.html.twig ------------------------------------------------------------ • 🧪 Test des Services Métier • Phase 2 Terminée ! • Test des nouvelles entités et services créés. • 📍 Localisation • Pays : • Région : • Département : • Ville : • 🎯 Spécialités • Aucune spécialité définie • 📊 Statistiques • Objets total • Disponibles • Limites d'abonnement • État de l'abonnement • Description • 🌐 Visiter le site • ← Retour à l'accueil • Test des entités 📄 search/admin.html.twig ------------------------------------------------------------ • let currentView = 'list'; let currentResults = []; let currentPage = 1; // Soumission du formulaire de recherche document.getElementById('advancedSearchForm').addEventListener('submit', function(e) { e.preventDefault(); performSearch(); }); function performSearch(page = 1) { const formData = new FormData(document.getElementById('advancedSearchForm')); const params = new URLSearchParams(); // Convertir FormData en URLSearchParams for (let [key, value] of formData.entries()) { if (value) params.append(key, value); } params.append('page', page); // Afficher un loader document.getElementById('searchResults').innerHTML = ` • { document.getElementById('searchResults').innerHTML = ` • `; }); } function displayResults(data) { const resultsContainer = document.getElementById('searchResults'); const countBadge = document.getElementById('resultsCount'); countBadge.textContent = data.total; if (data.results.length === 0) { resultsContainer.innerHTML = ` • `; return; } let html = ''; if (currentView === 'list') { html = ' • ${result.score.toFixed(2)} • '; } resultsContainer.innerHTML = html; // Afficher la pagination displayPagination(data); } function displayPagination(data) { const paginationContainer = document.getElementById('searchPagination'); if (data.totalPages • `; } // Pages for (let i = Math.max(1, currentPage - 2); i • `; } // Page suivante if (currentPage • 0) { displayResults({ results: currentResults, total: currentResults.length }); } } function clearForm() { document.getElementById('advancedSearchForm').reset(); document.getElementById('searchResults').innerHTML = ` 📄 search/error.html.twig ------------------------------------------------------------ • Erreur de recherche • Retour à l'accueil • Nouvelle recherche 📄 search/items.html.twig ------------------------------------------------------------ • Prix sur devis • Ajouter au panier • Demander un devis • Voir détails • Vendu • Réservé • .search-filters { background: #f8f9fa; padding: 1.5rem; border-radius: 8px; height: fit-content; position: sticky; top: 20px; } .filter-section { margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid #dee2e6; } .filter-section:last-child { border-bottom: none; margin-bottom: 0; } .item-card { transition: all 0.3s ease; border: 1px solid #dee2e6; } .item-card:hover { transform: translateY(-4px); box-shadow: 0 8px 25px rgba(0,0,0,0.15); } .search-suggestions { position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid #dee2e6; border-radius: 0 0 6px 6px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); z-index: 1000; max-height: 300px; overflow-y: auto; display: none; } .search-suggestion-item { padding: 12px 16px; border-bottom: 1px solid #f8f9fa; cursor: pointer; transition: background-color 0.2s; } .search-suggestion-item:hover { background-color: #f8f9fa; } .search-form { position: relative; } .highlight { background-color: #fff3cd; padding: 1px 3px; border-radius: 3px; } /* Vue liste */ .items-list .item-col { flex: 0 0 100%; max-width: 100%; } .items-list .item-card { flex-direction: row; } .items-list .card-img-top { width: 200px; height: 150px; object-fit: cover; border-radius: 6px 0 0 6px; } @media (max-width: 768px) { .search-filters { position: static; margin-bottom: 2rem; } .search-controls { flex-direction: column; align-items: stretch !important; gap: 1rem; } .items-list .item-card { flex-direction: column; } .items-list .card-img-top { width: 100%; height: 200px; border-radius: 6px 6px 0 0; } } • document.addEventListener('DOMContentLoaded', function() { // Initialize Cart Manager const cartManager = new CartManager(); // Gestion vue grille/liste const viewGrid = document.getElementById('viewGrid'); const viewList = document.getElementById('viewList'); const itemsContainer = document.getElementById('itemsContainer'); if (viewGrid && viewList && itemsContainer) { viewGrid.addEventListener('change', function() { if (this.checked) { itemsContainer.className = 'items-grid'; } }); viewList.addEventListener('change', function() { if (this.checked) { itemsContainer.className = 'items-list'; } }); } // Autocomplétion const searchInput = document.getElementById('searchInput'); const suggestionsContainer = document.getElementById('searchSuggestions'); let searchTimeout; if (searchInput && suggestionsContainer) { searchInput.addEventListener('input', function() { const query = this.value.trim(); clearTimeout(searchTimeout); if (query.length • { const filtersSection = document.getElementById('filters'); if (filtersSection) { filtersSection.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); } }, 100); // Petit délai pour laisser la page se charger } }); • Pagination des résultats 📄 search/members.html.twig ------------------------------------------------------------ • .search-filters { background: #f8f9fa; padding: 1.5rem; border-radius: 8px; height: fit-content; position: sticky; top: 20px; } .filter-section { margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid #dee2e6; } .filter-section:last-child { border-bottom: none; margin-bottom: 0; } .member-card { transition: all 0.3s ease; border: 1px solid #dee2e6; } .member-card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.15); } .search-suggestions { position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid #dee2e6; border-radius: 0 0 6px 6px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); z-index: 1000; max-height: 300px; overflow-y: auto; display: none; } .search-suggestion-item { padding: 12px 16px; border-bottom: 1px solid #f8f9fa; cursor: pointer; transition: background-color 0.2s; } .search-suggestion-item:hover { background-color: #f8f9fa; } .search-form { position: relative; } .highlight { background-color: #fff3cd; padding: 1px 3px; border-radius: 3px; } /* Vue liste */ .members-list .member-col { flex: 0 0 100%; max-width: 100%; } .members-list .member-card .card-body { padding: 1rem; } .members-list .member-avatar { width: 50px; height: 50px; } @media (max-width: 768px) { .search-filters { position: static; margin-bottom: 2rem; } .search-controls { flex-direction: column; align-items: stretch !important; gap: 1rem; } .member-card .card-body { padding: 1rem; } .member-avatar { width: 50px !important; height: 50px !important; } .member-contact p { font-size: 0.875rem !important; } } • document.addEventListener('DOMContentLoaded', function() { // Gestion vue grille/liste const viewGrid = document.getElementById('viewGrid'); const viewList = document.getElementById('viewList'); const membersContainer = document.getElementById('membersContainer'); if (viewGrid && viewList && membersContainer) { viewGrid.addEventListener('change', function() { if (this.checked) { membersContainer.className = 'members-grid'; } }); viewList.addEventListener('change', function() { if (this.checked) { membersContainer.className = 'members-list'; } }); } // Autocomplétion const searchInput = document.getElementById('searchInput'); const suggestionsContainer = document.getElementById('searchSuggestions'); let searchTimeout; if (searchInput && suggestionsContainer) { searchInput.addEventListener('input', function() { const query = this.value.trim(); clearTimeout(searchTimeout); if (query.length • Antiquaire - ${suggestion.city} • { filterForm.submit(); }, 100); }); }); } }); • Pagination des résultats 📄 search/results.html.twig ------------------------------------------------------------ • Globale • Rechercher • Filtres de recherche • Type de résultats • Objets • Antiquaires • Catégories • Régions • Prix • Appliquer • Effacer • Voir l'objet • Voir le profil • Profil en préparation • Aucun résultat trouvé • Essayez de modifier vos critères de recherche ou utilisez des mots-clés différents. • { radio.addEventListener('change', function() { // Soumettre automatiquement le formulaire lors du changement de type // ou actualiser l'affichage des filtres }); }); • Rechercher des antiquités, antiquaires... • Min € • Max € • Navigation des résultats 📄 security/change_password.html.twig ------------------------------------------------------------ • = 12) score += 25; if (/[a-z]/.test(password)) score += 10; if (/[A-Z]/.test(password)) score += 10; if (/[0-9]/.test(password)) score += 15; if (/[^A-Za-z0-9]/.test(password)) score += 15; if (score 📄 security/forgot_password.html.twig ------------------------------------------------------------ • /* Reset pour s'assurer que le fond touche le haut */ body.auth-page { margin: 0 !important; padding: 0 !important; background: white !important; } /* Modern Auth Page Styles */ .auth-page-wrapper { position: relative; min-height: 100vh; margin: 0; padding: 0; background: white; overflow: hidden; } .auth-card { background: white; border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), 0 0 0 3px rgba(59, 130, 246, 0.2), 0 0 20px rgba(59, 130, 246, 0.1); border: 2px solid #3b82f6; padding: 2.5rem; max-width: 600px; margin: 0 auto; position: relative; overflow: hidden; } .auth-card::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); animation: shine 3s ease-in-out infinite; } @keyframes shine { 0% { left: -100%; } 50% { left: 100%; } 100% { left: 100%; } } .auth-form-section { /* Plus de bordure ni padding puisqu'il n'y a plus de header */ } .form-header { text-align: center; margin-bottom: 1.5rem; } .form-title { font-size: 1.5rem; font-weight: 600; color: #2d3748; margin-bottom: 0.5rem; } .form-subtitle { color: #718096; font-size: 0.9rem; } /* Modern Form Styles */ .form-group { margin-bottom: 1.25rem; } .form-label { display: flex; align-items: center; font-weight: 500; color: #4a5568; margin-bottom: 0.5rem; font-size: 0.9rem; } .form-label i { margin-right: 0.5rem; color: #3b82f6; } .form-input { width: 100%; padding: 0.875rem 1rem; border: 2px solid #e2e8f0; border-radius: 12px; font-size: 1rem; transition: all 0.3s ease; background: #f7fafc; } .form-input:focus { outline: none; border-color: #3b82f6; background: white; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 0 20px rgba(59, 130, 246, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.7); transform: translateY(-1px); } /* Submit Button */ .auth-submit-btn { width: 100%; padding: 1rem; background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%); color: white; border: none; border-radius: 12px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 0.5rem; position: relative; overflow: hidden; box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.2); margin-bottom: 1.5rem; } .auth-submit-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.5s ease; } .auth-submit-btn:hover::before { left: 100%; } .auth-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3); } /* Alert Styles */ .auth-alert { padding: 1rem; border-radius: 12px; margin-bottom: 1.5rem; display: flex; align-items: flex-start; gap: 0.75rem; } .auth-alert-danger { background: rgba(239, 68, 68, 0.1); color: #dc2626; border: 1px solid rgba(239, 68, 68, 0.2); } .auth-alert-success { background: rgba(34, 197, 94, 0.1); color: #16a34a; border: 1px solid rgba(34, 197, 94, 0.2); } .auth-alert-info { background: rgba(59, 130, 246, 0.1); color: #2563eb; border: 1px solid rgba(59, 130, 246, 0.2); } .auth-alert strong { display: block; font-weight: 600; margin-bottom: 0.25rem; } .auth-alert p { margin: 0; font-size: 0.9rem; } /* Links Section */ .auth-links { margin: 1.5rem 0; } .link-group { text-align: center; margin: 1rem 0; } .auth-link { display: inline-flex; align-items: center; gap: 0.5rem; color: #3b82f6; text-decoration: none; font-weight: 500; transition: all 0.3s ease; } .auth-link:hover { color: #1e40af; transform: translateY(-1px); } .auth-link-primary { background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%); color: white !important; padding: 0.75rem 1.5rem; border-radius: 8px; margin-top: 0.5rem; position: relative; overflow: hidden; box-shadow: 0 3px 10px rgba(59, 130, 246, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.2); } .auth-link-primary::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.4s ease; } .auth-link-primary:hover::before { left: 100%; } .auth-link-primary:hover { color: white !important; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(59, 130, 246, 0.3); } .link-text { color: #718096; margin-bottom: 0.5rem; font-size: 0.9rem; } .auth-divider { text-align: center; margin: 1.5rem 0; position: relative; } .auth-divider::before { content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: #e2e8f0; } .auth-divider span { background: white; padding: 0 1rem; color: #718096; font-size: 0.8rem; position: relative; } /* Responsive */ @media (max-width: 768px) { .auth-card { padding: 2rem 1.5rem; margin: 1rem; border-radius: 16px; max-width: 90%; } .form-header { margin-bottom: 1.5rem; } .form-group { margin-bottom: 1.25rem; } .auth-links { margin: 1.5rem 0; } } 📄 security/login.html.twig ------------------------------------------------------------ • Erreur de connexion • Succès • Erreur • Accès Administration Requis • Pour accéder à l'administration, vous devez disposer d'un compte avec le rôle • Connexion Administrateur • Vous tentez d'accéder à l'interface d'administration. Veuillez vous connecter avec un compte administrateur. • Si vous n'avez pas de compte administrateur, contactez un administrateur système. • Protégé par reCAPTCHA - • Confidentialité • Conditions • /* Reset pour s'assurer que le fond touche le haut */ body.auth-page { margin: 0 !important; padding: 0 !important; background: white !important; } /* Modern Auth Page Styles */ .auth-page-wrapper { position: relative; min-height: 100vh; margin: 0; padding: 0; background: white; overflow: hidden; } .auth-card { background: white; border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), 0 0 0 3px rgba(59, 130, 246, 0.2), 0 0 20px rgba(59, 130, 246, 0.1); border: 2px solid #3b82f6; padding: 2.5rem; max-width: 600px; margin: 0 auto; position: relative; overflow: hidden; } .auth-card::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); animation: shine 3s ease-in-out infinite; } @keyframes shine { 0% { left: -100%; } 50% { left: 100%; } 100% { left: 100%; } } /* Styles header supprimés car plus utilisés */ .auth-form-section { /* Plus de bordure ni padding puisqu'il n'y a plus de header */ } .form-header { text-align: center; margin-bottom: 1.5rem; } .form-title { font-size: 1.5rem; font-weight: 600; color: #2d3748; margin-bottom: 0.5rem; } .form-subtitle { color: #718096; font-size: 0.9rem; } /* Modern Form Styles */ .form-group { margin-bottom: 1.25rem; } .form-label { display: flex; align-items: center; font-weight: 500; color: #4a5568; margin-bottom: 0.5rem; font-size: 0.9rem; } .form-label i { margin-right: 0.5rem; color: #3b82f6; } .form-input { width: 100%; padding: 0.875rem 1rem; border: 2px solid #e2e8f0; border-radius: 12px; font-size: 1rem; transition: all 0.3s ease; background: #f7fafc; } .form-input:focus { outline: none; border-color: #3b82f6; background: white; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 0 20px rgba(59, 130, 246, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.7); transform: translateY(-1px); } /* Custom Checkbox */ .form-check-group { margin: 1.5rem 0; } .checkbox-label { display: flex; align-items: center; cursor: pointer; font-size: 0.9rem; color: #4a5568; } .checkbox-input { position: absolute; opacity: 0; } .checkbox-mark { width: 20px; height: 20px; border: 2px solid #e2e8f0; border-radius: 4px; margin-right: 0.75rem; position: relative; transition: all 0.3s ease; } .checkbox-input:checked + .checkbox-mark { background: #3b82f6; border-color: #3b82f6; } .checkbox-input:checked + .checkbox-mark::after { content: '✓'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold; } /* Submit Button */ .auth-submit-btn { width: 100%; padding: 1rem; background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%); color: white; border: none; border-radius: 12px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 0.5rem; position: relative; overflow: hidden; box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.2); } .auth-submit-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.5s ease; } .auth-submit-btn:hover::before { left: 100%; } .auth-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3); } /* Alert Styles */ .auth-alert { padding: 1rem; border-radius: 12px; margin-bottom: 1.5rem; display: flex; align-items: flex-start; gap: 0.75rem; } .auth-alert-danger { background: rgba(239, 68, 68, 0.1); color: #dc2626; border: 1px solid rgba(239, 68, 68, 0.2); } .auth-alert-success { background: rgba(34, 197, 94, 0.1); color: #16a34a; border: 1px solid rgba(34, 197, 94, 0.2); } .auth-alert-admin-warning { background: rgba(251, 146, 60, 0.1); color: #ea580c; border: 1px solid rgba(251, 146, 60, 0.2); box-shadow: 0 4px 15px rgba(251, 146, 60, 0.1); } .auth-alert-info { background: rgba(59, 130, 246, 0.1); color: #1d4ed8; border: 1px solid rgba(59, 130, 246, 0.2); box-shadow: 0 4px 15px rgba(59, 130, 246, 0.1); } .admin-login-help { margin-top: 0.75rem; padding: 0.5rem; background: rgba(255, 255, 255, 0.5); border-radius: 8px; border-left: 3px solid currentColor; } .auth-alert strong { display: block; font-weight: 600; margin-bottom: 0.25rem; } .auth-alert p { margin: 0; font-size: 0.9rem; } /* Links Section */ .auth-links { margin: 1.5rem 0; } .link-group { text-align: center; margin: 1rem 0; } .auth-link { display: inline-flex; align-items: center; gap: 0.5rem; color: #3b82f6; text-decoration: none; font-weight: 500; transition: all 0.3s ease; } .auth-link:hover { color: #1e40af; transform: translateY(-1px); } .auth-link-primary { background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%); color: white !important; padding: 0.75rem 1.5rem; border-radius: 8px; margin-top: 0.5rem; position: relative; overflow: hidden; box-shadow: 0 3px 10px rgba(59, 130, 246, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.2); } .auth-link-primary::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.4s ease; } .auth-link-primary:hover::before { left: 100%; } .auth-link-primary:hover { color: white !important; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(59, 130, 246, 0.3); } .link-text { color: #718096; margin-bottom: 0.5rem; font-size: 0.9rem; } .auth-divider { text-align: center; margin: 1.5rem 0; position: relative; } .auth-divider::before { content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: #e2e8f0; } .auth-divider span { background: white; padding: 0 1rem; color: #718096; font-size: 0.8rem; position: relative; } /* reCAPTCHA info */ .recaptcha-info { text-align: center; margin-top: 1rem; font-size: 0.8rem; color: #718096; } .recaptcha-info a { color: #3b82f6; text-decoration: none; } /* Responsive */ @media (max-width: 768px) { .auth-card { padding: 2rem 1.5rem; margin: 1rem; border-radius: 16px; max-width: 90%; } .form-header { margin-bottom: 1.5rem; } .form-group { margin-bottom: 1.25rem; } .auth-links { margin: 1.5rem 0; } } 📄 security/register.html.twig ------------------------------------------------------------ • Avantages membre • Catalogue en ligne gratuit • Visibilité nationale • Outils de gestion • Support client dédié • En vous inscrivant, vous acceptez nos • politique de confidentialité • Créer mon compte antiquaire • Protégé par reCAPTCHA - • Confidentialité • Conditions • Déjà membre ? • Se connecter • Retour à l'accueil • Plans d'abonnement • €29/mois • €49/mois • €99/mois • Commencez gratuitement, passez Premium quand vous le souhaitez ! 📄 security/register_choice.html.twig ------------------------------------------------------------ • Rejoignez Notre • Communauté • d'Exception • Découvrez l'univers fascinant des antiquités françaises. Que vous soyez passionné ou professionnel, choisissez l'expérience qui vous correspond. • Antiquaires • Objets d'Art • Catégories • Choisissez Votre Expérience • Deux façons uniques de découvrir et participer à notre marketplace d'antiquités • Professionnel • Connectez-vous à votre espace personnel pour découvrir toutes vos fonctionnalités. • * { position: relative; z-index: 1; } .choice-card:hover { transform: translateY(-10px); box-shadow: 0 20px 60px rgba(0, 136, 204, 0.2); } .choice-card.featured { border: 3px solid var(--aef-beige-primary); transform: scale(1.05); } .choice-card.featured:hover { transform: scale(1.05) translateY(-10px); } .featured-badge { position: absolute; top: -1px; right: 2rem; background: var(--aef-gradient-beige); color: var(--aef-white); padding: 0.5rem 1.5rem; border-radius: 0 0 15px 15px; font-weight: 600; font-size: 0.9rem; display: flex; align-items: center; gap: 0.5rem; } .choice-hero { text-align: center; margin-bottom: 2rem; } .choice-icon { width: 80px; height: 80px; border-radius: 50%; background: var(--aef-gradient-blue); display: flex; align-items: center; justify-content: center; margin: 0 auto 1.5rem; font-size: 2rem; color: var(--aef-white); box-shadow: 0 8px 25px rgba(0, 136, 204, 0.3); } .dealer-card .choice-icon { background: var(--aef-gradient-beige); box-shadow: 0 8px 25px rgba(204, 136, 34, 0.3); } .choice-title { font-size: 1.8rem; font-weight: 700; color: var(--aef-text-dark); margin-bottom: 1rem; } .choice-subtitle { color: var(--aef-text-muted); font-size: 1.1rem; line-height: 1.6; } .choice-features { margin-bottom: 2.5rem; } .feature-list { display: flex; flex-direction: column; gap: 1rem; } .feature-item { display: flex; align-items: center; gap: 1rem; padding: 0.75rem; background: var(--aef-grey-light); border-radius: 12px; transition: all 0.3s ease; } .feature-item:hover { background: var(--aef-blue-light); } .feature-item i { font-size: 1.2rem; width: 24px; } .feature-item span { font-weight: 500; color: var(--aef-text-dark); } .choice-footer { text-align: center; } .choice-price { margin-bottom: 1.5rem; } .price-badge { background: var(--aef-blue-light); color: var(--aef-blue-dark); padding: 0.75rem 1.5rem; border-radius: 25px; font-weight: 700; font-size: 1.1rem; } .price-badge.featured { background: var(--aef-gradient-beige); color: var(--aef-white); } .btn-choice-primary { display: inline-flex; align-items: center; justify-content: center; background: var(--aef-gradient-blue); color: var(--aef-white); padding: 1rem 2rem; border-radius: 50px; text-decoration: none; font-weight: 600; font-size: 1.1rem; transition: all 0.3s ease; min-width: 250px; margin-bottom: 1rem; } .btn-choice-primary:hover { color: var(--aef-white); transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 136, 204, 0.4); } .btn-choice-featured { display: inline-flex; align-items: center; justify-content: center; background: var(--aef-gradient-beige); color: var(--aef-white); padding: 1rem 2rem; border-radius: 50px; text-decoration: none; font-weight: 600; font-size: 1.1rem; transition: all 0.3s ease; min-width: 250px; margin-bottom: 1rem; } .btn-choice-featured:hover { color: var(--aef-white); transform: translateY(-2px); box-shadow: 0 8px 25px rgba(204, 136, 34, 0.4); } .choice-note { color: var(--aef-text-muted); font-size: 0.9rem; margin: 0; } .help-section { padding: 3rem 0; background: var(--aef-grey-light); } .help-card { background: var(--aef-white); border-radius: 20px; padding: 2.5rem; box-shadow: 0 10px 40px rgba(0, 136, 204, 0.1); display: flex; align-items: center; gap: 2rem; max-width: 800px; margin: 0 auto; } .help-icon { width: 80px; height: 80px; border-radius: 50%; background: var(--aef-gradient-beige); display: flex; align-items: center; justify-content: center; font-size: 2rem; color: var(--aef-white); flex-shrink: 0; } .help-title { color: var(--aef-text-dark); font-weight: 700; margin-bottom: 1rem; } .help-description { color: var(--aef-text-muted); margin-bottom: 1.5rem; } .btn-help { background: var(--aef-gradient-blue); color: var(--aef-white); padding: 0.75rem 1.5rem; border-radius: 25px; text-decoration: none; font-weight: 600; transition: all 0.3s ease; } .btn-help:hover { color: var(--aef-white); transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 136, 204, 0.3); } .navigation-section { padding: 3rem 0; background: var(--aef-white); } .navigation-card { background: var(--aef-grey-light); border-radius: 20px; padding: 2.5rem; display: flex; justify-content: space-between; align-items: center; max-width: 800px; margin: 0 auto; } .nav-title { color: var(--aef-text-dark); font-weight: 700; margin-bottom: 0.5rem; } .nav-description { color: var(--aef-text-muted); margin-bottom: 1rem; } .btn-nav-primary { background: var(--aef-gradient-blue); color: var(--aef-white); padding: 0.75rem 1.5rem; border-radius: 25px; text-decoration: none; font-weight: 600; transition: all 0.3s ease; } .btn-nav-primary:hover { color: var(--aef-white); transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 136, 204, 0.3); } .btn-back { color: var(--aef-text-muted); text-decoration: none; font-weight: 500; transition: all 0.3s ease; } .btn-back:hover { color: var(--aef-blue-primary); } @media (max-width: 768px) { .choice-grid { grid-template-columns: 1fr; gap: 2rem; margin-top: 2rem; } .choice-card.featured { transform: none; } .choice-card.featured:hover { transform: translateY(-10px); } .help-card { flex-direction: column; text-align: center; padding: 2rem; } .navigation-card { flex-direction: column; text-align: center; gap: 2rem; padding: 2rem; } } • AOS.init({ duration: 800, easing: 'ease-out-cubic', once: true, offset: 50 }); 📄 security/register_user.html.twig ------------------------------------------------------------ • Protégé par reCAPTCHA - • Confidentialité • Conditions 📄 security/reset_password.html.twig ------------------------------------------------------------ • = 12) score += 25; if (/[a-z]/.test(password)) score += 10; if (/[A-Z]/.test(password)) score += 10; if (/[0-9]/.test(password)) score += 15; if (/[^A-Za-z0-9]/.test(password)) score += 15; if (score 📄 subscription/plans.html.twig ------------------------------------------------------------ • .card { transition: all 0.3s ease; } .card:hover { transform: translateY(-5px); box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175); } .border-primary { border-width: 2px !important; } .scale-105 { transform: scale(1.02); } .accordion-button:not(.collapsed) { background-color: #f8f9fa; color: #0d6efd; } .pricing-display { min-height: 80px; display: flex; align-items: center; justify-content: center; flex-direction: column; } .form-check-input:checked { background-color: #198754; border-color: #198754; } .badge.bg-success { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } /* Améliorer l'apparence des cartes de plans */ .card-header h3 { color: #2c3e50; } .display-4 { color: #2c3e50; } .card-footer .btn { font-weight: 600; padding: 12px 20px; } .list-unstyled li { padding: 8px 0; border-bottom: 1px solid #f8f9fa; } .list-unstyled li:last-child { border-bottom: none; } /* Style pour les badges de périodes d'essai */ .position-absolute .badge.bg-success { font-size: 0.75rem; padding: 6px 10px; } .position-absolute .badge.bg-primary { font-size: 0.8rem; padding: 8px 12px; } 📄 subscription/success.html.twig ------------------------------------------------------------ • // Afficher une notification de succès document.addEventListener('DOMContentLoaded', function() { // Créer une notification toast personnalisée const toastHTML = ` • `; // Ajouter le toast au DOM document.body.insertAdjacentHTML('beforeend', toastHTML); // Afficher le toast const toast = new bootstrap.Toast(document.querySelector('.toast')); toast.show(); // Supprimer le toast du DOM après qu'il soit caché document.querySelector('.toast').addEventListener('hidden.bs.toast', function() { this.remove(); }); }); 📄 user_dashboard/alerts.html.twig ------------------------------------------------------------ • Annuler • Créer l'alerte 📄 user_dashboard/favorites.html.twig ------------------------------------------------------------ • Conseil d'expert • Créez des alertes pour les objets que vous aimez ! Vous serez notifié dès qu'un objet similaire est ajouté au catalogue. • Créer une alerte Total: 100 templates nécessitent une traduction Total: 156 templates analysés