✨ feat(dashboard/profil): Ajoute la page de profil utilisateur Ajoute la page de profil utilisateur avec formulaire de mot de passe, gestion 2FA, et déconnexion. ✅ feat(AuditLogRepository): Améliore requête logs avec sécurité et filtre Améliore la requête des logs en appliquant les restrictions de sécurité et le filtrage optionnel par compte. ➕ feat(ProfilsController): Crée le contrôleur des profils utilisateurs Crée le contrôleur des profils utilisateurs pour gérer la sécurité du compte (2FA et mot de passe). 🎨 feat(dashboard/audit_logs): Améliore l'interface des journaux d'audit Améliore l'interface des journaux d'audit avec filtre par compte et design plus moderne. ```
150 lines
10 KiB
Twig
150 lines
10 KiB
Twig
{% extends 'dashboard/base.twig' %}
|
|
|
|
{% block title %}Mon Profil{% endblock %}
|
|
{% block title_header %}Paramètres du <span class="text-blue-500">Compte</span>{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="relative min-h-screen">
|
|
{# Orbes décoratifs en arrière-plan pour révéler le glassmorphism #}
|
|
<div class="absolute -top-24 -left-20 w-72 h-72 bg-blue-600/10 rounded-full blur-[120px] -z-10 pointer-events-none"></div>
|
|
<div class="absolute bottom-20 right-0 w-96 h-96 bg-indigo-600/5 rounded-full blur-[130px] -z-10 pointer-events-none"></div>
|
|
|
|
<div class="max-w-5xl space-y-8 relative z-10">
|
|
|
|
{# 1. CARTE PROFIL PRINCIPALE (IDENTITÉ) #}
|
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] p-10 shadow-2xl">
|
|
<div class="flex flex-col md:flex-row items-center gap-10">
|
|
{# Avatar #}
|
|
<div class="relative group">
|
|
<div class="w-32 h-32 rounded-[2.5rem] bg-blue-600 flex items-center justify-center text-white text-5xl font-black shadow-2xl shadow-blue-500/20 group-hover:rotate-3 transition-transform duration-500">
|
|
{{ user.firstName|first|upper }}
|
|
</div>
|
|
<div class="absolute -bottom-2 -right-2 w-10 h-10 bg-emerald-500 border-4 border-[#1e293b] rounded-full shadow-lg" title="Compte Actif"></div>
|
|
</div>
|
|
|
|
{# Infos textuelles #}
|
|
<div class="flex-1 text-center md:text-left">
|
|
<div class="flex flex-wrap items-center justify-center md:justify-start gap-3 mb-2">
|
|
<h2 class="text-3xl font-black text-white uppercase tracking-tighter">
|
|
{{ user.firstName }} {{ user.name|default('') }}
|
|
</h2>
|
|
<span class="px-3 py-1 bg-blue-500/10 border border-blue-500/20 rounded-lg text-blue-400 text-[10px] font-black uppercase tracking-widest">
|
|
{{ user.roles[0]|replace({'ROLE_': ''}) }}
|
|
</span>
|
|
</div>
|
|
<p class="text-slate-400 font-medium mb-6">{{ user.email }}</p>
|
|
|
|
<div class="flex flex-wrap justify-center md:justify-start gap-4">
|
|
<div class="bg-white/5 border border-white/5 px-4 py-2 rounded-xl text-center">
|
|
<p class="text-[9px] text-slate-500 uppercase font-black tracking-widest mb-1">Identifiant</p>
|
|
<p class="text-xs font-mono text-white">#{{ user.id }}</p>
|
|
</div>
|
|
<div class="bg-white/5 border border-white/5 px-4 py-2 rounded-xl text-center">
|
|
<p class="text-[9px] text-slate-500 uppercase font-black tracking-widest mb-1">Dernière connexion</p>
|
|
<p class="text-xs text-white uppercase font-bold tracking-tighter">Aujourd'hui</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 items-start">
|
|
|
|
{# 2. COLONNE GAUCHE : FORMULAIRE SÉCURITÉ #}
|
|
<div class="backdrop-blur-xl bg-white/5 border border-white/5 p-8 rounded-[2.5rem] shadow-xl">
|
|
<div class="flex items-center space-x-4 mb-8">
|
|
<div class="w-12 h-12 bg-blue-600/10 rounded-2xl flex items-center justify-center text-blue-500 border border-blue-500/20">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-white font-bold text-lg">Sécurité</h3>
|
|
<p class="text-slate-500 text-[10px] uppercase font-bold tracking-[0.2em]">Changer le mot de passe</p>
|
|
</div>
|
|
</div>
|
|
|
|
{{ form_start(formPassword) }}
|
|
<div class="space-y-5 password-form-custom">
|
|
{% for row in formPassword %}
|
|
{% if row.vars.name != '_token' %}
|
|
<div class="space-y-1">
|
|
{{ form_label(row, null, {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-2'}}) }}
|
|
{{ form_widget(row, {'attr': {'class': 'w-full px-5 py-4 bg-slate-900/50 border border-white/10 rounded-2xl text-white text-sm focus:border-blue-600 focus:ring-0 transition-all outline-none placeholder:text-slate-700'}}) }}
|
|
<div class="text-red-500 text-[9px] font-bold uppercase tracking-tighter mt-1 ml-2">
|
|
{{ form_errors(row) }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
<button type="submit" class="w-full mt-4 py-4 bg-blue-600 hover:bg-blue-700 text-white text-[10px] font-black uppercase tracking-[0.3em] rounded-2xl shadow-lg shadow-blue-600/20 transition-all duration-300">
|
|
Mettre à jour les accès
|
|
</button>
|
|
</div>
|
|
{{ form_end(formPassword) }}
|
|
</div>
|
|
|
|
{# 3. COLONNE DROITE : 2FA & SESSION #}
|
|
<div class="space-y-8">
|
|
{# AUTHENTIFICATION 2FA #}
|
|
<div class="backdrop-blur-xl bg-white/5 border border-white/5 p-8 rounded-[2.5rem] shadow-xl group transition-all duration-500">
|
|
<div class="flex items-center justify-between mb-8">
|
|
<div class="flex items-center space-x-4">
|
|
<div class="h-12 w-12 rounded-2xl bg-indigo-500/10 flex items-center justify-center text-indigo-500 border border-indigo-500/20 group-hover:scale-110 transition-transform duration-500">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-white font-bold text-lg tracking-tight">Authentification 2FA</h4>
|
|
<p class="text-[10px] uppercase font-bold tracking-[0.2em] mt-1">
|
|
{% if user.googleAuthenticatorSecret %}
|
|
<span class="text-emerald-500 animate-pulse">● Activée</span>
|
|
{% else %}
|
|
<span class="text-rose-500">○ Désactivée</span>
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="text-slate-400 text-xs mb-8 leading-relaxed font-medium">
|
|
Ajoutez une couche de protection en utilisant une application comme Google Authenticator pour valider vos connexions.
|
|
</p>
|
|
|
|
<a href="{{ path('app_crm_profils', {act: user.googleAuthenticatorSecret ? 'disable2fa' : 'sendLink2faenable'}) }}"
|
|
class="flex items-center justify-center w-full py-4 {% if user.googleAuthenticatorSecret %}bg-white/5 hover:bg-rose-600 text-slate-300 hover:text-white border-white/10 hover:border-rose-600{% else %}bg-indigo-600 hover:bg-indigo-700 text-white shadow-lg shadow-indigo-600/20 border-transparent{% endif %} border rounded-2xl text-[10px] font-black uppercase tracking-[0.3em] transition-all duration-300">
|
|
<span>{{ user.googleAuthenticatorSecret ? 'Désactiver la protection' : 'Envoyer le lien d\'activation' }}</span>
|
|
</a>
|
|
</div>
|
|
|
|
{# FERMETURE DE SESSION #}
|
|
<div class="backdrop-blur-xl bg-rose-500/5 border border-rose-500/10 p-8 rounded-[2.5rem] hover:bg-rose-500/10 transition-colors group">
|
|
<div class="w-12 h-12 bg-rose-500/10 rounded-2xl flex items-center justify-center text-rose-500 mb-6 group-hover:scale-110 transition-transform">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-white font-bold text-lg mb-2">Session Intranet</h3>
|
|
<p class="text-slate-400 text-sm mb-6 leading-relaxed">Déconnectez-vous pour fermer vos accès sur cet appareil et sécuriser vos données.</p>
|
|
<a href="{{ path('app_logout') }}" class="block text-center w-full py-4 bg-rose-500/20 hover:bg-rose-600 text-rose-500 hover:text-white text-[10px] font-black uppercase tracking-[0.3em] rounded-2xl border border-rose-500/20 transition-all">
|
|
Se déconnecter
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.password-form-custom ul {
|
|
@apply text-red-500 text-[9px] font-bold uppercase tracking-tighter mt-1 ml-2;
|
|
}
|
|
.backdrop-blur-xl {
|
|
background-image: radial-gradient(rgba(255,255,255,0.02) 1px, transparent 0);
|
|
background-size: 8px 8px;
|
|
}
|
|
</style>
|
|
{% endblock %}
|