feat: mise en page de la page login et page accueil

This commit is contained in:
2026-03-23 18:43:32 +01:00
parent 1b5fd98527
commit ba84b49134
17 changed files with 421 additions and 836 deletions

View File

@@ -0,0 +1,65 @@
<nav class="bg-white border-b border-gris-clair shadow-sm py-4 px-6 sticky top-0 z-50 font-sora">
<div class="max-w-7xl mx-auto flex flex-col md:flex-row items-center justify-between gap-4">
<div class="flex flex-col md:flex-row items-center gap-4 md:gap-8 w-full md:w-auto">
<a href="{{ path('app_home') }}" class="flex items-center gap-2 transition-transform hover:scale-105">
<img src="{{ asset('img/logo.svg') }}" alt="Logo de l'association" class="h-10 w-auto object-contain">
</a>
<ul class="flex flex-wrap justify-center md:justify-start gap-2 md:gap-4">
{# Onglet : Mon profil #}
<li>
<a href="{{ path('app_user') }}"
class="px-4 py-2 text-sm font-semibold transition-colors block
{{ app.request.attributes.get('_route') == 'app_user'
? 'bg-bouton/20 border border-bouton text-text rounded-lg'
: 'text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent' }}">
Mon profil
</a>
</li>
{# Onglet : Mon offre #}
<li>
{# TODO : créer la route {{ path('app_offres') }} #}
<a href="#"
class="px-4 py-2 text-sm font-semibold transition-colors block text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent flex items-center gap-1">
Mon offre
</a>
</li>
{# Onglet : Gérer mes mots de passe #}
<li>
<a href="{{ path('app_user_edit_password') }}"
class="px-4 py-2 text-sm font-semibold transition-colors block
{{ app.request.attributes.get('_route') == 'app_user_edit_password'
? 'bg-bouton/20 border border-bouton text-text rounded-lg'
: 'text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent' }}">
Gérer mes mots de passe
</a>
</li>
{# Onglet : Mon organisation (ne s'affiche que si on a le rôle adéquat) #}
{% if is_granted('ROLE_ADMIN_ORGANISATION') %}
<li>
<a href="#"
class="px-4 py-2 text-sm font-semibold transition-colors block text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent">
Mon organisation
</a>
</li>
{% endif %}
</ul>
</div>
<div class="flex-shrink-0 mt-4 md:mt-0">
<a href="{{ path('app_logout') }}"
class="px-4 py-2 text-sm font-bold bg-danger text-white rounded-lg hover:bg-danger-hover transition-colors shadow flex items-center gap-2">
Se déconnecter
</a>
</div>
</div>
</nav>

View File

@@ -2,9 +2,13 @@
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% block title %}Association KAZ{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
<link rel="icon" href="{{ asset("img/logo.svg") }}">
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('styles/app.css') }}">
{% endblock %}
{% block javascripts %}
@@ -13,18 +17,46 @@
</head>
<body>
<main class="container mx-auto mt-4 px-4">
{# Section des notifications #}
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="p-4 mb-4 rounded-lg shadow-md border-l-4 {{ label == 'success' ? 'bg-brand-teal text-brand-dark border-bg-secondary' : 'bg-brand-gold text-brand-dark border-red-700' }}">
{{ message }}
{# entête du site #}
<header>
<div class="container">
{{ include('_navbar.html.twig') }}
</div>
</header>
{# contenu principal de chaque page #}
<main>
<div>
{% block body %}
{% endblock body %}
</div>
</main>
{# pied-de-page du site #}
<footer class="bg-white border-t border-gris-clair py-6 sm:py-8 mt-auto w-full font-sora">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center gap-4">
<div class="text-sm text-gris-fonce flex items-center gap-2 justify-center md:justify-start">
{# Logo de l'association #}
<img src="{{ asset('img/logo.svg') }}"
alt="Logo de l'association"
class="h-6 w-auto object-contain opacity-80 hover:opacity-100 transition-opacity">
{# Le texte et les liens #}
<span>
&copy; {{ 'now'|date('Y') }} | Kaz, le numérique sobre, libre, éthique et local.
</span>
</div>
{% endfor %}
{% endfor %}
{% block body %}{% endblock %}
</main>
<ul class="flex flex-wrap justify-center gap-4 sm:gap-6 text-sm text-gris-fonce">
<li>
<a href="https://kaz.bzh/mentions-legales/" class="hover:text-bouton transition-colors">Mentions légales et statuts</a>
</li>
<li>
<a href="https://status.kaz.bzh/status/kaz" class="hover:text-bouton transition-colors">Santé des services Kaz</a>
</li>
<li>
<a href="https://kaz.bzh/contact/" class="hover:text-bouton transition-colors">Contact</a>
</li>
</ul>
</div>
</footer>
</body>
</html>

View File

@@ -1 +0,0 @@
error404.html.twig

View File

@@ -1,78 +1,106 @@
{% extends 'base.html.twig' %}
{% block title %}Tableau de bord | Association KAZ{% endblock %}
{% block title %}Accueil | Association KAZ{% endblock %}
{% block body %}
<div class="min-h-screen bg-gray-50 py-8 w-full">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="min-h-screen bg-bg-primaire py-8 w-full font-sora">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
{# --- EN-TÊTE DU TABLEAU DE BORD --- #}
<div class="bg-white rounded-xl shadow-sm border border-gray-100 px-6 py-6 mb-8 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
<div>
<h1 class="text-2xl font-bold text-gray-900">Espace Adhérent KAZ</h1>
<p class="text-sm text-gray-500 mt-1">Bienvenue sur votre intranet associatif.</p>
{# Bloc "message d'accueil" #}
<h1 class="text-4xl font-caveat text-text mb-6 text-center sm:text-center">
Page d'accueil
</h1>
<div class="bg-white rounded-xl shadow-sm border border-gris-clair p-6 sm:p-8 mb-10">
<h2 class="text-xl font-bold text-title mb-4 text-center">
Bienvenue sur ton espace kaznaute <span class="text-bouton">{{ app.user ? app.user.userIdentifier : 'visiteur' }}</span> !
</h2>
{# Zone réservée pour les futures données de l'API #}
<div class="bg-bouton/10 border border-bouton/30 rounded-lg p-5">
<h3 class="font-semibold text-title mb-3 flex items-center gap-2">
Votre abonnement actuellement :
</h3>
<ul class="space-y-2 text-sm text-text">
<li class="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2">
<span class="font-semibold text-gris-fonce">Formule souscrite :</span>
{# TODO API : Remplacer par la vraie variable #}
<span class="italic opacity-70">Ajouter la vraie valeur</span>
</li>
<li class="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2">
<span class="font-semibold text-gris-fonce">Date de validité :</span>
{# TODO API : Remplacer par la vraie variable #}
<span class="italic opacity-70">Ajouter la vraie valeur</span>
</li>
</ul>
</div>
{% if app.user %}
<div class="flex items-center space-x-4">
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-sm font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
👤 {{ app.user.userIdentifier }}
</span>
<a href="{{ path('app_logout') }}" class="rounded-md bg-red-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 transition-colors duration-200">
Déconnexion
</a>
</div>
{% endif %}
</div>
{# --- GRILLE DES FONCTIONNALITÉS --- #}
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{# Carte 1 : Profil #}
<div class="bg-white overflow-hidden shadow-sm border border-gray-100 rounded-xl hover:shadow-md transition-shadow duration-200">
<div class="p-5">
<div class="flex items-center">
<div class="flex-shrink-0 bg-blue-600 rounded-lg p-3">
<span class="text-2xl">📋</span>
</div>
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 truncate">Mon Profil</dt>
<dd class="text-lg font-semibold text-gray-900">Gérer mes informations</dd>
</dl>
</div>
</div>
</div>
<div class="bg-gray-50 px-5 py-3 border-t border-gray-100">
<div class="text-sm">
<a href="#" class="font-medium text-blue-600 hover:text-blue-500">Voir mon profil &rarr;</a>
</div>
</div>
</div>
{# Bloc "que souhaitez-vous faire ?" #}
<h2 class="text-2xl font-bold text-title mb-6 text-center sm:text-left">
Que souhaitez-vous faire ?
</h2>
{# Gestion du responsive #}
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
{# Carte 2 : Mon abonnement KAZ #}
<div class="bg-white overflow-hidden shadow-sm border border-gray-100 rounded-xl hover:shadow-md transition-shadow duration-200">
<div class="p-5">
<div class="flex items-center">
<div class="flex-shrink-0 bg-green-500 rounded-lg p-3">
<span class="text-2xl">💳</span>
</div>
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 truncate">Mon abonnement KAZ</dt>
<dd class="text-lg font-semibold text-gray-900">À jour</dd>
</dl>
</div>
</div>
{# LIGNE 1 : Profil & Offre #}
<a href="{{ path('app_user')|default('#') }}" class="group flex items-center p-5 bg-white border border-gris-clair rounded-xl shadow-sm hover:shadow-md hover:border-bouton transition-all duration-200">
<div class="flex-shrink-0 bg-blue-50 text-blue-600 rounded-lg p-3 group-hover:bg-blue-600 group-hover:text-white transition-colors">
<span class="text-2xl block">👤</span>
</div>
<div class="bg-gray-50 px-5 py-3 border-t border-gray-100">
<div class="text-sm">
<a href="#" class="font-medium text-green-600 hover:text-green-500">Voir l'historique &rarr;</a>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-title group-hover:text-bouton transition-colors">Mon Profil</h3>
<p class="text-sm text-gris-fonce">Consulter et modifier mes informations</p>
</div>
</div>
</a>
<a href="#" class="group flex items-center p-5 bg-white border border-gris-clair rounded-xl shadow-sm hover:shadow-md hover:border-bouton transition-all duration-200">
<div class="flex-shrink-0 bg-green-50 text-green-600 rounded-lg p-3 group-hover:bg-green-600 group-hover:text-white transition-colors">
<span class="text-2xl block">💳</span>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-title group-hover:text-bouton transition-colors">Mon Offre</h3>
<p class="text-sm text-gris-fonce">Gérer mon adhésion KAZ</p>
</div>
</a>
{# LIGNE 2 : Sécurité & Organisation/Contact #}
<a href="{{ path('app_user_edit_password') }}" class="group flex items-center p-5 bg-white border border-gris-clair rounded-xl shadow-sm hover:shadow-md hover:border-bouton transition-all duration-200">
<div class="flex-shrink-0 bg-orange-50 text-orange-600 rounded-lg p-3 group-hover:bg-orange-600 group-hover:text-white transition-colors">
<span class="text-2xl block">🔒</span>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-title group-hover:text-bouton transition-colors">Sécurité</h3>
<p class="text-sm text-gris-fonce">Modifier mes mots de passe</p>
</div>
</a>
{# Si la personne gère une asso, on montre l'organisation. Sinon, un bouton Contact pour garder la grille de 6 éléments équilibrée #}
{% if is_granted('ROLE_ADMIN_ORGANISATION') %}
<a href="#" class="group flex items-center p-5 bg-white border border-bouton/30 rounded-xl shadow-sm hover:shadow-md hover:border-bouton transition-all duration-200">
<div class="flex-shrink-0 bg-bouton/20 text-bouton rounded-lg p-3 group-hover:bg-bouton group-hover:text-white transition-colors">
<span class="text-2xl block">🏢</span>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-title group-hover:text-bouton transition-colors">Mon Organisation</h3>
<p class="text-sm text-gris-fonce">Espace de gestion du bureau</p>
</div>
</a>
{% else %}
<a href="https://kaz.bzh/contact/" class="group flex items-center p-5 bg-white border border-gris-clair rounded-xl shadow-sm hover:shadow-md hover:border-bouton transition-all duration-200">
<div class="flex-shrink-0 bg-purple-50 text-purple-600 rounded-lg p-3 group-hover:bg-purple-600 group-hover:text-white transition-colors">
<span class="text-2xl block">✉️</span>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-title group-hover:text-bouton transition-colors">Nous contacter</h3>
<p class="text-sm text-gris-fonce">Besoin d'aide ou d'assistance ?</p>
</div>
</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,34 +1,92 @@
{% extends 'base.html.twig' %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page de connexion | Association KAZ</title>
{% block title %}Se connecter | {{ parent() }}{% endblock %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
</head>
{% block body %}
<form method="post">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<body class="min-h-screen bg-bg-primaire font-sora text-text flex flex-col justify-between items-center p-4 sm:p-8">
<div class="flex-none"></div>
<main class="w-full max-w-md bg-white p-8 rounded-xl shadow-lg border border-gris-clair">
{% if app.user %}
<div class="mb-3">
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ logout_path() }}">Logout</a>
</div>
{% endif %}
<header class="flex justify-center mb-6">
<img src="{{ asset('img/logo.svg') }}"
alt="Logo association"
class="h-16 md:h-24 w-auto object-contain">
</header>
<h1 class="h3 mb-3 font-weight-normal">Se connecter à mon tableau de bord KAZ</h1>
<label for="inputEmail">Email :</label>
<input type="email" value="{{ last_username }}" name="_username" id="inputEmail" class="form-control" autocomplete="email" required autofocus>
<label for="inputPassword">Mot de passe : </label>
<input type="password" name="_password" id="inputPassword" class="form-control" autocomplete="current-password" required>
<input type="hidden" name="_csrf_token" data-controller="csrf-protection" value="{{ csrf_token('authenticate') }}">
<h1 class="text-4xl text-center mb-8 font-caveat text-text">Se connecter</h1>
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Se souvenir de moi
</label>
</div>
{% if error %}
<div class="bg-danger/10 border border-danger text-danger px-4 py-3 rounded-lg mb-6 text-sm" role="alert">
{{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}
<button class="btn btn-lg btn-primary" type="submit">
Se connecter
</button>
</form>
{% endblock %}
<form method="post" class="space-y-5">
{# ajout du token csrf pour 2 fois plus de plaisir en toute sécurité #}
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
{# champ adresse-mail #}
<div class="space-y-1">
<label for="username" class="block text-sm font-semibold text-text">
Adresse-mail :
</label>
<input type="email" value="{{ last_username }}" name="_username" id="username"
class="w-full px-4 py-3 border border-gris-clair rounded-lg focus:outline-none focus:border-bouton focus:ring-1 focus:ring-bouton placeholder-gris-moyen transition-shadow"
placeholder="Saisissez votre e-mail" required autofocus autocomplete="email">
</div>
{# champ "mot de passe" #}
<div class="space-y-1">
<label for="password" class="block text-sm font-semibold text-text">
Mot de passe :
</label>
<input type="password" name="_password" id="password"
class="w-full px-4 py-3 border border-gris-clair rounded-lg focus:outline-none focus:border-bouton focus:ring-1 focus:ring-bouton placeholder-gris-moyen transition-shadow"
placeholder="Saisissez votre mot de passe" required autocomplete="current-password">
</div>
{# checkbox "se souvenir de moi" #}
<div class="flex items-center pt-1">
<input type="checkbox" name="_remember_me" id="remember_me"
class="w-4 h-4 text-bouton border-gris-clair rounded focus:ring-bouton cursor-pointer">
<label for="remember_me" class="ml-2 text-sm text-gris-fonce cursor-pointer select-none">
Se souvenir de moi
</label>
</div>
<div class="flex flex-col sm:flex-row gap-4 pt-2">
<button type="submit"
class="flex-1 py-3 bg-bouton hover:bg-bouton-hover text-text font-bold rounded-lg shadow transition-colors">
Se connecter
</button>
<a href="https://kaz.bzh/offres/"
target="_blank"
rel="noopener noreferrer"
class="flex-1 flex items-center justify-center py-3 border border-gris-moyen text-text hover:bg-gris-clair font-bold rounded-lg transition-colors text-center">
M'inscrire
</a>
</div>
<div class="text-center pt-4">
{# TODO : faire route vers mot de passe oublié #}
<a href="#"
class="text-sm font-semibold text-title hover:text-bouton transition-colors">
Mot de passe oublié ?
</a>
</div>
</form>
</main>
<footer class="mt-8 text-center text-sm text-gris-fonce w-full">
&copy; {{ 'now'|date('Y') }} | Kaz, le numérique sobre, libre, éthique et local.
</footer>
</body>
</html>

View File

@@ -1,7 +1,6 @@
{# templates/user/edit_password.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Modifier mon mot de passe | {{ parent() }}{% endblock %}
{% block title %}Modifier mes mots de passe | {{ parent() }}{% endblock %}
{% block body %}
<div class="min-h-screen bg-bg-primary flex items-center justify-center p-4">
@@ -20,7 +19,7 @@
{{ form_errors(form.oldPassword) }}
</div>
{# Champs Nouveau Mot de Passe (RepeatedType) #}
{# Champs Nouveau Mot de Passe #}
<div class="space-y-4">
{{ form_row(form.newPassword.first, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-brand-teal outline-none'}}) }}
{{ form_row(form.newPassword.second, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-brand-teal outline-none'}}) }}
@@ -34,4 +33,4 @@
</div>
</div>
{% endblock %}
{% endblock %}