templates/base.html.twig line 1

  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     {% block meta %}
  7.     <meta name="author" content="DAIP"/>
  8.     <meta property="fb:app_id" content="1604133883317306" />
  9.     {% endblock %}
  10.     <title>{% block title %}DAIP - Direction de l'Apprentissage et de l'Insertion Professionnelle{% endblock %}</title>
  11.     
  12.     <!-- Tailwind CSS -->
  13.     <script src="https://cdn.tailwindcss.com"></script>
  14.     
  15.     <!-- Configuration du thème -->
  16.     <script>
  17.         tailwind.config = {
  18.             theme: {
  19.                 extend: {
  20.                     colors: {
  21.                         primary: {
  22.                             50: '#eef2ff',
  23.                             100: '#e0e7ff',
  24.                             200: '#c7d2fe',
  25.                             300: '#a5b4fc',
  26.                             400: '#818cf8',
  27.                             500: '#6366f1',
  28.                             600: '#4f46e5',
  29.                             700: '#4338ca',
  30.                             800: '#3730a3',
  31.                             900: '#312e81',
  32.                         },
  33.                         secondary: {
  34.                             50: '#f5f3ff',
  35.                             100: '#ede9fe',
  36.                             200: '#ddd6fe',
  37.                             300: '#c4b5fd',
  38.                             400: '#a78bfa',
  39.                             500: '#8b5cf6',
  40.                             600: '#7c3aed',
  41.                             700: '#6d28d9',
  42.                             800: '#5b21b6',
  43.                             900: '#4c1d95',
  44.                         }
  45.                     },
  46.                     animation: {
  47.                         'scroll': 'scroll 30s linear infinite',
  48.                         'scroll-reverse': 'scroll 30s linear infinite reverse',
  49.                         'fade-in': 'fadeIn 0.5s ease-in-out',
  50.                         'slide-up': 'slideUp 0.6s ease-out',
  51.                     },
  52.                     keyframes: {
  53.                         scroll: {
  54.                             '0%': { transform: 'translateX(0)' },
  55.                             '100%': { transform: 'translateX(-50%)' }
  56.                         },
  57.                         fadeIn: {
  58.                             '0%': { opacity: '0' },
  59.                             '100%': { opacity: '1' }
  60.                         },
  61.                         slideUp: {
  62.                             '0%': { transform: 'translateY(20px)', opacity: '0' },
  63.                             '100%': { transform: 'translateY(0)', opacity: '1' }
  64.                         }
  65.                     }
  66.                 }
  67.             }
  68.         }
  69.     </script>
  70.     
  71.     <!-- Font Awesome -->
  72.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
  73.     
  74.     <!-- Google Fonts -->
  75.     <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
  76.     
  77.     <style>
  78.         body { font-family: 'Plus Jakarta Sans', sans-serif; }
  79.         .gradient-text {
  80.             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  81.             -webkit-background-clip: text;
  82.             -webkit-text-fill-color: transparent;
  83.         }
  84.         .hero-gradient {
  85.             background: radial-gradient(circle at top right, #667eea 0%, #764ba2 100%);
  86.         }
  87.         .card-hover {
  88.             transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  89.         }
  90.         .card-hover:hover {
  91.             transform: translateY(-8px) scale(1.02);
  92.             box-shadow: 0 20px 40px -15px rgba(102, 126, 234, 0.3);
  93.         }
  94.         .glass-effect {
  95.             background: rgba(255, 255, 255, 0.1);
  96.             backdrop-filter: blur(10px);
  97.             border: 1px solid rgba(255, 255, 255, 0.2);
  98.         }
  99.         @keyframes float {
  100.             0%, 100% { transform: translateY(0); }
  101.             50% { transform: translateY(-10px); }
  102.         }
  103.         .float { animation: float 6s ease-in-out infinite; }
  104.         html {
  105.             scroll-behavior: smooth;
  106.         }
  107.     </style>
  108.     
  109.     {% block stylesheets %}{% endblock %}
  110. </head>
  111. <body class="bg-gray-50 overflow-x-hidden">
  112.     {% include 'header.html.twig' %}
  113.     
  114.     <main>
  115.         {% block body %}{% endblock %}
  116.     </main>
  117.     
  118.     {% include 'footer.html.twig' %}
  119.     
  120.     {% block javascripts %}
  121.     <!-- Alpine.js en premier (sans defer pour garantir l'ordre) -->
  122.     <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
  123.     
  124.     <!-- jQuery ensuite -->
  125.     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  126.     
  127.     <!-- Script personnalisé pour forcer la réinitialisation d'Alpine -->
  128.     <script>
  129.         document.addEventListener('DOMContentLoaded', function() {
  130.             console.log('DOM chargé, Alpine.js disponible:', typeof Alpine !== 'undefined');
  131.             
  132.             // Auto-disparition des messages flash
  133.             const flashMessages = document.querySelectorAll('[data-flash-message]');
  134.             flashMessages.forEach(function(message) {
  135.                 const delay = message.dataset.delay || 5000; // 5 secondes par défaut
  136.                 
  137.                 setTimeout(function() {
  138.                     // Ajouter une animation de fondu
  139.                     message.style.transition = 'opacity 0.5s ease-out, transform 0.3s ease-out';
  140.                     message.style.opacity = '0';
  141.                     message.style.transform = 'translateY(-10px)';
  142.                     
  143.                     // Supprimer l'élément après l'animation
  144.                     setTimeout(function() {
  145.                         message.remove();
  146.                     }, 500);
  147.                 }, delay);
  148.                 
  149.                 // Ajouter un bouton de fermeture manuelle
  150.                 const closeButton = document.createElement('button');
  151.                 closeButton.innerHTML = '×';
  152.                 closeButton.className = 'ml-4 text-gray-400 hover:text-gray-600 text-xl font-bold transition-colors';
  153.                 closeButton.style.cursor = 'pointer';
  154.                 closeButton.onclick = function() {
  155.                     message.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out';
  156.                     message.style.opacity = '0';
  157.                     message.style.transform = 'translateY(-10px)';
  158.                     setTimeout(function() {
  159.                         message.remove();
  160.                     }, 300);
  161.                 };
  162.                 
  163.                 // Ajouter le bouton au message
  164.                 const messageContent = message.querySelector('div');
  165.                 if (messageContent) {
  166.                     messageContent.appendChild(closeButton);
  167.                 }
  168.             });
  169.             
  170.             // Forcer la réinitialisation des composants Alpine si nécessaire
  171.             if (typeof Alpine !== 'undefined') {
  172.                 // Attendre un peu pour que tout soit bien chargé
  173.                 setTimeout(function() {
  174.                     // Réinitialiser les composants Alpine (optionnel)
  175.                     document.querySelectorAll('[x-data]').forEach(el => {
  176.                         Alpine.initTree(el);
  177.                     });
  178.                     console.log('Composants Alpine réinitialisés');
  179.                 }, 100);
  180.             }
  181.         });
  182.     </script>
  183.     {% endblock %}
  184. </body>
  185. </html>