Files
ludikevent_crm/templates/revervation/base.twig
Serreau Jovann 6656d56111 ```
 feat(reservation/contrat): Ajoute la gestion complète des contrats
```
2026-01-22 20:15:21 +01:00

235 lines
12 KiB
Twig
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
{# --- SEO Fondamental --- #}
<title>{% block title %}Ludikevent | Location de structures gonflables à Danizy{% endblock %}</title>
<meta name="description" content="{% block description %}Ludikevent : location de châteaux gonflables et animations. Qualité pro pour vos événements.{% endblock %}">
{# URL Canonique dynamique #}
<link rel="canonical" href="{{ app.request.schemeAndHttpHost }}{{ app.request.pathinfo }}">
{# --- Open Graph (Facebook / WhatsApp) --- #}
<meta property="og:type" content="website">
<meta property="og:url" content="{{ app.request.uri }}">
<meta property="og:title" content="{{ block('title') }}">
<meta property="og:description" content="{{ block('description') }}">
<meta property="og:image" content="{{ absolute_url(asset('provider/images/favicon.png')) }}">
<meta property="article:publisher" content="https://www.facebook.com/profile.php?id=61574652399326">
{# --- Twitter Card --- #}
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ block('title') }}">
<meta name="twitter:image" content="{{ absolute_url(asset('provider/images/favicon.png')) }}">
{# --- Données Structurées (JSON-LD) --- #}
<script type="application/ld+json">
[
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Ludikevent",
"image": "{{ absolute_url(asset('provider/images/favicon.png')) }}",
"telephone": "+33614172447",
"email": "contact@ludikevent.fr",
"url": "{{ app.request.schemeAndHttpHost }}",
"address": {
"@type": "PostalAddress",
"streetAddress": "6 Rue du Château",
"addressLocality": "Danizy",
"postalCode": "02800",
"addressCountry": "FR"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 49.6644,
"longitude": 3.3852
},
"sameAs": [
"https://www.facebook.com/profile.php?id=61574652399326"
],
"priceRange": "€€"
},
{
"@context": "https://schema.org",
"@type": "WebSite",
"url": "{{ app.request.schemeAndHttpHost }}",
"potentialAction": {
"@type": "SearchAction",
"target": "{{ url('reservation_search') }}?q={search_term_string}",
"query-input": "required name=search_term_string"
}
},
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Accueil",
"item": "{{ url('reservation') }}"
}
{% block breadcrumb_json %}{% endblock %}
]
}
]
</script>
{% block jsonld %}{% endblock %}
{# --- PWA (Configuré via manifest.json) --- #}
{% if app.environment != 'dev' %}
{{ pwa(swAttributes={ 'nonce': csp_nonce('script') }) }}
<script data-host-url="https://tools-security.esy-web.dev" nonce="{{ csp_nonce('script') }}" defer src="/utm_reserve.js" data-website-id="38d713c3-3923-4791-875a-dfe5f45372c3"></script>
{% else %}
<script data-host-url="https://tools-security.esy-web.dev" nonce="{{ csp_nonce('script') }}" defer src="/utm_reserve.js" data-website-id="bc640e0d-43fb-4c3a-bb17-1ac01cec9643"></script>
{% endif %}
{{ vite_asset('reserve.js',{}) }}
{% block stylesheets %}{% endblock %}
</head>
<body class="bg-gray-50 text-gray-900 font-sans antialiased min-h-screen flex flex-col">
{% if is_granted('ROLE_ADMIN') %}
<utm-account id="{{ app.user.id }}" email="{{ app.user.email }}" name="{{ app.user.username }}"></utm-account>
{% endif %}
{% if is_granted('ROLE_CUSTOMER') and 'gestion-contrat' not in app.request.pathInfo %}
<utm-account id="{{ app.user.id }}" email="{{ app.user.email }}" name="{{ app.user.name }}"></utm-account>
{% endif %}
{# --- NAVIGATION --- #}
<nav class="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-gray-100">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-20">
{# Logo #}
<div class="flex-shrink-0 flex items-center">
<a href="{{ path('reservation') }}" class="flex items-center gap-2 group">
<img class="h-12 w-auto transition-transform group-hover:scale-105"
src="{{ asset('provider/images/favicon.png') }}"
alt="Ludikevent Logo">
<span class="text-2xl font-black tracking-tighter text-blue-600 uppercase">
Ludik<span class="text-amber-500">event</span>
</span>
</a>
</div>
{# Menu Desktop #}
<div class="hidden md:flex items-center space-x-8">
<a href="{{ path('reservation') }}" class="text-gray-700 hover:text-blue-600 font-medium transition-colors">Accueil</a>
<a href="{{ path('reservation_catalogue') }}" class="text-gray-700 hover:text-blue-600 font-medium transition-colors">Catalogue</a>
<a href="{{ path('reservation_workflow') }}" class="text-gray-700 hover:text-blue-600 font-medium transition-colors">Comment réserver ?</a>
<a href="{{ path('reservation_contact') }}" class="text-gray-700 hover:text-blue-600 font-medium transition-colors">Contact</a>
<a href="{{ path('reservation_search') }}" class="p-2 text-gray-500 hover:text-blue-600 transition-colors" aria-label="Rechercher">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</a>
<a href="tel:0614172447" class="inline-flex items-center px-6 py-3 border border-transparent text-sm font-bold rounded-full text-white bg-blue-600 hover:bg-blue-700 shadow-lg shadow-blue-200 transition-all hover:-translate-y-0.5">
06 14 17 24 47
</a>
</div>
{# Bouton Menu Mobile #}
<div class="md:hidden flex items-center">
<button id="menu-button" type="button" class="text-gray-600 p-2 focus:outline-none" aria-expanded="false" aria-controls="mobile-menu">
<svg class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
</svg>
</button>
</div>
</div>
</div>
{# Contenu Menu Mobile (Caché par défaut) #}
<div id="mobile-menu" class="hidden md:hidden bg-white border-t border-gray-100 shadow-xl">
<div class="px-4 pt-2 pb-6 space-y-2">
<a href="{{ path('reservation') }}" class="block px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 rounded-xl transition-colors">Accueil</a>
<a href="{{ path('reservation_search') }}" class="block px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 rounded-xl transition-colors">Rechercher</a>
<div class="pt-4 border-t border-gray-50">
<a href="tel:0614172447" class="block px-3 py-3 text-center bg-blue-600 text-white rounded-xl font-bold">
Appeler le 06 14 17 24 47
</a>
</div>
</div>
</div>
</nav>
{# --- GESTION DES MESSAGES FLASH --- #}
{% for label, messages in app.flashes %}
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
{% for message in messages %}
<div class="flex items-center justify-between p-4 rounded-[2rem] shadow-lg border animate-in fade-in slide-in-from-top-4 duration-500
{% if label == 'success' %}
bg-emerald-50 border-emerald-100 text-emerald-800
{% elseif label == 'error' or label == 'danger' %}
bg-red-50 border-red-100 text-red-800
{% else %}
bg-blue-50 border-blue-100 text-blue-800
{% endif %}">
<div class="flex items-center gap-3">
<span class="text-xl">
{% if label == 'success' %}
{% elseif label == 'error' or label == 'danger' %}
{% else %} {% endif %}
</span>
<p class="text-sm font-black italic uppercase tracking-tight">{{ message }}</p>
</div>
{# Bouton pour fermer le message #}
<button onclick="this.parentElement.parentElement.remove()" class="p-2 hover:opacity-50 transition-opacity">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
{% endfor %}
</div>
{% endfor %}
{# --- CONTENU --- #}
<main class="flex-grow">
{% block body %}{% endblock %}
</main>
{# --- PIED DE PAGE --- #}
<footer class="bg-white border-t border-gray-100 py-8 mt-auto">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row justify-between items-center gap-8">
{# Marque #}
<div class="text-center md:text-left">
<p class="text-sm text-gray-500">
&copy; {{ "now"|date("Y") }} <span class="font-bold text-blue-600">Ludikevent</span>.
Tous droits réservés.
</p>
<p class="text-xs text-gray-400 mt-1">Location de structures gonflables.</p>
</div>
{# Liens légaux #}
<div class="flex flex-wrap justify-center gap-x-6 gap-y-2 text-xs text-gray-500 font-medium">
<a href="{{ path('reservation_mentions-legal') }}" class="hover:text-blue-600 transition-colors">Mentions légales</a>
<a href="{{ path('reservation_cgv') }}" class="hover:text-blue-600 transition-colors">CGV</a>
<a href="{{ path('reservation_rgpd') }}" class="hover:text-blue-600 transition-colors">RGPD</a>
<a href="{{ path('reservation_cookies') }}" class="hover:text-blue-600 transition-colors">Cookies</a>
<a href="{{ path('reservation_hosting') }}" class="hover:text-blue-600 transition-colors">Hébergement</a>
</div>
{# Réseaux Sociaux #}
<div class="flex items-center gap-4">
<a href="https://www.facebook.com/profile.php?id=61574652399326" target="_blank" rel="noopener" class="text-gray-400 hover:text-blue-600 transition-colors" aria-label="Facebook">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"><path d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z"/></svg>
</a>
</div>
</div>
</div>
</footer>
{% block javascripts %}{% endblock %}
</body>
</html>