- Add public organizers list page (/organisateurs) with neo-brutalist card grid, social icons, and logo display
- Add organizer detail page (/organisateur/{id}-{slug}) with company info, SIRET, email, address, social links, and events placeholder
- Add slug-based URLs with 301 redirect on wrong slug, getSlug() method on User entity
- Add "Voir les evenements" button on organizer cards linking to detail page
- Add JSON-LD BreadcrumbList to all 17 pages that were missing breadcrumbs (login, forgot_password, register_success, email_verified, legal/*, attestation/*, account/*)
- Add Open Graph meta tags (og:title, og:description, og:image, og:type, og:locale, og:site_name) in base.html.twig with automatic inheritance from title/description blocks
- Add og:image with organizer logo on detail page
- Update sitemap: add /organisateurs to sitemap-main, generate organizer detail URLs in sitemap-orgas with logo images
- Update navbar to highlight "Organisateurs" on detail pages
- Redesign homepage with hero section, marquee, stats counters, how-it-works, and CTA sections
- Add Tailwind v4 @source "../templates" directive to app.scss and admin.scss
- Migrate Flysystem from S3 to local storage (uploads/events, uploads/logos)
- Update Liip Imagine config with FormatExtensionResolver for webp conversion
- Add User entity social fields (website, facebook, instagram, twitter, tiktok), logo upload (Vich), __serialize/__unserialize for session safety
- Add account page settings tab with profile, logo upload, and social media for organizers
- Add Stripe Connect status display and sub-account management in account page
- Delete WebpExtensionSubscriber (replaced by FormatExtensionResolver)
- Add migration for social fields and logo columns
- Add deploy.yml chmod tasks for uploads directories
- Add HomeController tests (detail success, wrong slug redirect, 404 cases)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
402 lines
32 KiB
Twig
402 lines
32 KiB
Twig
{% extends 'base.html.twig' %}
|
|
|
|
{% block title %}Mon compte - E-Ticket{% endblock %}
|
|
|
|
{% block body %}
|
|
<div style="max-width:60rem;margin:0 auto;padding:3rem 1rem;">
|
|
<div style="margin-bottom:2rem;">
|
|
<h1 class="text-3xl font-black uppercase tracking-tighter italic" style="border-bottom:4px solid #111827;display:inline-block;margin-bottom:0.5rem;">Mon compte</h1>
|
|
<p class="font-bold text-gray-500 italic">Bonjour {{ app.user.firstName }}, bienvenue sur votre espace.</p>
|
|
</div>
|
|
|
|
{% for message in app.flashes('success') %}
|
|
<div style="border:4px solid #111827;box-shadow:4px 4px 0 rgba(0,0,0,1);background:#d1fae5;padding:1rem 1.5rem;margin-bottom:1.5rem;">
|
|
<p class="font-black text-sm">{{ message }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
{% for message in app.flashes('error') %}
|
|
<div style="border:4px solid #111827;box-shadow:4px 4px 0 rgba(0,0,0,1);background:#fee2e2;padding:1rem 1.5rem;margin-bottom:1.5rem;">
|
|
<p class="font-black text-sm">{{ message }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{% if isOrganizer and not app.user.approved %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:#fef3c7;padding:2rem;text-align:center;">
|
|
<div style="font-size:2rem;margin-bottom:1rem;">⏳</div>
|
|
<h2 class="text-xl font-black uppercase tracking-tighter italic" style="margin-bottom:0.5rem;">Compte en cours de validation</h2>
|
|
<p class="font-bold text-gray-700 text-sm">Votre compte organisateur est en cours de validation par l'equipe E-Ticket. Vous recevrez un email une fois votre compte approuve.</p>
|
|
<p class="text-gray-500 text-xs font-bold" style="margin-top:1rem;">Contactez <a href="mailto:contact@e-cosplay.fr" class="text-indigo-600 hover:underline">contact@e-cosplay.fr</a> pour toute question.</p>
|
|
</div>
|
|
|
|
{% else %}
|
|
|
|
{% if isOrganizer %}
|
|
{% if not app.user.stripeAccountId %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:#fef3c7;padding:1.5rem;margin-bottom:2rem;">
|
|
<h2 class="text-sm font-black uppercase tracking-widest" style="margin-bottom:0.5rem;">Configuration Stripe requise
|
|
<span style="background:white;border:2px solid #111827;padding:0.1rem 0.4rem;font-size:10px;margin-left:0.5rem;">Statut : non configure</span>
|
|
</h2>
|
|
<p class="text-sm font-bold text-gray-700" style="margin-bottom:1rem;">Pour creer vos evenements, vendre des billets et recevoir vos paiements, vous devez creer votre compte vendeur via Stripe.</p>
|
|
<a href="{{ path('app_account_stripe_connect') }}" style="padding:0.5rem 1rem;border:3px solid #111827;box-shadow:4px 4px 0 rgba(0,0,0,1);background:#fabf04;display:inline-block;" class="font-black uppercase text-xs tracking-widest hover:bg-indigo-600 hover:text-black transition-all">Creer mon compte Stripe</a>
|
|
</div>
|
|
|
|
{% elseif not app.user.stripeChargesEnabled and not app.user.stripePayoutsEnabled %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:#fef3c7;padding:1.5rem;margin-bottom:2rem;">
|
|
<h2 class="text-sm font-black uppercase tracking-widest" style="margin-bottom:0.5rem;">Verification Stripe en cours
|
|
<span style="background:white;border:2px solid #111827;padding:0.1rem 0.4rem;font-size:10px;margin-left:0.5rem;">Statut : {{ app.user.stripeStatus ?? 'en attente' }}</span>
|
|
</h2>
|
|
<p class="text-sm font-bold text-gray-700" style="margin-bottom:1rem;">Votre compte Stripe est en cours de verification. Merci de patienter, vous serez notifie une fois la verification terminee.</p>
|
|
<div style="display:flex;gap:0.75rem;flex-wrap:wrap;">
|
|
<a href="{{ path('app_account_stripe_connect') }}" style="padding:0.5rem 1rem;border:3px solid #111827;background:white;display:inline-block;" class="font-black uppercase text-xs tracking-widest hover:bg-gray-100 transition-all">Completer ma verification</a>
|
|
<form method="post" action="{{ path('app_account_stripe_cancel') }}" data-confirm="Etes-vous sur de vouloir annuler la creation de votre compte Stripe ?" style="display:inline;">
|
|
<button type="submit" style="padding:0.5rem 1rem;border:3px solid #991b1b;background:#dc2626;color:white;cursor:pointer;" class="font-black uppercase text-xs tracking-widest hover:bg-red-800 transition-all">Annuler la creation</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% elseif app.user.stripeChargesEnabled and app.user.stripePayoutsEnabled %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:#d1fae5;padding:1rem 1.5rem;margin-bottom:2rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem;">
|
|
<p class="font-black text-sm">Stripe Connect actif — Paiements et virements actives.
|
|
<span style="background:white;border:2px solid #111827;padding:0.1rem 0.4rem;font-size:10px;margin-left:0.5rem;">Statut : {{ app.user.stripeStatus }}</span>
|
|
</p>
|
|
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;">
|
|
<a href="{{ path('app_account_stripe_dashboard') }}" target="_blank" style="padding:0.4rem 0.75rem;border:2px solid #111827;background:white;display:inline-block;" class="text-xs font-black uppercase tracking-widest hover:bg-gray-100 transition-all">Dashboard Stripe</a>
|
|
<form method="post" action="{{ path('app_account_stripe_cancel') }}" data-confirm="Etes-vous sur de vouloir cloturer votre compte Stripe ? Vous ne pourrez plus recevoir de paiements." style="display:inline;">
|
|
<button type="submit" style="padding:0.4rem 0.75rem;border:2px solid #991b1b;background:#dc2626;color:white;cursor:pointer;" class="text-xs font-black uppercase tracking-widest hover:bg-red-800 transition-all">Cloturer</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% else %}
|
|
<div style="border:4px solid #991b1b;box-shadow:6px 6px 0 rgba(0,0,0,1);background:#fee2e2;padding:1.5rem;margin-bottom:2rem;">
|
|
<h2 class="text-sm font-black uppercase tracking-widest" style="margin-bottom:0.5rem;color:#991b1b;">Compte Stripe refuse
|
|
<span style="background:white;border:2px solid #991b1b;padding:0.1rem 0.4rem;font-size:10px;margin-left:0.5rem;">Statut : {{ app.user.stripeStatus ?? 'refuse' }}</span>
|
|
</h2>
|
|
<p class="text-sm font-bold text-gray-700">Stripe a refuse votre compte vendeur. Vous ne pouvez pas utiliser nos services de vente pour le moment. Contactez <a href="mailto:contact@e-cosplay.fr" class="text-indigo-600 hover:underline">contact@e-cosplay.fr</a> pour plus d'informations.</p>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<div style="display:flex;gap:0;margin-bottom:2rem;flex-wrap:wrap;">
|
|
{% if isOrganizer %}
|
|
<a href="{{ path('app_account', {tab: 'events'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'events' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Evenements / Brocantes</a>
|
|
<a href="{{ path('app_account', {tab: 'subaccounts'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'subaccounts' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Sous-comptes</a>
|
|
<a href="{{ path('app_account', {tab: 'payouts'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'payouts' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Virements</a>
|
|
{% endif %}
|
|
<a href="{{ path('app_account', {tab: 'tickets'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'tickets' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Billets</a>
|
|
<a href="{{ path('app_account', {tab: 'purchases'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'purchases' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Achats</a>
|
|
<a href="{{ path('app_account', {tab: 'invoices'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;border-right:none;{{ tab == 'invoices' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Factures</a>
|
|
<a href="{{ path('app_account', {tab: 'settings'}) }}" style="flex:1;min-width:100px;text-align:center;padding:0.75rem;border:3px solid #111827;{{ tab == 'settings' ? 'background:#fabf04;' : 'background:white;' }}" class="font-black uppercase text-xs tracking-widest transition-all">Parametres</a>
|
|
</div>
|
|
|
|
{% if tab == 'tickets' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes billets</h2>
|
|
</div>
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucun billet pour le moment.</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% elseif tab == 'purchases' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes achats</h2>
|
|
</div>
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucun achat pour le moment.</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% elseif tab == 'invoices' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes factures</h2>
|
|
</div>
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucune facture pour le moment.</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% elseif tab == 'events' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes evenements / Brocantes / Reservations</h2>
|
|
</div>
|
|
{% if isOrganizer and (not app.user.stripeChargesEnabled or not app.user.stripePayoutsEnabled) %}
|
|
<div style="padding:1.5rem;background:#fef3c7;border-bottom:2px solid #e5e7eb;">
|
|
<p class="font-black text-sm">Configuration Stripe ou validation est requise !</p>
|
|
</div>
|
|
{% endif %}
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucun evenement pour le moment.</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% elseif tab == 'subaccounts' %}
|
|
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;padding:1.5rem;margin-bottom:2rem;">
|
|
<h2 class="text-sm font-black uppercase tracking-widest" style="margin-bottom:1rem;">Creer un sous-compte</h2>
|
|
<form method="post" action="{{ path('app_account_create_subaccount') }}" style="display:flex;flex-direction:column;gap:1rem;">
|
|
<div style="display:flex;flex-wrap:wrap;gap:1rem;">
|
|
<div style="flex:1;min-width:140px;">
|
|
<label for="sub_last_name" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Nom</label>
|
|
<input type="text" id="sub_last_name" name="last_name" required style="width:100%;padding:0.5rem 0.75rem;border:2px solid #111827;font-weight:700;outline:none;" placeholder="Dupont">
|
|
</div>
|
|
<div style="flex:1;min-width:140px;">
|
|
<label for="sub_first_name" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Prenom</label>
|
|
<input type="text" id="sub_first_name" name="first_name" required style="width:100%;padding:0.5rem 0.75rem;border:2px solid #111827;font-weight:700;outline:none;" placeholder="Jean">
|
|
</div>
|
|
<div style="flex:2;min-width:200px;">
|
|
<label for="sub_email" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Email</label>
|
|
<input type="email" id="sub_email" name="email" required style="width:100%;padding:0.5rem 0.75rem;border:2px solid #111827;font-weight:700;outline:none;" placeholder="collaborateur@exemple.fr">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<p style="font-size:10px;letter-spacing:0.1em;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Permissions</p>
|
|
<div style="display:flex;flex-wrap:wrap;gap:1rem;">
|
|
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;" class="text-sm font-bold">
|
|
<input type="checkbox" name="permissions[]" value="scanner" style="width:1rem;height:1rem;"> Scanner (valider les billets)
|
|
</label>
|
|
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;" class="text-sm font-bold">
|
|
<input type="checkbox" name="permissions[]" value="events" style="width:1rem;height:1rem;"> Evenements (creer, modifier, supprimer)
|
|
</label>
|
|
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;" class="text-sm font-bold">
|
|
<input type="checkbox" name="permissions[]" value="tickets" style="width:1rem;height:1rem;"> Billets (invitations gratuites)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<button type="submit" style="padding:0.5rem 1rem;border:2px solid #111827;background:#fabf04;cursor:pointer;align-self:flex-start;" class="font-black uppercase text-xs tracking-widest hover:bg-green-500 hover:text-black transition-all">Creer</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Sous-comptes</h2>
|
|
</div>
|
|
{% if subAccounts|length > 0 %}
|
|
<table style="width:100%;border-collapse:collapse;">
|
|
<thead>
|
|
<tr style="border-bottom:2px solid #e5e7eb;">
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Nom</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Email</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Permissions</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:right;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for sub in subAccounts %}
|
|
<tr style="border-bottom:1px solid #e5e7eb;" class="hover:bg-gray-50 transition-all">
|
|
<td style="padding:0.75rem 1.5rem;" class="font-bold text-sm">{{ sub.firstName }} {{ sub.lastName }}</td>
|
|
<td style="padding:0.75rem 1.5rem;" class="text-sm text-gray-600">{{ sub.email }}</td>
|
|
<td style="padding:0.75rem 1.5rem;">
|
|
{% for perm in sub.subAccountPermissions ?? [] %}
|
|
{% if perm == 'scanner' %}
|
|
<span style="background:#dbeafe;border:2px solid #111827;padding:0.1rem 0.4rem;" class="text-xs font-black uppercase">Scanner</span>
|
|
{% elseif perm == 'events' %}
|
|
<span style="background:#e0e7ff;border:2px solid #111827;padding:0.1rem 0.4rem;" class="text-xs font-black uppercase">Evenements</span>
|
|
{% elseif perm == 'tickets' %}
|
|
<span style="background:#fef3c7;border:2px solid #111827;padding:0.1rem 0.4rem;" class="text-xs font-black uppercase">Billets</span>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</td>
|
|
<td style="padding:0.75rem 1.5rem;text-align:right;">
|
|
<div style="display:flex;gap:0.5rem;justify-content:flex-end;">
|
|
<a href="{{ path('app_account_edit_subaccount_page', {id: sub.id}) }}" style="border:2px solid #111827;padding:0.3rem 0.5rem;background:#fabf04;display:inline-block;" class="text-xs font-black uppercase tracking-widest hover:bg-indigo-600 hover:text-black transition-all">Editer</a>
|
|
<form method="post" action="{{ path('app_account_delete_subaccount', {id: sub.id}) }}" data-confirm="Supprimer le sous-compte de {{ sub.firstName }} {{ sub.lastName }} ?" style="display:inline;">
|
|
<button type="submit" style="border:2px solid #991b1b;padding:0.3rem 0.5rem;background:#dc2626;color:white;cursor:pointer;" class="text-xs font-black uppercase tracking-widest hover:bg-red-800 transition-all">Supprimer</button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucun sous-compte pour le moment.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% elseif tab == 'payouts' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;">
|
|
<div style="padding:0.75rem 1.5rem;background:#111827;">
|
|
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes virements</h2>
|
|
</div>
|
|
{% if isOrganizer and (not app.user.stripeChargesEnabled or not app.user.stripePayoutsEnabled) %}
|
|
<div style="padding:1.5rem;background:#fef3c7;border-bottom:2px solid #e5e7eb;">
|
|
<p class="font-black text-sm">Configuration Stripe ou validation est requise !</p>
|
|
</div>
|
|
{% endif %}
|
|
{% if payouts|length > 0 %}
|
|
<table style="width:100%;border-collapse:collapse;">
|
|
<thead>
|
|
<tr style="border-bottom:2px solid #e5e7eb;">
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">ID</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Montant</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Statut</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Destination</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Arrivee</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:left;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Date</th>
|
|
<th style="padding:0.75rem 1.5rem;text-align:right;" class="text-[10px] font-black uppercase tracking-widest text-gray-400">Attestation</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for payout in payouts %}
|
|
<tr style="border-bottom:1px solid #e5e7eb;" class="hover:bg-gray-50 transition-all">
|
|
<td style="padding:0.75rem 1.5rem;" class="text-xs font-mono text-gray-500">{{ payout.stripePayoutId }}</td>
|
|
<td style="padding:0.75rem 1.5rem;" class="text-sm font-bold">{{ payout.amountDecimal|number_format(2, ',', ' ') }} {{ payout.currency|upper }}</td>
|
|
<td style="padding:0.75rem 1.5rem;">
|
|
{% if payout.status == 'paid' %}
|
|
<span style="background:#d1fae5;border:2px solid #111827;padding:0.15rem 0.5rem;" class="text-xs font-black uppercase">{{ payout.status }}</span>
|
|
{% elseif payout.status == 'failed' or payout.status == 'canceled' %}
|
|
<span style="background:#fee2e2;border:2px solid #111827;padding:0.15rem 0.5rem;" class="text-xs font-black uppercase">{{ payout.status }}</span>
|
|
{% else %}
|
|
<span style="background:#fef3c7;border:2px solid #111827;padding:0.15rem 0.5rem;" class="text-xs font-black uppercase">{{ payout.status }}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td style="padding:0.75rem 1.5rem;" class="text-xs font-mono text-gray-500">{{ payout.destination ?? '—' }}</td>
|
|
<td style="padding:0.75rem 1.5rem;" class="text-sm text-gray-500">{{ payout.arrivalDate ? payout.arrivalDate|date('d/m/Y') : '—' }}</td>
|
|
<td style="padding:0.75rem 1.5rem;" class="text-sm text-gray-400">{{ payout.createdAt|date('d/m/Y H:i') }}</td>
|
|
<td style="padding:0.75rem 1.5rem;text-align:right;">
|
|
{% if payout.status == 'paid' %}
|
|
<a href="{{ path('app_account_payout_pdf', {id: payout.id}) }}" target="_blank" style="border:2px solid #111827;padding:0.3rem 0.5rem;background:#fabf04;display:inline-block;" class="text-xs font-black uppercase tracking-widest hover:bg-indigo-600 hover:text-black transition-all">PDF</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<div style="padding:3rem;text-align:center;">
|
|
<p class="text-gray-400 font-bold text-sm">Aucun virement pour le moment.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% elseif tab == 'settings' %}
|
|
<div style="border:4px solid #111827;box-shadow:6px 6px 0 rgba(0,0,0,1);background:white;padding:1.5rem;">
|
|
<h2 class="text-sm font-black uppercase tracking-widest" style="margin-bottom:1rem;">Parametres du compte</h2>
|
|
<form method="post" action="{{ path('app_account_settings') }}" enctype="multipart/form-data" style="display:flex;flex-direction:column;gap:1.5rem;">
|
|
<div style="display:flex;flex-wrap:wrap;gap:1.5rem;">
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_last_name" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Nom</label>
|
|
<input type="text" id="settings_last_name" name="last_name" value="{{ app.user.lastName }}" required
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;{{ isOrganizer ? 'background:#f3f4f6;' : '' }}"
|
|
{{ isOrganizer ? 'disabled' : '' }}>
|
|
</div>
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_first_name" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Prenom</label>
|
|
<input type="text" id="settings_first_name" name="first_name" value="{{ app.user.firstName }}" required
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;{{ isOrganizer ? 'background:#f3f4f6;' : '' }}"
|
|
{{ isOrganizer ? 'disabled' : '' }}>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="settings_email" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Email</label>
|
|
<input type="email" id="settings_email" name="email" value="{{ app.user.email }}" required
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;">
|
|
</div>
|
|
|
|
<div>
|
|
<label for="settings_phone" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Telephone</label>
|
|
<input type="tel" id="settings_phone" name="phone" value="{{ app.user.phone }}"
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;">
|
|
</div>
|
|
|
|
{% if not isOrganizer %}
|
|
<div>
|
|
<label for="settings_address" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Adresse</label>
|
|
<input type="text" id="settings_address" name="address" value="{{ app.user.address }}"
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;">
|
|
</div>
|
|
|
|
<div style="display:flex;flex-wrap:wrap;gap:1.5rem;">
|
|
<div style="flex:1;min-width:120px;">
|
|
<label for="settings_postal" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Code postal</label>
|
|
<input type="text" id="settings_postal" name="postal_code" value="{{ app.user.postalCode }}" maxlength="5"
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;">
|
|
</div>
|
|
<div style="flex:2;min-width:200px;">
|
|
<label for="settings_city" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.5rem;" class="font-black uppercase text-gray-400">Ville</label>
|
|
<input type="text" id="settings_city" name="city" value="{{ app.user.city }}"
|
|
style="width:100%;padding:0.75rem 1rem;border:3px solid #111827;font-weight:700;outline:none;">
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if isOrganizer %}
|
|
<div style="border:4px solid #111827;background:#fabf04;padding:1.5rem;">
|
|
<h3 style="font-size:10px;letter-spacing:0.1em;margin-bottom:1rem;" class="font-black uppercase">Logo de l'organisation</h3>
|
|
{% if app.user.logoName %}
|
|
<div style="margin-bottom:1rem;">
|
|
<img src="{{ ('/uploads/logos/' ~ app.user.logoName) | imagine_filter('organizer_logo') }}" alt="Logo" style="max-height:80px;border:2px solid #111827;">
|
|
</div>
|
|
{% endif %}
|
|
<input type="file" name="logo" accept="image/png,image/jpeg,image/webp"
|
|
style="padding:0.5rem;border:2px solid #111827;background:white;font-weight:700;width:100%;">
|
|
<p class="text-xs font-bold" style="margin-top:0.5rem;">PNG, JPEG ou WebP. Max 2 Mo.</p>
|
|
</div>
|
|
|
|
<div style="border:4px solid #111827;background:white;padding:1.5rem;">
|
|
<h3 style="font-size:10px;letter-spacing:0.1em;margin-bottom:1rem;" class="font-black uppercase text-gray-400">Reseaux sociaux & site internet</h3>
|
|
<div style="display:flex;flex-direction:column;gap:1rem;">
|
|
<div>
|
|
<label for="settings_website" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Site internet</label>
|
|
<input type="url" id="settings_website" name="website" value="{{ app.user.website ?? '' }}"
|
|
style="width:100%;padding:0.5rem 0.75rem;border:3px solid #111827;font-weight:700;outline:none;"
|
|
placeholder="https://mon-association.fr">
|
|
</div>
|
|
<div style="display:flex;flex-wrap:wrap;gap:1rem;">
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_facebook" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Facebook</label>
|
|
<input type="url" id="settings_facebook" name="facebook" value="{{ app.user.facebook ?? '' }}"
|
|
style="width:100%;padding:0.5rem 0.75rem;border:3px solid #111827;font-weight:700;outline:none;"
|
|
placeholder="https://facebook.com/...">
|
|
</div>
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_instagram" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">Instagram</label>
|
|
<input type="url" id="settings_instagram" name="instagram" value="{{ app.user.instagram ?? '' }}"
|
|
style="width:100%;padding:0.5rem 0.75rem;border:3px solid #111827;font-weight:700;outline:none;"
|
|
placeholder="https://instagram.com/...">
|
|
</div>
|
|
</div>
|
|
<div style="display:flex;flex-wrap:wrap;gap:1rem;">
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_twitter" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">X (Twitter)</label>
|
|
<input type="url" id="settings_twitter" name="twitter" value="{{ app.user.twitter ?? '' }}"
|
|
style="width:100%;padding:0.5rem 0.75rem;border:3px solid #111827;font-weight:700;outline:none;"
|
|
placeholder="https://x.com/...">
|
|
</div>
|
|
<div style="flex:1;min-width:200px;">
|
|
<label for="settings_tiktok" style="font-size:10px;letter-spacing:0.1em;display:block;margin-bottom:0.25rem;" class="font-black uppercase text-gray-400">TikTok</label>
|
|
<input type="url" id="settings_tiktok" name="tiktok" value="{{ app.user.tiktok ?? '' }}"
|
|
style="width:100%;padding:0.5rem 0.75rem;border:3px solid #111827;font-weight:700;outline:none;"
|
|
placeholder="https://tiktok.com/@...">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="border:4px solid #111827;background:#f9fafb;padding:1rem 1.5rem;">
|
|
<p class="text-xs font-bold text-gray-500">Les informations de votre organisation (raison sociale, SIRET, adresse) ne peuvent etre modifiees que par l'equipe E-Ticket. Contactez <a href="mailto:contact@e-cosplay.fr" class="text-indigo-600 hover:underline">contact@e-cosplay.fr</a> pour toute modification.</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div>
|
|
<button type="submit"
|
|
style="padding:0.75rem 2rem;border:3px solid #111827;box-shadow:4px 4px 0 rgba(0,0,0,1);background:#fabf04;cursor:pointer;"
|
|
class="font-black uppercase text-sm tracking-widest hover:bg-green-500 hover:text-black transition-all">
|
|
Enregistrer
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|