Aller au contenu

Pages de connexion et accueil de la plateforme

Cette page explique pourquoi les pages de connexion et l'accueil public de Kirexo se présentent comme ils le font une fois habillés au design system : un flux de connexion en deux étapes posé en plein écran, une distinction visuelle nette entre l'espace utilisateur et l'espace d'administration, et un accueil qui change de visage selon qu'il existe ou non des articles publiés. Elle ne décrit pas la mécanique d'authentification elle-même — pour ça, voir Architecture des firewalls et le how-to Se connecter à Kirexo. Pour le design system lui-même (tokens, thème, accent), voir l'explication Pourquoi un accent d'instance piloté serveur et la Référence du design system.

Le flux de connexion, inchangé mais réhabillé

Le mécanisme de connexion email-first — saisir son email, puis seulement après voir apparaître le champ mot de passe — existe depuis l'étape 5. L'habillage au design system ne change rien à ce mécanisme : le Live Component App\Twig\Components\EmailFirstLogin (src/Twig/Components/EmailFirstLogin.php) est conservé tel quel. Validation de l'email, anti-énumération (un email inconnu ne révèle rien), protection CSRF, « rester connecté », lien « mot de passe oublié » : tout ce comportement reste identique. Seuls les templates changent.

Pourquoi ne toucher qu'à la présentation ? Parce que le comportement de connexion est déjà correct et déjà couvert par des tests. Le réhabiller en réécrivant le composant PHP introduirait du code de production à re-tester sans aucun gain fonctionnel — et risquerait, au passage, de casser le binding AJAX du Live Component (les LiveAction checkEmail / resetEmail, les props, l'élément racine <div {{ attributes }}> ancre du re-render). La frontière a donc été tracée nettement : le design system habille, il ne réécrit pas la logique.

Concrètement, l'utilisateur perçoit toujours les deux mêmes étapes :

  1. Étape email — il saisit son adresse ; un email vide ou mal formé le maintient à cette étape avec un message neutre.
  2. Étape mot de passe — une fois l'email validé, le champ mot de passe apparaît, avec le lien « mot de passe oublié ». Un lien « Modifier l'email » (l'action resetEmail) permet de revenir à l'étape précédente.

La soumission finale part vers le firewall Symfony (/login_check ou /admin/login_check), hors du composant. Ce déroulé est détaillé côté utilisateur dans Se connecter à Kirexo.

La connexion en plein écran : une page, pas un encart

Avant l'habillage, les pages de login s'inséraient dans les layouts applicatifs (un layout « épuré » côté user, « sobre » côté admin). Le design system les pose désormais en plein écran : templates/login/index.html.twig et templates/admin/login/index.html.twig étendent directement base.html.twig (et non plus un layout porteur de header), et placent un conteneur lg-wrap à deux colonnes directement dans le <body>.

Ce choix du plein écran répond à l'intention de la page. Se connecter n'est pas une action « dans » l'application : c'est le seuil par lequel on y entre. Une page de login ne doit donc pas afficher la barre de navigation, les liens d'espace ou les éléments d'une session qui n'existe pas encore. La supprimer concentre l'attention sur le seul geste attendu — s'identifier — et évite d'exposer une coquille d'interface vide ou trompeuse à un visiteur non authentifié.

Les deux colonnes du lg-wrap séparent motivation et action :

  • un aside (lg-aside) qui porte l'identité de marque et un message d'accroche ;
  • une carte (lg-main / lg-card) qui contient le titre, un sous-titre, d'éventuels messages flash, et le composant EmailFirstLogin.

Le landmark #main — cible du lien d'évitement du design system — est posé sur la colonne lg-main, de sorte que la navigation clavier saute directement au formulaire et non à l'argumentaire de l'aside.

Distinguer l'espace utilisateur de l'espace administrateur, dès le login

Kirexo sépare deux espaces qui n'ont pas le même rôle : l'espace utilisateur, où l'on écrit et publie ses articles, et l'espace d'administration, qui gère les comptes mais jamais le contenu (voir Architecture des firewalls). Cette séparation existe déjà côté sécurité — deux firewalls, deux sessions. Le design system la rend immédiatement lisible à l'œil, dès la page de connexion.

Côté utilisateur : une page qui motive à écrire

La page /login met en avant l'usage de la plateforme. Son aside affiche le wordmark Kirexo, une accroche (« Écrire une fois, diffuser partout. ») et des chips rappelant les canaux de diffusion (Web, RSS, ActivityPub). Le ton est celui d'un outil d'écriture : on rappelle au visiteur pourquoi il revient se connecter — reprendre l'écriture — avant de lui demander ses identifiants. C'est cohérent avec l'esprit « éditeur de texte » revendiqué pour l'espace utilisateur.

Côté administrateur : l'identité back-office, visible immédiatement

La page /admin/login affiche au contraire, dès l'arrivée, l'identité de l'espace d'administration : son aside porte la coque sombre lg-aside bo-side, un bloc de marque bo-brand et surtout un tag « ADMIN ». Le ton est sobre et signale une zone réservée (« Gestion des comptes et de la plateforme. L'accès est strictement réservé aux administrateurs. »).

Pourquoi rendre l'ambiance admin visible avant même la connexion ? Parce que la page de login admin n'est pas un détail périphérique : c'est le premier écran de l'espace d'administration. Un administrateur qui atterrit sur /admin/login doit savoir d'un coup d'œil qu'il est au bon endroit — et qu'il n'est plus dans l'interface d'écriture. La distinction visuelle est un repère, pas une décoration.

Préfixe bo-, jamais ad-

Les classes propres au back-office utilisent le préfixe bo- (bo-side, bo-brand…), jamais ad- : un préfixe ad- est fréquemment bloqué par les bloqueurs de publicité, ce qui casserait silencieusement le style de l'admin. Cette convention est détaillée dans la Référence du design system.

Cette discrétion visuelle ne remplace pas la discrétion technique : pour un visiteur déjà connecté à l'espace utilisateur, /admin/login renvoie carrément un 404 — l'admin se masque entièrement. C'est un mécanisme distinct, expliqué dans Masquer l'admin : 404 plutôt que 403. L'habillage bo- ne concerne que ce qu'un visiteur légitime (anonyme ou administrateur) voit sur la page.

L'accueil de la plateforme : deux états selon le contenu

L'accueil public (/, route app_home, servie par src/Controller/AppHomeController.php) a deux visages, selon qu'il existe ou non des articles publiés. Ce n'est pas une coquetterie : une plateforme fraîchement installée et une plateforme vivante n'ont pas le même besoin.

État vide : inviter à écrire le premier article

Quand aucun article n'est publié, l'accueil affiche un écran d'invitation : un titre (« Votre carnet est prêt. »), un texte d'incitation, un bouton principal « Écrire le premier article », et trois étapes d'onboarding indicatives. Une plateforme vide ne doit pas afficher une liste vide — un trou — mais orienter vers la seule action qui a du sens à ce stade : écrire.

Un détail important : le bouton « Écrire le premier article » pointe vers l'accueil de l'espace utilisateur (/u, route app_user_home), pas vers un éditeur. La rédaction d'articles façon WriteFreely est une étape future ; à ce stade, le chemin vers l'écriture passe par l'espace utilisateur. Le CTA incite sans promettre une page qui n'existe pas encore.

État rempli : le fil des articles publiés

Dès qu'au moins un article est publié, l'accueil bascule sur le fil des articles : un masthead (titre de la plateforme) suivi de la liste des articles publiés, du plus récent au plus ancien. Chaque article affiche son titre, son extrait, sa date de publication et ses canaux de diffusion (Web, RSS, Mastodon/ActivityPub, API).

À ce stade, les titres d'articles sont des liens inertes : il n'existe pas encore de page article dédiée (étape future). Le fil donne à voir l'activité de la plateforme sans pouvoir encore mener à la lecture complète d'un article.

Pourquoi un service synchrone et pas un bus

Le choix « vide vs liste » se décide entièrement à partir d'une donnée : la liste des articles publiés. Le controller la récupère via un service applicatif synchrone, App\Service\Article\ArticleFeedProvider (src/Service/Article/ArticleFeedProvider.php), qui délègue à ArticleRepositoryInterface::findPublished(). La chaîne est controller → service → repository, sans bus Messenger.

C'est l'application directe du pattern 1 de Kirexo : la logique de lecture interne (rendu d'une page, d'un dashboard) passe par des services synchrones injectés, pas par un query bus. Le bus Messenger est réservé à l'asynchrone réel (diffusion découplée d'un article publié vers les plugins, via RabbitMQ) ou aux routes dédiées de type API. Afficher l'accueil n'est ni l'un ni l'autre : c'est une lecture, immédiate, dans le cycle de la requête. Le raisonnement général est posé dans Architecture.

Le controller reste volontairement fin : il ne calcule rien. La distinction « vide vs liste » est un simple test de cardinalité côté Twig (articles is empty), pas une branche métier dans le code PHP. Le controller délègue la lecture et passe la liste au template ; le template décide de l'écran à afficher.

Voir aussi