From 503781c95f6a5ef953497b572eec443250696cb1 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 6 Sep 2026 10:26:50 +0200 Subject: [PATCH 1/3] =?UTF-8?q?feat(landing):=20lien=20de=20t=C3=A9l=C3=A9?= =?UTF-8?q?chargement=20de=20l'app=20Android=20(#65)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sur la page vitrine `/`, sous la rangée de CTA du hero (pas un 3e bouton : un compte reste nécessaire quelle que soit la plateforme), un lien discret vers l'APK Android + une ligne d'aide. - Cible : l'asset `batchcooking.apk` de la dernière release taguée Forgejo (`/releases/latest/download/…`, nom de fichier stable) — pas un artefact de CI. 404 tant que #64 + la correction de release.yml ne sont pas faits : état transitoire assumé, ce ticket n'ajoute que le lien. - `mobileHint` : rappel honnête que c'est un .apk à sideloader, pas une distribution Play Store. - i18n `landing.hero.mobileDownload` / `mobileHint` ; style discret dans landing-page.scss ; scénario Cypress de plus (présence + href du lien). Vérifs : `pnpm build` + `pnpm lint` OK. `landing.feature` non lancé en local (le hoist `tslib` de `@cypress/vite-dev-server` dans ce node_modules est cassé par un `pnpm install --force` interrompu + un verrou concurrent sur `@esbuild/win32-x64` ; `pnpm-lock.yaml` inchangé, la CI n'est pas affectée) → couvert par le job `e2e` de la CI. Co-Authored-By: Claude Sonnet 5 --- apps/web/cypress/e2e/landing.feature | 5 ++++ apps/web/cypress/e2e/landing.ts | 13 +++++++++ apps/web/src/locales/fr/translation.json | 4 ++- apps/web/src/pages/landing/LandingPage.tsx | 18 ++++++++++++- apps/web/src/pages/landing/landing-page.scss | 28 ++++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/apps/web/cypress/e2e/landing.feature b/apps/web/cypress/e2e/landing.feature index 4567e7d..714fd8b 100644 --- a/apps/web/cypress/e2e/landing.feature +++ b/apps/web/cypress/e2e/landing.feature @@ -22,6 +22,11 @@ Feature: Public landing page at the root When I click the link "Créer un compte" Then the URL should include "/signup" + Scenario: The landing page offers the Android app download + Given I am not signed in + When I visit "/" + Then I should see the Android download link + Scenario: Another guarded route still redirects a logged-out visitor to sign in Given I am not signed in When I visit "/recettes" diff --git a/apps/web/cypress/e2e/landing.ts b/apps/web/cypress/e2e/landing.ts index 2c58911..6763477 100644 --- a/apps/web/cypress/e2e/landing.ts +++ b/apps/web/cypress/e2e/landing.ts @@ -14,3 +14,16 @@ Then("I should see the landing call to action", () => { .should("be.visible") .and("have.attr", "href", "/login"); }); + +// The Android build is distributed as a Forgejo release asset with a stable +// filename (issue #64 builds/attaches it). We only assert the link is there +// and points at the right URL — the file itself is external to the suite. +Then("I should see the Android download link", () => { + cy.get(".landing__hero .landing__mobile-link") + .should("be.visible") + .and( + "have.attr", + "href", + "https://git.dev.kyuno.fr/kyuno/batchCooking/releases/latest/download/batchcooking.apk", + ); +}); diff --git a/apps/web/src/locales/fr/translation.json b/apps/web/src/locales/fr/translation.json index 70ee33b..e0d99c3 100644 --- a/apps/web/src/locales/fr/translation.json +++ b/apps/web/src/locales/fr/translation.json @@ -1327,7 +1327,9 @@ "title": "Cuisinez une fois, mangez toute la semaine", "lede": "Planifiez vos repas, importez des recettes depuis vos sites préférés, et générez la liste de courses qui va avec — pour tout le foyer, sans y penser deux fois.", "ctaSignup": "Créer un compte", - "ctaLogin": "Se connecter" + "ctaLogin": "Se connecter", + "mobileDownload": "Télécharger pour Android", + "mobileHint": "Fichier .apk à installer soi-même : Android demandera d'autoriser l'installation depuis une source inconnue. Ce n'est pas une version du Play Store, et un compte reste nécessaire." }, "features": { "title": "Ce que batchCooking fait pour vous", diff --git a/apps/web/src/pages/landing/LandingPage.tsx b/apps/web/src/pages/landing/LandingPage.tsx index 48b800a..ed3e33f 100644 --- a/apps/web/src/pages/landing/LandingPage.tsx +++ b/apps/web/src/pages/landing/LandingPage.tsx @@ -1,4 +1,4 @@ -import { CalendarDays, HeartPulse, Sparkles, Users } from "lucide-react"; +import { CalendarDays, HeartPulse, Smartphone, Sparkles, Users } from "lucide-react"; import type { ReactNode } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; @@ -50,6 +50,22 @@ export function LandingPage() { {t("landing.hero.ctaLogin")} + {/* + * Secondary action — an account is needed on any platform, so the + * Android build is a discreet link under the CTA row, not a third + * button. Points at the Forgejo "latest release" asset with a + * stable filename (see issue #64); 404s until that pipeline ships, + * accepted as a transient state. The hint is honest that this is a + * sideloaded .apk, not a Play Store listing. + */} + + + {t("landing.hero.mobileDownload")} + +

{t("landing.hero.mobileHint")}

diff --git a/apps/web/src/pages/landing/landing-page.scss b/apps/web/src/pages/landing/landing-page.scss index f3954ec..befe47f 100644 --- a/apps/web/src/pages/landing/landing-page.scss +++ b/apps/web/src/pages/landing/landing-page.scss @@ -116,6 +116,34 @@ } } +// --- Android download (discreet, under the CTA row) -------------------- +.landing__mobile-link { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + margin-top: var(--space-md); + font-size: var(--font-size-sm); + font-weight: 600; + color: var(--color-primary); + text-decoration: none; + + svg { + width: 1em; + height: 1em; + } + + &:hover { + text-decoration: underline; + } +} + +.landing__mobile-hint { + margin: var(--space-xs) 0 0; + font-size: var(--font-size-xs); + color: var(--color-text-muted); + max-width: 34rem; +} + // --- Features ----------------------------------------------------------- .landing__features h2, .landing__preview h2 { From e90cadcc416b2446736e373a97b4888b85635fa0 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 6 Sep 2026 11:02:53 +0200 Subject: [PATCH 2/3] chore: relance la CI (#68) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le job `test` de la run précédente a échoué sur une saturation du runner (P1002 Prisma + timeout Docker), pas sur le code — le même job échouait au même moment sur toutes les branches, `main` compris. Diff 100 % frontend. Co-Authored-By: Claude Sonnet 5 From 966a0afa0230a1e536cbdf3dc7cc5b2bf2561363 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 6 Sep 2026 16:00:32 +0200 Subject: [PATCH 3/3] chore: relance la CI (#68) Co-Authored-By: Claude Sonnet 5