templates/partials/_flash_messages.html.twig line 1

  1. {# templates/partials/_flash_messages.html.twig #}
  2. {% for type, messages in app.flashes %}
  3.     {% for message in messages %}
  4.         <div class="flash-message bg-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-50 border-l-4 border-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-500 p-4 rounded-r-lg mb-4 relative animate-slide-in" data-autodismiss="{{ type == 'success' ? '3000' : '5000' }}">
  5.             <button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 p-1 text-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-500 hover:text-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-700 transition-colors" onclick="this.closest('.flash-message').remove()">
  6.                 <i class="fas fa-times"></i>
  7.             </button>
  8.             <div class="flex items-center">
  9.                 <i class="fas fa-{{ type == 'success' ? 'check-circle' : (type == 'error' ? 'exclamation-circle' : (type == 'warning' ? 'exclamation-triangle' : 'info-circle')) }} text-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-500 mr-3"></i>
  10.                 <p class="text-{{ type == 'success' ? 'green' : (type == 'error' ? 'red' : (type == 'warning' ? 'amber' : 'blue')) }}-700 pr-6">{{ message|raw }}</p>
  11.             </div>
  12.         </div>
  13.     {% endfor %}
  14. {% endfor %}
  15. {% if error is defined and error %}
  16.     <div class="bg-red-50 border-l-4 border-red-500 p-4 rounded-r-lg mb-4 animate-shake relative">
  17.         <button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 p-1 text-red-500 hover:text-red-700 transition-colors" onclick="this.closest('[class*=\'bg-red-50\']').remove()">
  18.             <i class="fas fa-times"></i>
  19.         </button>
  20.         <div class="flex items-center">
  21.             <i class="fas fa-exclamation-circle text-red-500 mr-3"></i>
  22.             <p class="text-red-700 pr-6">{{ error.messageKey|trans(error.messageData, 'security') }}</p>
  23.         </div>
  24.     </div>
  25. {% endif %}
  26. <style>
  27. @keyframes slideIn {
  28.     from {
  29.         transform: translateY(-20px);
  30.         opacity: 0;
  31.     }
  32.     to {
  33.         transform: translateY(0);
  34.         opacity: 1;
  35.     }
  36. }
  37. .animate-slide-in {
  38.     animation: slideIn 0.3s ease-out;
  39. }
  40. @keyframes shake {
  41.     0%, 100% { transform: translateX(0); }
  42.     10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  43.     20%, 40%, 60%, 80% { transform: translateX(5px); }
  44. }
  45. .animate-shake {
  46.     animation: shake 0.6s ease-in-out;
  47. }
  48. @keyframes fadeOut {
  49.     from {
  50.         opacity: 1;
  51.         transform: translateY(0);
  52.     }
  53.     to {
  54.         opacity: 0;
  55.         transform: translateY(-10px);
  56.     }
  57. }
  58. .flash-message.fade-out {
  59.     animation: fadeOut 0.3s ease-out forwards;
  60. }
  61. </style>
  62. <script>
  63. document.addEventListener('DOMContentLoaded', function() {
  64.     document.querySelectorAll('.flash-message[data-autodismiss]').forEach(function(message) {
  65.         var delay = parseInt(message.dataset.autodismiss, 10);
  66.         setTimeout(function() {
  67.             message.classList.add('fade-out');
  68.             setTimeout(function() {
  69.                 message.remove();
  70.             }, 300);
  71.         }, delay);
  72.     });
  73. });
  74. </script>