From 7a8022d11a195af203bd0e063120bb605fa64ff0 Mon Sep 17 00:00:00 2001 From: Matheo Guilbert Date: Fri, 17 Apr 2026 11:13:20 +0200 Subject: [PATCH] apply translations in all pages --- app/[locale]/page.tsx | 4 +- components/layout/Footer.tsx | 13 +++-- components/layout/Header.tsx | 10 ++-- components/sections/AboutSection.tsx | 58 ++++++++++--------- ...{FeatureSection.tsx => AppoachSection.tsx} | 43 +++++++------- components/sections/HeroSection.tsx | 15 +++-- components/sections/OtherProjects.tsx | 6 +- components/sections/ProjectHero.tsx | 8 ++- components/sections/ProjectMeta.tsx | 10 ++-- components/sections/ProjectTechnologies.tsx | 4 +- components/sections/WorksSection.tsx | 7 ++- components/ui/FeatureColumn.tsx | 33 ----------- components/ui/ProjectCard.tsx | 5 +- messages/en.json | 8 +-- messages/fr.json | 8 +-- 15 files changed, 108 insertions(+), 124 deletions(-) rename components/sections/{FeatureSection.tsx => AppoachSection.tsx} (71%) delete mode 100644 components/ui/FeatureColumn.tsx diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index b9fbf56..065078f 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -1,6 +1,6 @@ import HeroSection from "@/components/sections/HeroSection"; import WorksSection from "@/components/sections/WorksSection"; -import FeatureSection from "@/components/sections/FeatureSection"; +import ApproachSection from "@/components/sections/AppoachSection"; import TimelineSection from "@/components/sections/AboutSection"; import { getAllProjects } from "@/lib/projects/get-projects"; @@ -20,7 +20,7 @@ export default async function Home({ params }: props) {
- +
diff --git a/components/layout/Footer.tsx b/components/layout/Footer.tsx index 9f714d9..60ffa22 100644 --- a/components/layout/Footer.tsx +++ b/components/layout/Footer.tsx @@ -1,6 +1,9 @@ import { FiFacebook, FiInstagram, FiLinkedin, FiGithub } from "react-icons/fi"; +import { useTranslations } from "next-intl"; export default function Footer() { + const t = useTranslations('footer'); + return (
{/* Logo */} @@ -9,13 +12,13 @@ export default function Footer() {

Mathéo Guilbert EI

-

Développeur Full Stack & Architecte Web

+

{t('me')}

-

Légal

-

Mentions Légales

-

Conditions Générales de Vente

+

{t('legal.title')}

+

{t('legal.legalNotice')}

+

{t('legal.termsAndConditions')}

@@ -32,7 +35,7 @@ export default function Footer() {
-

© 2026 M. Guilbert. Tous droits réservés.

+

{t('copyright')}

); } \ No newline at end of file diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index 67faaa9..22335bf 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -5,6 +5,7 @@ import React, { useState, useEffect, MouseEvent } from "react"; import { useParams, usePathname } from "next/navigation"; import { CiMenuFries } from "react-icons/ci"; import { IoCloseOutline } from "react-icons/io5"; +import { useTranslations } from "next-intl"; import LanguageSwitcher from "../ui/LanguageSwitcher"; @@ -12,13 +13,14 @@ export default function Header() { const params = useParams<{ locale?: string }>(); const pathname = usePathname(); const locale = params?.locale ?? "fr"; + const t = useTranslations('header'); const homePath = `/${locale}`; const links = [ - { text: "Accueil", target: homePath }, - { text: "Travaux", target: `${homePath}#works` }, - { text: "A propos", target: `${homePath}#about` }, - { text: "Blog", target: `${homePath}/blog` }, + { text: t('home'), target: homePath }, + { text: t('works'), target: `${homePath}#works` }, + { text: t('about'), target: `${homePath}#about` }, + { text: t('blog'), target: `${homePath}/blog` }, ]; const [isOpen, setIsOpen] = useState(false); diff --git a/components/sections/AboutSection.tsx b/components/sections/AboutSection.tsx index d20da82..4ff6d24 100644 --- a/components/sections/AboutSection.tsx +++ b/components/sections/AboutSection.tsx @@ -1,36 +1,38 @@ 'use client'; import { useRef, useEffect, useState } from 'react'; - -const steps = [ - { - title: 'Les Débuts', - text: "J'ai commencé par le web en 2019 suite à un stage, je n'ai plus jamais arrêté. Aujourd'hui je veux en faire mon métier.", - year: '2019', - position: 'top' as const, - left: '16%', - }, - { - title: 'L\'Évolution', - text: "Après un bac STI2D avec mention Très bien j'ai entamé un BUT Informatique Parcours Développement IA.", - year: '2022', - position: 'bottom' as const, - left: '50%', - }, - { - title: 'Aujourd\'hui', - text: "Je suis entrepreneur, co-fondateur d'une startup et développeur freelance, je vis de ma passion.", - year: '2026', - position: 'top' as const, - left: '84%', - }, -]; - -const lineTop = '58%'; +import { useTranslations } from "next-intl"; export default function TimelineSection() { const sectionRef = useRef(null); const [visible, setVisible] = useState(false); + const t = useTranslations('about'); + + const lineTop = '58%'; + + const steps = [ + { + title: t('step1.title'), + text: t('step1.text'), + year: '2019', + position: 'top' as const, + left: '16%', + }, + { + title: t('step2.title'), + text: t('step2.text'), + year: '2022', + position: 'bottom' as const, + left: '50%', + }, + { + title: t('step3.title'), + text: t('step3.text'), + year: '2026', + position: 'top' as const, + left: '84%', + }, + ]; useEffect(() => { const section = sectionRef.current; @@ -56,11 +58,11 @@ export default function TimelineSection() { {/* Label */}
- Parcours + {t('sectionLabel')}

- À propos + {t('title')}

{/* Mobile layout */} diff --git a/components/sections/FeatureSection.tsx b/components/sections/AppoachSection.tsx similarity index 71% rename from components/sections/FeatureSection.tsx rename to components/sections/AppoachSection.tsx index 1fa4197..7c3d8b3 100644 --- a/components/sections/FeatureSection.tsx +++ b/components/sections/AppoachSection.tsx @@ -1,28 +1,29 @@ 'use client'; import { useRef, useEffect } from 'react'; -import { FeatureColumn } from '@/components/ui/FeatureColumn'; +import { useTranslations } from "next-intl"; -const features = [ - { - imagePath: '/icons/brain.svg', - title: 'Plus qu\'un simple exécutant', - text: 'Grâce à mon background en conception numérique et mobile, je ne me contente pas de coder. J\'apporte un regard critique et constructif sur l\'ensemble de votre projet.', - }, - { - imagePath: '/icons/building.svg', - title: 'Des fondations en béton', - text: 'Ma spécialité : l\'architecture. Je construis des solutions pérennes, évolutives et capables d\'absorber la croissance de votre produit dans le temps.', - }, - { - imagePath: '/icons/people.svg', - title: 'L\'utilisateur au centre', - text: 'Le code parfait n\'est rien si le produit ne répond pas à un besoin. Je place l\'expérience utilisateur et la fonctionnalité au cœur de mes développements.', - }, -]; - -export default function FeatureSection() { +export default function ApproachSection() { const sectionRef = useRef(null); + const t = useTranslations('approach'); + + const features = [ + { + imagePath: '/icons/brain.svg', + title: t('feature1.title'), + text: t('feature1.text'), + }, + { + imagePath: '/icons/building.svg', + title: t('feature2.title'), + text: t('feature2.text'), + }, + { + imagePath: '/icons/people.svg', + title: t('feature3.title'), + text: t('feature3.text'), + }, + ]; useEffect(() => { const section = sectionRef.current; @@ -51,7 +52,7 @@ export default function FeatureSection() { {/* Section label */}
- Approche + {t('sectionLabel')}
diff --git a/components/sections/HeroSection.tsx b/components/sections/HeroSection.tsx index 45090f8..b8805ac 100644 --- a/components/sections/HeroSection.tsx +++ b/components/sections/HeroSection.tsx @@ -1,9 +1,11 @@ 'use client'; import { useEffect, useRef } from 'react'; +import { useTranslations } from "next-intl"; export default function HeroSection() { const sectionRef = useRef(null); + const t = useTranslations('hero'); useEffect(() => { const section = sectionRef.current; @@ -36,7 +38,7 @@ export default function HeroSection() { > - Développeur Full Stack & Architecte Web + {t('sectionLabel')}
@@ -46,9 +48,7 @@ export default function HeroSection() { style={{ opacity: 0, transform: 'translateY(28px)', transition: 'opacity 700ms cubic-bezier(0.22,1,0.36,1), transform 700ms cubic-bezier(0.22,1,0.36,1)' }} >

- Ensemble,
- construisons
- ce qui dure. + {t('title')}

@@ -58,8 +58,7 @@ export default function HeroSection() { style={{ opacity: 0, transform: 'translateY(28px)', transition: 'opacity 700ms cubic-bezier(0.22,1,0.36,1), transform 700ms cubic-bezier(0.22,1,0.36,1)' }} >

- Je conçois des architectures robustes, scalables et pérennes — - des fondations qui supportent la croissance de votre produit dans le temps. + {t('subtitle')}

@@ -77,7 +76,7 @@ export default function HeroSection() { }} > - Voir mes travaux + {t('cta')} Défiler + {t('scrollPrompt')} (null); + const t = useTranslations('projectPage.otherProjects'); useEffect(() => { const el = ref.current; @@ -45,12 +47,12 @@ export function OtherProjects({ locale, projects }: props) {
- Autres projets + {t('sectionLabel')}

- Voir aussi + {t('title')}

diff --git a/components/sections/ProjectHero.tsx b/components/sections/ProjectHero.tsx index 77d0b6f..331126f 100644 --- a/components/sections/ProjectHero.tsx +++ b/components/sections/ProjectHero.tsx @@ -2,6 +2,7 @@ import { useEffect, useRef } from 'react'; import Link from 'next/link'; +import { useTranslations } from "next-intl"; type props = { title: string; @@ -13,6 +14,7 @@ type props = { export function ProjectHero({ title, description, dateLabel, locale, cover }: props) { const ref = useRef(null); + const t = useTranslations('projectPage.hero'); useEffect(() => { const section = ref.current; @@ -46,7 +48,7 @@ export function ProjectHero({ title, description, dateLabel, locale, cover }: pr )} {/* Back link */} -
+
- Retour aux projets + {t('backToProjects')}
@@ -107,7 +109,7 @@ export function ProjectHero({ title, description, dateLabel, locale, cover }: pr {/* Scroll indicator */}
- Défiler + {t('scrollPrompt')} (null); + const t = useTranslations('projectPage.meta'); useEffect(() => { const el = ref.current; @@ -47,16 +49,16 @@ export function ProjectMeta({ dateLabel, category, roles, client }: props) {
- {dateLabel} - {category} - + {dateLabel} + {category} +
{roles.map((role) => ( {role} ))}
- {client} + {client}
{/* Bottom divider */} diff --git a/components/sections/ProjectTechnologies.tsx b/components/sections/ProjectTechnologies.tsx index 6902e9f..be70b3a 100644 --- a/components/sections/ProjectTechnologies.tsx +++ b/components/sections/ProjectTechnologies.tsx @@ -1,6 +1,7 @@ 'use client'; import { useRef, useEffect } from 'react'; +import { useTranslations } from "next-intl"; type props = { technologies: string[]; @@ -8,6 +9,7 @@ type props = { export function ProjectTechnologies({ technologies }: props) { const ref = useRef(null); + const t = useTranslations('projectPage.technologies'); useEffect(() => { const el = ref.current; @@ -32,7 +34,7 @@ export function ProjectTechnologies({ technologies }: props) {
- Technologies + {t('sectionLabel')}
diff --git a/components/sections/WorksSection.tsx b/components/sections/WorksSection.tsx index 6895aa8..b255b68 100644 --- a/components/sections/WorksSection.tsx +++ b/components/sections/WorksSection.tsx @@ -1,6 +1,8 @@ 'use client'; import { useRef, useEffect } from 'react'; +import { useTranslations } from "next-intl"; + import { Project } from "@/lib/projects/types"; import { ProjectCard } from "../ui/ProjectCard"; @@ -11,6 +13,7 @@ type props = { export default function WorksSection({ projects, locale }: props) { const sectionRef = useRef(null); + const t = useTranslations('works'); useEffect(() => { const section = sectionRef.current; @@ -39,11 +42,11 @@ export default function WorksSection({ projects, locale }: props) { {/* Section label */}
- Sélection de projets + {t('sectionLabel')}

- Travaux + {t('title')}

diff --git a/components/ui/FeatureColumn.tsx b/components/ui/FeatureColumn.tsx deleted file mode 100644 index 20e8946..0000000 --- a/components/ui/FeatureColumn.tsx +++ /dev/null @@ -1,33 +0,0 @@ -type props = { - imagePath: string; - title: string; - text: string; - delay?: number; -}; - -export const FeatureColumn = ({ imagePath, title, text, delay = 0 }: props) => { - return ( -
- {/* Icon container */} -
- -
- -
- {title} -
- -
- {text} -
-
- ); -}; diff --git a/components/ui/ProjectCard.tsx b/components/ui/ProjectCard.tsx index 7e88e7f..81fc7cf 100644 --- a/components/ui/ProjectCard.tsx +++ b/components/ui/ProjectCard.tsx @@ -2,6 +2,8 @@ import { useRef, useEffect } from 'react'; import Link from "next/link"; +import { useTranslations } from "next-intl"; + import { Project } from "@/lib/projects/types"; type props = { @@ -14,6 +16,7 @@ type props = { export const ProjectCard = ({ project, locale, isTheLast = false, index = 0 }: props) => { const num = String(index + 1).padStart(2, '0'); const cardRef = useRef(null); + const t = useTranslations('projectCard'); useEffect(() => { const el = cardRef.current; @@ -85,7 +88,7 @@ export const ProjectCard = ({ project, locale, isTheLast = false, index = 0 }: p {/* CTA */}
- Lire le cas + {t('cta')}