Files
e-cosplay/templates/base.twig
Serreau Jovann 65925bdf82 ```
[DEL] docs(file/topic): Supprime favicon et manifest inutilisés.
[FEAT] feat(file/topic): Ajoute PWA bundle et CSP pour la sécurité.
```
2026-01-25 11:56:39 +01:00

251 lines
13 KiB
Twig

<!doctype html>
<html lang="{{ app.request.locale }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{# --- LOGIQUE DE NOËL (Adaptée au style Brutaliste) --- #}
{% set current_date = "now"|date("m-d") %}
{% set is_christmas = (current_date >= "12-15" or current_date <= "01-05") %}
<title>E-Cosplay | {% block title %}Accueil{% endblock %}</title>
<meta name="description" content="{% block meta_description '' %}">
<meta name="env" content="{{ app.environment }}">
{# SEO & Open Graph (Conservés) #}
<meta property="og:type" content="website">
<meta property="og:url" content="{{ url(app.request.attributes.get('_route','app_home'), app.request.attributes.get('_route_params',[])) }}">
<meta property="og:title" content="E-Cosplay | {{ block('title') }}">
<meta property="og:description" content="{{ block('meta_description') }}">
<meta property="og:image" content="{{ asset('assets/images/logo.jpg') | imagine_filter('webp') }}">
<meta name="twitter:card" content="summary_large_image">
<meta name="author" content="Association E-Cosplay">
{# FAVICONS #}
<link rel="icon" type="image/png" href="{{ asset('favicon/favicon-96x96.png') }}" sizes="96x96"/>
<link rel="shortcut icon" href="{{ asset('favicon/favicon.ico') }}"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
{% block canonical_url %}{% endblock %}
{# CONFIGURATION DES COULEURS NEUBRUTALISTES #}
<style>
:root {
--main-bg: #fbfbfb;
--accent-indigo: #4f46e5;
--accent-yellow: #fabf04;
--accent-pink: #ec4899;
--brutal-black: #111827;
--border-width: 4px;
}
body { background-color: var(--main-bg); }
.brutal-shadow { shadow-[8px_8px_0px_rgba(0,0,0,1)]; }
.brutal-border { border: var(--border-width) solid var(--brutal-black); }
{% if is_christmas %}
/* Thème Noël Esport : On remplace l'indigo par un rouge vibrant et le jaune par un vert sapin néon */
:root {
--accent-indigo: #c41e3a;
--accent-yellow: #166534;
}
{% endif %}
</style>
{# SCHÉMAS JSON-LD (Conservés) #}
{% block breadcrumb_schema %}{% endblock %}
{{ vite_asset('app.js', []) }}
{{ pwa(swAttributes={ 'nonce': csp_nonce('script') }) }}
</head>
<body class="flex flex-col min-h-screen font-sans antialiased text-gray-900">
{% set menu_links = [
{ 'name': 'Accueil'|trans, 'route': 'app_home' },
{ 'name': 'Qui sommes-nous'|trans, 'route': 'app_about' },
{ 'name': 'Nos membres'|trans, 'route': 'app_members' },
{ 'name': 'epage_cosplay'|trans, 'route': 'app_pages' },
{ 'name': 'Nos événements'|trans, 'route': 'app_events' },
{ 'name': 'Boutiques'|trans, 'route': 'app_shop' },
{ 'name': 'Documents'|trans, 'route': 'app_doc' },
{ 'name': 'Dons'|trans, 'route': 'app_dons' },
{ 'name': 'Nous rejoindre'|trans, 'route': 'app_recruit' },
{ 'name': 'Contact'|trans, 'route': 'app_contact' }
] %}
{# --- BARRE DE NAVIGATION : COMMAND CENTER --- #}
<header class="sticky top-0 z-50 bg-white border-b-4 border-gray-900">
<nav class="mx-auto px-4 lg:px-8">
<div class="flex justify-between items-center h-20">
{# LOGO #}
<div class="flex-shrink-0">
<a href="{{ path('app_home') }}" class="flex items-center group">
<div class="relative p-2 border-2 border-gray-900 shadow-[4px_4px_0px_rgba(0,0,0,1)] group-hover:translate-x-1 group-hover:translate-y-1 group-hover:shadow-none transition-all">
<img class="h-8 w-auto" src="{{ asset('assets/images/logo.jpg') | imagine_filter('logo') }}" alt="E-Cosplay">
{% if is_christmas %}<span class="absolute -top-4 -left-4 text-2xl rotate-[-15deg]">🎅</span>{% endif %}
</div>
<span class="ml-4 text-2xl font-black uppercase tracking-tighter italic">E-Cosplay</span>
</a>
</div>
{# DESKTOP NAV #}
<div class="hidden lg:flex items-center space-x-1">
{% for link in menu_links %}
{% set is_active = (app.request.get('_route') == link.route) %}
<a href="{{ path(link.route) }}"
class="px-3 py-2 text-xs font-black uppercase tracking-widest transition-all
{% if is_active %} bg-yellow-400 border-2 border-gray-900 shadow-[2px_2px_0px_rgba(0,0,0,1)]
{% else %} hover:text-indigo-600 {% endif %}">
{{ link.name }}
</a>
{% endfor %}
</div>
{# ACTIONS (Lang, Cart, User) #}
<div class="flex items-center space-x-4 border-l-4 border-gray-900 pl-6 h-full">
{# SÉLECTEUR LANGUE PRO #}
<div class="hidden xl:flex space-x-2">
{% for lang in ['fr', 'en','cn','ger','es'] %}
<a href="{{ path(app.request.attributes.get('_route','app_home'), app.request.attributes.get('_route_params',[])|merge({'lang': lang})) }}"
class="text-[10px] font-black uppercase p-1 border-2 border-transparent {% if app.request.locale == lang %} border-gray-900 bg-gray-900 text-white {% else %} hover:border-gray-900 {% endif %}">
{{ lang }}
</a>
{% endfor %}
</div>
{# ICONS #}
<div class="flex items-center gap-2">
<button id="openCartDesktop" class="relative p-2 border-2 border-gray-900 hover:bg-pink-500 hover:text-white transition-colors">
<i class="fas fa-shopping-cart"></i>
<span id="cartCountDesktop" class="absolute -top-2 -right-2 bg-indigo-600 text-white text-[10px] font-black w-5 h-5 flex items-center justify-center border-2 border-gray-900">0</span>
</button>
<div class="relative group">
{% if app.user %}
<a href="{{ path('app_profile') }}"
class="p-2 border-2 border-gray-900 bg-indigo-600 text-white shadow-[3px_3px_0px_#000] hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px] transition-all flex items-center justify-center">
<i class="fas fa-user-check"></i>
</a>
{% else %}
{# État DÉCONNECTÉ : Style neutre d'origine #}
<a href="{{ path('app_login') }}"
class="p-2 border-2 border-gray-900 bg-white text-gray-900 hover:bg-gray-900 hover:text-white transition-all flex items-center justify-center">
<i class="fas fa-user-circle"></i>
</a>
{% endif %}
</div>
<button id="mobileMenuButton" class="lg:hidden p-2 border-2 border-gray-900 bg-yellow-400">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</div>
</nav>
{# MOBILE MENU SLIDE #}
<div id="mobile-menu" class="hidden lg:hidden border-t-4 border-gray-900 bg-white">
<div class="p-4 space-y-2 uppercase font-black italic">
{% for link in menu_links %}
<a href="{{ path(link.route) }}" class="block p-3 border-2 border-transparent hover:border-gray-900 hover:bg-gray-50">
{{ link.name }}
</a>
{% endfor %}
</div>
</div>
</header>
<main role="main" class="flex-grow">
{% block body %}{% endblock %}
</main>
{# --- FOOTER : THE TERMINAL --- #}
<footer class="bg-yellow-400 border-t-8 border-gray-900 text-gray-900 mt-auto">
<div class="max-w-7xl mx-auto py-12 px-4 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-12 mb-12 border-b-4 border-gray-900 pb-12">
{# CONTACT #}
<div class="space-y-4">
<h3 class="text-3xl font-black uppercase tracking-tighter italic border-b-4 border-gray-900 inline-block">{{ 'footer_contact_title'|trans }}</h3>
<p class="font-bold text-lg leading-tight">42 RUE DE SAINT-QUENTIN<br>02800 BEAUTOR, FRANCE</p>
<a href="mailto:contact@e-cosplay.fr" class="inline-block bg-gray-900 text-white px-4 py-2 font-black uppercase text-sm hover:bg-indigo-600 transition-colors">
contact@e-cosplay.fr
</a>
</div>
{# SOCIAL & STRIPE #}
<div class="space-y-6">
<h3 class="text-3xl font-black uppercase tracking-tighter italic border-b-4 border-gray-900 inline-block">{{ 'footer_follow_us_title'|trans }}</h3>
<div class="bg-white border-4 border-gray-900 p-4 shadow-[6px_6px_0px_rgba(0,0,0,1)]">
<p class="text-xs font-black uppercase mb-2 tracking-widest">{{ 'newsletter.title'|trans }}</p>
<form action="{{ path('app_newsletter') }}" method="POST" class="flex flex-col gap-2">
<input required type="email" name="email" placeholder="email@e-cosplay.fr"
class="border-2 border-gray-900 p-2 text-xs font-bold uppercase focus:bg-pink-100 outline-none">
<button type="submit"
class="bg-indigo-600 text-white border-2 border-gray-900 py-2 px-4 text-xs font-black uppercase hover:bg-black hover:shadow-none shadow-[2px_2px_0px_rgba(0,0,0,1)] transition-all active:translate-x-1 active:translate-y-1">
{{ 'newsletter.subscribe'|trans }}
</button>
</form>
</div>
<div class="flex gap-4">
<a href="https://www.facebook.com/assocationecosplay" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-facebook-f text-xl"></i></a>
<a href="https://www.instagram.com/asso_ecosplay/" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-instagram text-xl"></i></a>
</div>
<div class="bg-white/50 p-2 border-2 border-gray-900 inline-block">
<iframe width="300" height="60" style="border:0;" src="https://climate.stripe.com/badge/qrsnOf?theme=light&size=small&locale={{ app.request.locale }}"></iframe>
</div>
</div>
{# MISSION #}
<div class="space-y-4">
<h3 class="text-3xl font-black uppercase tracking-tighter italic border-b-4 border-gray-900 inline-block">E-Cosplay</h3>
<p class="font-bold text-gray-800 italic leading-snug">
{{ 'footer_mission_description'|trans|striptags }}
</p>
</div>
</div>
{# BOTTOM LINKS #}
<div class="flex flex-col md:flex-row justify-between items-center gap-6">
<div class="text-center md:text-left">
<p class="font-black uppercase text-sm">&copy; {{ "now"|date("Y") }} E-COSPLAY.</p>
<p class="text-[10px] font-bold opacity-70">RNA N°W022006988 - DEV BY SITECONSEIL</p>
</div>
<div class="flex flex-wrap justify-center gap-3">
{% set footer_links = [
{'path': 'app_legal', 'label': 'legal_notice_link'},
{'path': 'app_cookies', 'label': 'cookie_policy_link'},
{'path': 'app_cgu', 'label': 'cgu_link'},
{'path': 'app_rgpd', 'label': 'rgpd_policy_link'},
{'path': 'app_hosting', 'label': 'hosting_link'},
{'path': 'app_rules', 'label': 'rule_link'}
] %}
{% for flink in footer_links %}
<a href="{{ path(flink.path) }}" class="text-[10px] font-black uppercase bg-gray-900 text-white px-2 py-1 hover:bg-indigo-600 transition-colors">
{{ flink.label|trans }}
</a>
{% endfor %}
</div>
</div>
</div>
</footer>
{# OVERLAYS (Cart Sidebar) - Style Brutaliste #}
<div id="cartSidebar" class="fixed top-0 right-0 w-full md:w-[450px] h-full bg-white border-l-8 border-gray-900 shadow-[-20px_0px_0px_rgba(79,70,229,0.5)] transform translate-x-full transition-transform duration-500 ease-[cubic-bezier(0.95,0.05,0.795,0.035)] z-[100] flex flex-col italic">
<div class="p-8 border-b-4 border-gray-900 flex justify-between items-center bg-pink-500 text-white">
<h2 class="text-4xl font-black uppercase tracking-tighter">{{ 'your_cart'|trans }}</h2>
<button id="closeCartButton" class="w-12 h-12 border-4 border-white flex items-center justify-center hover:bg-white hover:text-pink-500 transition-all">
<i class="fas fa-times text-2xl"></i>
</button>
</div>
<div id="cartItemsContainer" class="flex-grow overflow-y-auto p-8 font-bold">
{# Dynamic items here #}
</div>
</div>
</body>
</html>