Page vitrine pré-connexion/inscription à la racine (/) #41

Closed
opened 2026-09-05 18:19:39 +02:00 by kyuno · 0 comments
Owner

Contexte

Aujourd'hui, l'app n'a strictement aucune page publique : visiter /
déconnecté redirige immédiatement vers /login (RequireAuth.tsx:19-21,
return <Navigate to="/login" replace />;) — un visiteur qui ne connaît
pas déjà l'app tombe directement sur un formulaire de connexion, sans rien
qui explique ce qu'elle fait. Le but : une vraie page de présentation
("vitrine") avant la connexion/inscription.

Décisions validées avec l'utilisateur

Question Décision
Emplacement Directement sur / — contenu conditionnel selon l'état de connexion (vitrine si déconnecté, planning si connecté), pas une route dédiée séparée
Ambition visuelle Riche, avec de vrais visuels — captures d'écran de l'app + illustration, pas seulement du texte

Conception — routage

/ reste nichée exactement comme aujourd'hui sous
<Route element={<RequireAuth><AppLayout /></RequireAuth>}><Route path="/" element={<PlanningPage />} />
(App.tsx:66-93, aucun changement de la table de routes). Le seul
changement : RequireAuth.tsx devient sensible au chemin courant
(useLocation()) pour ce cas précis, sans toucher son comportement pour
toutes les autres routes qu'il protège :

export function RequireAuth({ children }: { children: ReactNode }) {
  const { user, isLoading } = useAuth();
  const location = useLocation();

  if (isLoading) return null;
  if (!user) {
    // "/" spécifiquement montre la vitrine plutôt que de rediriger tout de
    // suite vers /login — chaque autre route protégée continue de
    // rediriger exactement comme avant.
    if (location.pathname === "/") return <LandingPage />;
    return <Navigate to="/login" replace />;
  }
  return <>{children}</>;
}

Pourquoi ça marche sans toucher AppLayout ni la table de routes : children
de RequireAuth est <AppLayout /> — tant que la branche
!user && pathname === "/" renvoie <LandingPage /> directement, AppLayout
(et donc la sidebar) ne monte jamais pour un visiteur déconnecté sur /. Une
fois connecté, {children} reprend le dessus et AppLayout s'Outlete vers
PlanningPage exactement comme aujourd'hui. RedirectIfAuthenticated
(/login, /signup) n'a besoin d'aucun changement — un visiteur déjà
connecté qui y navigue directement continue d'être renvoyé vers /, où il
retombe sur le planning comme avant.

Documenter cette exception dans le JSDoc de RequireAuth (pourquoi ce garde
par ailleurs générique importe une page précise) et dans
specs/frontend-architecture.md's description du routage racine.

Conception — contenu de la page

Nouveau apps/web/src/pages/landing/LandingPage.tsx + landing-page.scss
(tokens de _theme.scss réutilisés, cohérent avec le reste de l'app — pas
une charte graphique à part). Aucune nouvelle dépendance : ni librairie
d'illustration, ni asset externe — dans l'esprit déjà établi par
TechStepCorrectionPopover.tsx qui dessine ses propres icônes SVG "stroke-based"
pour rester dans le langage visuel de lucide-react plutôt que d'importer un
jeu d'icônes de plus.

  1. Hero — wordmark "batchCooking" + accroche courte (texte réel à
    affiner en revue de PR, pas figé ici) + illustration héro en SVG dessiné
    à la main (même style ligne/trait que les icônes existantes, pas de
    fichier image externe) + deux CTA : "Se connecter" (/login), "Créer un
    compte" (/signup).
  2. Fonctionnalités — grille de 3-4 cartes (icône lucide + titre + courte
    description), construites sur les capacités réelles déjà documentées
    dans le README plutôt qu'inventées : planification hebdomadaire du
    planning, import de recettes depuis plusieurs sources externes
    (TheMealDB/Marmiton/750g/Manger Bouger), suivi allergies/régimes/ingrédients
    détestés, foyer partagé à plusieurs (invitation par code).
  3. Aperçu de l'app — 1 à 3 captures d'écran réelles (pas des maquettes) :
    la grille du planning, une fiche recette avec surlignage des techniques,
    la liste de courses. Nouveau dossier apps/web/src/assets/ (n'existe pas
    encore) pour ces fichiers image, importés normalement via Vite.
  4. CTA final — répète "Créer un compte".

Nouvelles clés i18n sous un namespace landing.* dans
apps/web/src/locales/fr/translation.json (titre, accroche, chaque
fonctionnalité, libellés des CTA) — jamais de texte en dur dans le JSX,
même convention que le reste de l'app.

Bonus peu coûteux, à faire dans la foulée : apps/web/index.html n'a
aujourd'hui ni favicon ni meta description (<title>batchCooking</title>
seul) — pertinent maintenant que / est une vraie page publique/partageable.
Ajouter un favicon simple (même monogramme "bC" que la sidebar, en SVG) et
un <meta name="description">.

Fichiers à toucher

  • apps/web/src/features/auth/RequireAuth.tsx — la branche pathname === "/" ci-dessus.
  • apps/web/src/pages/landing/LandingPage.tsx + landing-page.scss (nouveaux).
  • apps/web/src/assets/ (nouveau dossier) — captures d'écran.
  • apps/web/src/locales/fr/translation.json — namespace landing.*.
  • apps/web/index.html — favicon + meta description.
  • specs/frontend-architecture.md — routage racine.

Tests

Cypress e2e (Gherkin, nouveau .feature ou extension d'un existant) :
visiteur non connecté sur / voit la vitrine (titre, CTA) ; clique "Se
connecter" → atterrit sur /login ; clique "Créer un compte" → atterrit sur
/signup ; un visiteur déjà connecté qui force / voit bien le planning,
pas la vitrine (non-régression du comportement actuel). Pas la peine de
tester le rendu pixel des sections visuelles — comportement/navigation
seulement, même posture que le reste de la suite Cypress de ce repo.

Hors scope

  • Optimisation SEO poussée (Open Graph, sitemap, indexation) — un
    <meta description> de base suffit pour cette itération.
  • Contenu marketing multi-langue — une seule locale (fr) existe
    aujourd'hui dans toute l'app, pas de raison de commencer ici.

🤖 Filed by Claude Code

## Contexte Aujourd'hui, l'app n'a strictement aucune page publique : visiter `/` déconnecté redirige immédiatement vers `/login` (`RequireAuth.tsx:19-21`, `return <Navigate to="/login" replace />;`) — un visiteur qui ne connaît pas déjà l'app tombe directement sur un formulaire de connexion, sans rien qui explique ce qu'elle fait. Le but : une vraie page de présentation ("vitrine") avant la connexion/inscription. ## Décisions validées avec l'utilisateur | Question | Décision | |---|---| | Emplacement | **Directement sur `/`** — contenu conditionnel selon l'état de connexion (vitrine si déconnecté, planning si connecté), pas une route dédiée séparée | | Ambition visuelle | **Riche, avec de vrais visuels** — captures d'écran de l'app + illustration, pas seulement du texte | ## Conception — routage `/` reste nichée exactement comme aujourd'hui sous `<Route element={<RequireAuth><AppLayout /></RequireAuth>}><Route path="/" element={<PlanningPage />} />` (`App.tsx:66-93`, **aucun changement de la table de routes**). Le seul changement : `RequireAuth.tsx` devient sensible au chemin courant (`useLocation()`) pour ce cas précis, sans toucher son comportement pour toutes les autres routes qu'il protège : ```tsx export function RequireAuth({ children }: { children: ReactNode }) { const { user, isLoading } = useAuth(); const location = useLocation(); if (isLoading) return null; if (!user) { // "/" spécifiquement montre la vitrine plutôt que de rediriger tout de // suite vers /login — chaque autre route protégée continue de // rediriger exactement comme avant. if (location.pathname === "/") return <LandingPage />; return <Navigate to="/login" replace />; } return <>{children}</>; } ``` Pourquoi ça marche sans toucher `AppLayout` ni la table de routes : `children` de `RequireAuth` **est** `<AppLayout />` — tant que la branche `!user && pathname === "/"` renvoie `<LandingPage />` directement, `AppLayout` (et donc la sidebar) ne monte jamais pour un visiteur déconnecté sur `/`. Une fois connecté, `{children}` reprend le dessus et `AppLayout` s'Outlete vers `PlanningPage` exactement comme aujourd'hui. `RedirectIfAuthenticated` (`/login`, `/signup`) n'a besoin d'aucun changement — un visiteur déjà connecté qui y navigue directement continue d'être renvoyé vers `/`, où il retombe sur le planning comme avant. Documenter cette exception dans le JSDoc de `RequireAuth` (pourquoi ce garde par ailleurs générique importe une page précise) et dans `specs/frontend-architecture.md`'s description du routage racine. ## Conception — contenu de la page Nouveau `apps/web/src/pages/landing/LandingPage.tsx` + `landing-page.scss` (tokens de `_theme.scss` réutilisés, cohérent avec le reste de l'app — pas une charte graphique à part). Aucune nouvelle dépendance : ni librairie d'illustration, ni asset externe — dans l'esprit déjà établi par `TechStepCorrectionPopover.tsx` qui dessine ses propres icônes SVG "stroke-based" pour rester dans le langage visuel de `lucide-react` plutôt que d'importer un jeu d'icônes de plus. 1. **Hero** — wordmark "batchCooking" + accroche courte (texte réel à affiner en revue de PR, pas figé ici) + illustration héro en SVG dessiné à la main (même style ligne/trait que les icônes existantes, pas de fichier image externe) + deux CTA : "Se connecter" (`/login`), "Créer un compte" (`/signup`). 2. **Fonctionnalités** — grille de 3-4 cartes (icône lucide + titre + courte description), construites sur les capacités réelles déjà documentées dans le README plutôt qu'inventées : planification hebdomadaire du planning, import de recettes depuis plusieurs sources externes (TheMealDB/Marmiton/750g/Manger Bouger), suivi allergies/régimes/ingrédients détestés, foyer partagé à plusieurs (invitation par code). 3. **Aperçu de l'app** — 1 à 3 captures d'écran réelles (pas des maquettes) : la grille du planning, une fiche recette avec surlignage des techniques, la liste de courses. Nouveau dossier `apps/web/src/assets/` (n'existe pas encore) pour ces fichiers image, importés normalement via Vite. 4. **CTA final** — répète "Créer un compte". Nouvelles clés i18n sous un namespace `landing.*` dans `apps/web/src/locales/fr/translation.json` (titre, accroche, chaque fonctionnalité, libellés des CTA) — jamais de texte en dur dans le JSX, même convention que le reste de l'app. **Bonus peu coûteux, à faire dans la foulée** : `apps/web/index.html` n'a aujourd'hui ni favicon ni meta description (`<title>batchCooking</title>` seul) — pertinent maintenant que `/` est une vraie page publique/partageable. Ajouter un favicon simple (même monogramme "bC" que la sidebar, en SVG) et un `<meta name="description">`. ## Fichiers à toucher - `apps/web/src/features/auth/RequireAuth.tsx` — la branche `pathname === "/"` ci-dessus. - `apps/web/src/pages/landing/LandingPage.tsx` + `landing-page.scss` (nouveaux). - `apps/web/src/assets/` (nouveau dossier) — captures d'écran. - `apps/web/src/locales/fr/translation.json` — namespace `landing.*`. - `apps/web/index.html` — favicon + meta description. - `specs/frontend-architecture.md` — routage racine. ## Tests Cypress e2e (Gherkin, nouveau `.feature` ou extension d'un existant) : visiteur non connecté sur `/` voit la vitrine (titre, CTA) ; clique "Se connecter" → atterrit sur `/login` ; clique "Créer un compte" → atterrit sur `/signup` ; un visiteur déjà connecté qui force `/` voit bien le planning, pas la vitrine (non-régression du comportement actuel). Pas la peine de tester le rendu pixel des sections visuelles — comportement/navigation seulement, même posture que le reste de la suite Cypress de ce repo. ## Hors scope - Optimisation SEO poussée (Open Graph, sitemap, indexation) — un `<meta description>` de base suffit pour cette itération. - Contenu marketing multi-langue — une seule locale (`fr`) existe aujourd'hui dans toute l'app, pas de raison de commencer ici. --- 🤖 Filed by [Claude Code](https://claude.com/claude-code)
kyuno added the
enhancement
planned
labels 2026-09-05 18:19:39 +02:00
kyuno added the
Low
label 2026-09-05 18:52:46 +02:00
kyuno closed this issue 2026-09-06 05:06:20 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/batchCooking#41
No description provided.