Files
ludikevent_crm/templates/dashboard/customer.twig

175 lines
11 KiB
Twig
Raw Normal View History

{% extends 'dashboard/base.twig' %}
{% block title %}Gestion Clients{% endblock %}
{% block title_header %}Annuaire <span class="text-blue-500">Clients</span>{% endblock %}
{% block actions %}
<div class="flex items-center space-x-3">
<a href="{{ path('app_crm_customer_add') }}" class="flex items-center space-x-2 px-6 py-3 bg-blue-600 hover:bg-blue-500 text-white text-[10px] font-black uppercase tracking-[0.2em] rounded-xl transition-all shadow-lg shadow-blue-600/20 group">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M12 4v16m8-8H4" />
</svg>
<span>Nouveau Client</span>
</a>
</div>
{% endblock %}
{% block body %}
<div class="w-full backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] shadow-2xl overflow-hidden">
{# HEADER TABLEAU #}
<div class="px-8 py-6 border-b border-white/5 bg-white/5 flex items-center justify-between">
<div>
<h2 class="text-xl font-bold text-white tracking-tight">Liste des clients</h2>
<p class="text-[10px] text-slate-500 font-bold uppercase tracking-widest mt-1">Base de données centralisée</p>
</div>
<span class="px-4 py-1.5 bg-blue-500/10 text-blue-400 text-[10px] font-black uppercase rounded-lg border border-blue-500/20">
{{ customers|length }} CONTACTS
</span>
</div>
<div class="overflow-x-auto custom-scrollbar">
<table class="w-full text-left border-collapse">
<thead>
<tr class="bg-slate-900/40 border-b border-white/5">
<th class="px-8 py-5 text-[10px] font-black text-slate-500 uppercase tracking-widest">Identité</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-500 uppercase tracking-widest text-center">Type</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-500 uppercase tracking-widest">Coordonnées</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-500 uppercase tracking-widest">SIRET / ID</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-500 uppercase tracking-widest text-right">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-white/5">
{% for customer in customers %}
<tr class="hover:bg-white/5 transition-all group">
{# 1. IDENTITÉ #}
<td class="px-8 py-6 whitespace-nowrap">
<div class="flex items-center">
{# Avatar avec initiales #}
<div class="h-10 w-10 rounded-xl bg-gradient-to-br from-slate-700 to-slate-800 flex flex-shrink-0 items-center justify-center text-white font-black text-xs border border-white/10 shadow-lg">
{{ customer.surname|first|upper }}{{ customer.name|first|upper }}
</div>
<div class="ml-4">
{# Nom et Civilité #}
<div class="text-sm font-bold text-white">
<span class="text-slate-500 text-[10px] uppercase mr-1">{{ customer.civ }}</span>
{{ customer.surname|upper }} {{ customer.name }}
</div>
{# ID Interne et État Stripe #}
<div class="flex items-center mt-1 space-x-2">
{# Badge ID Interne #}
<span class="text-[9px] font-bold text-slate-500 tracking-tighter">
ID: #{{ customer.id }}
</span>
{% if customer.customerId %}
{# ÉTAT : SYNCHRONISÉ (VERT) #}
<div class="flex items-center text-[8px] font-black text-emerald-400 uppercase tracking-[0.1em] bg-emerald-500/10 px-2 py-0.5 rounded-md border border-emerald-500/30 shadow-sm shadow-emerald-500/10">
<span class="flex h-1.5 w-1.5 rounded-full bg-emerald-500 mr-2"></span>
Stripe synchronisé
</div>
{% else %}
{# ÉTAT : NON SYNCHRONISÉ (ROUGE) #}
<div class="flex items-center text-[8px] font-black text-rose-500 uppercase tracking-[0.1em] bg-rose-500/10 px-2 py-0.5 rounded-md border border-rose-500/30 shadow-sm shadow-rose-500/10">
<span class="flex h-1.5 w-1.5 rounded-full bg-rose-500 mr-2 animate-pulse"></span>
Stripe non synchronisé
</div>
{% endif %}
</div>
</div>
</div>
</td>
{# 2. TYPE (Badge dynamique) #}
<td class="px-8 py-6 text-center">
{% set typeStyles = {
'company': 'bg-purple-500/10 text-purple-400 border-purple-500/20',
'personal': 'bg-sky-500/10 text-sky-400 border-sky-500/20',
'association': 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',
'mairie': 'bg-amber-500/10 text-amber-400 border-amber-500/20'
} %}
<span class="px-3 py-1 rounded-lg text-[9px] font-black border uppercase tracking-widest {{ typeStyles[customer.type] ?? 'bg-slate-500/10 text-slate-400' }}">
{{ customer.type|default('Indéfini') }}
</span>
</td>
{# 3. COORDONNÉES #}
<td class="px-8 py-6">
<div class="flex flex-col space-y-1">
<div class="flex items-center text-slate-300 text-xs">
<svg class="w-3.5 h-3.5 mr-2 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>
{{ customer.email }}
</div>
<div class="flex items-center text-slate-400 text-[11px] font-mono">
<svg class="w-3.5 h-3.5 mr-2 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" /></svg>
{{ customer.phone }}
</div>
</div>
</td>
{# 4. SIRET #}
<td class="px-8 py-6">
{% if customer.siret %}
<div class="text-[10px] font-mono text-slate-500 bg-black/20 px-2 py-1 rounded border border-white/5 inline-block">
{{ customer.siret }}
</div>
{% else %}
<span class="text-[10px] text-slate-600 italic">N/A</span>
{% endif %}
</td>
{# 5. ACTIONS #}
<td class="px-8 py-6 text-right">
<div class="flex items-center justify-end space-x-2">
<a href="#" class="p-2 text-slate-400 hover:text-blue-400 hover:bg-blue-400/10 rounded-lg transition-all" title="Modifier">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" /></svg>
</a>
<a href="#" class="p-2 text-slate-400 hover:text-white hover:bg-white/10 rounded-lg transition-all" title="Voir fiche">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" /></svg>
</a>
</div>
</td>
</tr>
{% else %}
<tr>
<td colspan="5" class="px-8 py-20 text-center italic text-slate-500 font-medium">
Aucun client enregistré dans la base.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{# PAGINATION #}
<div class="px-8 py-8 bg-black/20 border-t border-white/5">
<div class="flex flex-col md:flex-row items-center justify-between gap-6">
<div class="text-[10px] font-black text-slate-500 uppercase tracking-[0.2em]">
Affichage de {{ customers.getItemNumberPerPage }} clients par page
</div>
<div class="navigation custom-pagination">
{{ knp_pagination_render(customers) }}
</div>
</div>
</div>
</div> {# Fin du conteneur principal #}
{# CSS pour styliser KnpPagination aux couleurs de ton dashboard #}
<style>
.custom-pagination nav ul { @apply flex space-x-2; }
.custom-pagination nav ul li span,
.custom-pagination nav ul li a {
@apply px-4 py-2 rounded-xl bg-white/5 border border-white/5 text-slate-400 text-xs font-bold transition-all;
}
.custom-pagination nav ul li.active span {
@apply bg-blue-600 border-blue-500 text-white shadow-lg shadow-blue-600/20;
}
.custom-pagination nav ul li a:hover {
@apply bg-white/10 text-white border-white/20;
}
</style>
{% endblock %}