{# Flowbite-compatible flash messages #}
<div class="fixed bottom-4 right-2 z-50 space-y-2 pointer-events-none">
{% set types = {
'success': {
'bg': 'bg-green-50 dark:bg-gray-800',
'txt': 'text-green-800 dark:text-green-300',
'btn': 'text-green-500 dark:text-green-300',
'ring': 'ring-1 ring-green-500/50',
'iconPath': 'M16.707 5.293a1 1 0 0 1 0 1.414l-7.5 7.5a1 1 0 0 1-1.414 0l-3-3a1 1 0 1 1 1.414-1.414L8.5 12.086l6.793-6.793a1 1 0 0 1 1.414 0z'
},
'warning': {
'bg': 'bg-yellow-50 dark:bg-gray-800',
'txt': 'text-yellow-800 dark:text-yellow-300',
'btn': 'text-yellow-500 dark:text-yellow-300',
'ring': 'ring-1 ring-yellow-500/50',
'iconPath': 'M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9 4h2v6H9V4Zm0 8h2v2H9v-2Z'
},
'error': {
'bg': 'bg-red-50 dark:bg-gray-800',
'txt': 'text-red-800 dark:text-red-300',
'btn': 'text-red-500 dark:text-red-300',
'ring': 'ring-1 ring-red-500/50',
'iconPath': 'M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm-1-5h2v2H9v-2Zm0-6h2v5H9V7Z'
},
'danger': {
'bg': 'bg-red-50 dark:bg-gray-800',
'txt': 'text-red-800 dark:text-red-300',
'btn': 'text-red-500 dark:text-red-300',
'ring': 'ring-1 ring-red-500/50',
'iconPath': 'M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm-1-5h2v2H9v-2Zm0-6h2v5H9V7Z'
},
'info': {
'bg': 'bg-blue-50 dark:bg-gray-800',
'txt': 'text-blue-800 dark:text-blue-300',
'btn': 'text-blue-500 dark:text-blue-300',
'ring': 'ring-1 ring-blue-500/50',
'iconPath': 'M10 2a8 8 0 1 0 0 16A8 8 0 0 0 10 2Zm1 12H9v-4h2v4Zm0-6H9V6h2v2Z'
}
} %}
{% for type, messages in {
'success': app.flashes('success'),
'warning': app.flashes('warning'),
'error': app.flashes('error'),
'danger': app.flashes('danger'),
'info': app.flashes('info')
} %}
{% set conf = types[type] %}
{% for message in messages %}
{% set id = 'alert-' ~ type ~ '-' ~ loop.index ~ '-' ~ random() %}
<div id="{{ id }}" class="flex items-start gap-2 p-4 rounded-lg shadow-sm {{ conf.bg }} {{ conf.txt }} {{ conf.ring }} pointer-events-auto" role="alert">
<svg class="shrink-0 w-5 h-5 mt-0.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path d="{{ conf.iconPath }}"/>
</svg>
<div class="text-sm font-medium">
{{ message|raw }}
</div>
<button type="button" class="ms-auto -mx-1.5 -my-1.5 rounded-lg focus:ring-2 p-1.5 hover:bg-white/40 inline-flex items-center justify-center h-8 w-8 {{ conf.btn }}" data-dismiss-target="#{{ id }}" aria-label="Close">
<span class="sr-only">Fermer</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/></svg>
</button>
</div>
{% endfor %}
{% endfor %}
{# Also render MercurySeries Flashy notifications with the same Flowbite UI #}
{% for item in app.flashes('mercuryseries_flashy_notification') %}
{% set t = (item.type ?? 'info') %}
{% set conf = types[t] ?? types['info'] %}
{% set id = 'alert-flashy-' ~ t ~ '-' ~ random() %}
<div id="{{ id }}" class="flex items-start gap-2 p-4 rounded-lg shadow-sm {{ conf.bg }} {{ conf.txt }} {{ conf.ring }} pointer-events-auto" role="alert">
<svg class="shrink-0 w-5 h-5 mt-0.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path d="{{ conf.iconPath }}"/>
</svg>
<div class="text-sm font-medium">
{{ item.message|default('')|raw }}
{% if item.link %}
<a href="{{ item.link }}" class="underline ml-1" target="_blank" rel="noopener">Voir</a>
{% endif %}
</div>
<button type="button" class="ms-auto -mx-1.5 -my-1.5 rounded-lg focus:ring-2 p-1.5 hover:bg-white/40 inline-flex items-center justify-center h-8 w-8 {{ conf.btn }}" data-dismiss-target="#{{ id }}" aria-label="Close">
<span class="sr-only">Fermer</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/></svg>
</button>
</div>
{% endfor %}
</div>