Payout system:
- Create Payout entity (stripePayoutId, status, amount, currency, destination, arrivalDate)
- Webhook handles payout.created/updated/paid/failed/canceled with email notification
- Payout list in /mon-compte virements tab with status badges
- PDF attestation on paid payouts with email attachment
PDF attestation:
- dompdf with DejaVu Sans font, yellow-orange gradient background
- Orange centered title bar, E-Cosplay logo, emitter/beneficiary info blocks
- QR code linking to /attestation/check/{payoutId} for authenticity verification
- Public verification page: shows payout details if valid, error if altered
- Legal disclaimer and CGV reference
- Button visible only when status is paid, opens in new tab
Sub-accounts:
- Add parentOrganizer (self-referencing ManyToOne) and subAccountPermissions (JSON) to User
- Permissions: scanner (validate tickets), events (CRUD), tickets (free invitations)
- Create sub-account with random password, send email with credentials
- Edit page with name/email/permissions checkboxes
- Delete with confirmation
- hasPermission() helper method
Account improvements:
- Block entire page for unapproved organizers with validation pending message
- Display stripeStatus in Stripe Connect banners
- Remove test payout button
Webhook v2 Connect events:
- v2.core.account.created/updated/closed → update stripeStatus
- capability_status_updated → sync charges/payouts enabled from capabilities
- PayoutPdfService for reusable PDF generation
Migrations: stripeStatus, Payout table, sub-account fields, drop pdfPath
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
350 lines
28 KiB
Twig
350 lines
28 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') }}" 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:#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 %}
|