diff --git a/messages/fr.json b/messages/fr.json index de58b41..1bf9a14 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -11,12 +11,12 @@ { "key": "0", "title": "Sauvegardez du contenu à lire", - "description": "Sauvegardez n'importe quel lien pour le lire plus tard. Triez, archivez et organisez comme bon vous semble." + "description": "Sauvegardez n'importe quel lien pour le lire plus tard." }, { "key": "1", "title": "Suivez vos sources préférées", - "description": "Blogs, YouTube, Reddit... Restez à jour avec tous vos contenus préférés grâce aux flux RSS et Atom." + "description": "Blogs, YouTube, Reddit... Restez à jour avec tous vos contenus grâce aux flux RSS et Atom." }, { "key": "2", @@ -204,7 +204,7 @@ }, "exportDataSection": { "title": "Exporter données du compte", - "description": "Exporter vos données au format JSON.", + "description": "Exporter vos données.", "export": "Exporter" }, "deleteAccountSection": { diff --git a/package.json b/package.json index 17d7ff2..111f030 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@radix-ui/react-context-menu": "^2.2.4", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dropdown-menu": "^2.1.4", + "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-navigation-menu": "^1.2.3", "@radix-ui/react-radio-group": "^1.2.2", @@ -36,6 +37,7 @@ "isomorphic-dompurify": "^2.19.0", "jsdom": "^25.0.1", "lucide-react": "^0.460.0", + "motion": "^11.18.1", "next": "^15.1.3", "next-auth": "5.0.0-beta.25", "next-intl": "^3.26.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32e7464..d77903c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,9 @@ importers: '@radix-ui/react-dropdown-menu': specifier: ^2.1.4 version: 2.1.4(@types/react-dom@19.0.2(@types/react@19.0.1))(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@19.0.0) '@radix-ui/react-label': specifier: ^2.1.1 version: 2.1.1(@types/react-dom@19.0.2(@types/react@19.0.1))(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -93,6 +96,9 @@ importers: lucide-react: specifier: ^0.460.0 version: 0.460.0(react@19.0.0) + motion: + specifier: ^11.18.1 + version: 11.18.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) next: specifier: ^15.1.3 version: 15.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -935,6 +941,11 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-icons@1.3.2': + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + '@radix-ui/react-id@1.1.0': resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} peerDependencies: @@ -1697,6 +1708,20 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} + framer-motion@11.18.1: + resolution: {integrity: sha512-EQa8c9lWVOm4zlz14MsBJWr8woq87HsNmsBnQNvcS0hs8uzw6HtGAxZyIU7EGTVpHD1C1n01ufxRyarXcNzpPg==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2010,6 +2035,26 @@ packages: mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + motion-dom@11.18.1: + resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} + + motion-utils@11.18.1: + resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==} + + motion@11.18.1: + resolution: {integrity: sha512-Tqbn7UMVp1V6JH5gbLFJAbP1//gdHNwEciQO22UHgFH1mBScq6gHrq8dlyBGbOlRF8iVSX8k0UV8tkkAVbwpKw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3327,6 +3372,10 @@ snapshots: '@types/react': 19.0.1 '@types/react-dom': 19.0.2(@types/react@19.0.1) + '@radix-ui/react-icons@1.3.2(react@19.0.0)': + dependencies: + react: 19.0.0 + '@radix-ui/react-id@1.1.0(@types/react@19.0.1)(react@19.0.0)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.1)(react@19.0.0) @@ -4086,6 +4135,15 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + framer-motion@11.18.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + motion-dom: 11.18.1 + motion-utils: 11.18.1 + tslib: 2.8.1 + optionalDependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + fsevents@2.3.3: optional: true @@ -4639,6 +4697,20 @@ snapshots: mitt@3.0.1: {} + motion-dom@11.18.1: + dependencies: + motion-utils: 11.18.1 + + motion-utils@11.18.1: {} + + motion@11.18.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + framer-motion: 11.18.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + tslib: 2.8.1 + optionalDependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + ms@2.1.3: {} mz@2.7.0: diff --git a/src/app/[locale]/(landing)/page.tsx b/src/app/[locale]/(landing)/page.tsx index 89f5a7f..2b05e3e 100644 --- a/src/app/[locale]/(landing)/page.tsx +++ b/src/app/[locale]/(landing)/page.tsx @@ -1,5 +1,12 @@ import { SPACING } from "@/app/[locale]/ui/spacing"; +import BlurFade from "@/components/ui/blur-fade"; import { Button } from "@/components/ui/button"; +import { + Card, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; import { NavigationMenu, NavigationMenuItem, @@ -7,97 +14,64 @@ import { NavigationMenuList, navigationMenuTriggerStyle, } from "@/components/ui/navigation-menu"; +import { ShimmerButton } from "@/components/ui/shimmer-button"; import { Link } from "@/i18n/routing"; import { cn } from "@/lib/utils"; import { useTranslations } from "next-intl"; +import { TbArchive, TbMail, TbRss } from "react-icons/tb"; export default function Home(): React.JSX.Element { const t = useTranslations("metadata"); + const elements: { + el: () => React.JSX.Element; + index: number; + }[] = [ + { + el: HeroSection, + index: 0, + }, + { + el: FeaturesSection, + index: 1, + }, + { + el: CtaSection, + index: 2, + }, + ]; return ( <> + + + + + {t("title")} + + + {t("login")} + + + + + - - - - - {t("title")} - - - {t("login")} - - - - - - {/* hero */} - - - {t("headline")} - - - {t("description")} - - - {t("ctaButton")} - - - - - {/* features */} - - {t.raw("features")?.map( - (feature: { - key: number; - title: string; - description: string; - }) => ( - - - {feature.title} - - {feature.description} - - ), - )} - - - {/* last cta */} - - - {t("lastCtaHeadline")} - - {t("lastCtaDescription")} - - {t("ctaButton")} - - + {elements.map((el) => ( + + {el.el()} + + ))}
{t("description")}
{feature.description}
{t("lastCtaDescription")}