import { CalendarDays, HeartPulse, Smartphone, Sparkles, Users } from "lucide-react";
import type { ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { attemptOpenNativeApp, isAndroidPhoneBrowser } from "../../lib/mobile-app-redirect";
import "./landing-page.scss";
/**
* Public marketing page shown at `/` to a logged-out visitor (see
* `RequireAuth` for how it's wired in without touching the route table).
* All copy comes from i18next under the `landing.*` namespace — no
* hardcoded JSX text, same convention as every other page.
*
* Deliberately dependency-free for visuals: the hero illustration is an
* inline stroke-drawn SVG in the same visual language as `lucide-react`
* (the icon set already used everywhere), not an imported illustration
* library or an external asset — same choice `TechStepCorrectionPopover`
* made for its own hand-drawn icons. The three preview images are real
* app screenshots served statically from `public/landing/` (see that
* folder's README); a missing file just falls back to its `alt` text and
* never breaks the build.
*/
export function LandingPage() {
const { t } = useTranslation();
const navigate = useNavigate();
// UA-based, not `useIsMobileViewport()` — same reasoning as
// `attemptOpenNativeApp`'s own doc comment: this decides whether trying
// to open the *native app* makes sense at all (a platform question), not
// whether the viewport is narrow (a resized desktop window shouldn't
// attempt a scheme navigation just because it's a small window).
const isMobile = isAndroidPhoneBrowser();
function handleOpenApp() {
attemptOpenNativeApp({ onFallback: () => navigate("/telecharger") });
}
const features: { icon: ReactNode; key: "planning" | "import" | "health" | "household" }[] = [
{ icon: , key: "planning" },
{ icon: , key: "import" },
{ icon: , key: "health" },
{ icon: , key: "household" },
];
const shots: { src: string; key: "planning" | "recipe" | "cookingSession" }[] = [
{ src: "/landing/planning.png", key: "planning" },
{ src: "/landing/recipe.png", key: "recipe" },
{ src: "/landing/cooking-session.png", key: "cookingSession" },
];
return (
batchCooking
{t("landing.hero.title")}
{t("landing.hero.lede")}
{/*
* Issue #85: on a real Android phone browser, opening/getting
* the app is more useful than a web account — the web
* experience isn't optimized for mobile at all (the whole
* point of this chantier), and someone with the app already
* installed can sign up/log in from inside it just as well.
* So this becomes the *primary* action, demoting Signup/Login
* to secondary rather than hiding them — some visitors
* genuinely want the browser flow, e.g. to try it before
* installing anything. Desktop is untouched: a scheme-open
* attempt makes no sense there, so Signup stays primary and
* this button doesn't render at all (see the plain `/telecharger`
* link below instead, replacing the old direct-APK link).
*/}
{isMobile && (
)}
{t("landing.hero.ctaSignup")}
{t("landing.hero.ctaLogin")}
{/*
* Desktop only — a scheme-open attempt (the mobile button above)
* has no meaning here. Routed through `/telecharger` (the same
* fallback page a failed mobile attempt lands on) rather than
* linking `${API_BASE_URL}/mobile/download` directly, so "get
* the app" has exactly one canonical destination app-wide
* instead of two slightly different mechanisms to keep in sync.
*/}
{!isMobile && (
{t("landing.hero.mobileDownload")}
)}
{t("landing.finalCta.button")}
);
}
/**
* Hero illustration — a week grid with a simmering pot, drawn in the same
* 2px round-stroke `currentColor` language as the lucide icon set so it
* sits visually with the rest of the app. No external asset.
*/
function HeroIllustration() {
return (
);
}