feat: render locale-aware portfolio routes

This commit is contained in:
2026-09-08 19:21:26 +03:30
parent 3bb6b4396c
commit 3af34dbd92
22 changed files with 797 additions and 186 deletions

12
src/app/(en)/layout.tsx Normal file
View File

@@ -0,0 +1,12 @@
import type { Metadata } from 'next';
import { SiteRoot } from '@/app/SiteRoot';
import { messagesByLocale } from '@/i18n/content';
import '@/styles/globals.css';
export const metadata: Metadata = messagesByLocale.en.metadata;
export default function EnglishLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return <SiteRoot locale="en">{children}</SiteRoot>;
}

5
src/app/(en)/page.tsx Normal file
View File

@@ -0,0 +1,5 @@
import { PortfolioPage } from '@/app/PortfolioPage';
export default function Home() {
return <PortfolioPage locale="en" />;
}

View File

@@ -0,0 +1,12 @@
import type { Metadata } from 'next';
import { SiteRoot } from '@/app/SiteRoot';
import { messagesByLocale } from '@/i18n/content';
import '@/styles/globals.css';
export const metadata: Metadata = messagesByLocale.fa.metadata;
export default function PersianLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return <SiteRoot locale="fa">{children}</SiteRoot>;
}

5
src/app/(fa)/fa/page.tsx Normal file
View File

@@ -0,0 +1,5 @@
import { PortfolioPage } from '@/app/PortfolioPage';
export default function PersianHome() {
return <PortfolioPage locale="fa" />;
}

View File

@@ -8,33 +8,20 @@ import { MilestonesSection } from '@/components/MilestonesSection';
import { FooterSection } from '@/components/FooterSection';
import { MotionController } from '@/components/MotionController';
import { SiteLoader } from '@/components/SiteLoader';
import type { Locale } from '@/i18n/content';
export default function Home() {
export function PortfolioPage({ locale }: { locale: Locale }) {
return (
<main className="desktop-canvas">
<SiteLoader />
<main className="desktop-canvas" data-locale={locale}>
<SiteLoader locale={locale} />
<MotionController />
{/* 1. Hero & About Me River Journey (Seamless Scenic Background) */}
<ScenicHeroJourney />
{/* 2. Projects Carousel Section */}
<ProjectsSection />
{/* 3. Work Experience Timeline Section */}
<ExperienceSection />
{/* 4. Skills & Tools Matrix Section */}
<SkillsSection />
{/* 5. Education Foundation Section */}
<EducationSection />
{/* 6. Milestones & Awards Section */}
<MilestonesSection />
{/* 7. Footer CTA & Social Section */}
<FooterSection />
<ScenicHeroJourney locale={locale} />
<ProjectsSection locale={locale} />
<ExperienceSection locale={locale} />
<SkillsSection locale={locale} />
<EducationSection locale={locale} />
<MilestonesSection locale={locale} />
<FooterSection locale={locale} />
</main>
);
}

View File

@@ -1,19 +1,6 @@
import type { Metadata } from 'next';
import type { ReactNode } from 'react';
import { ThemeProvider } from '@/context/ThemeContext';
import '@/styles/globals.css';
export const metadata: Metadata = {
title: "Amirhossein Khalili | Dedicated Product Engineer",
description:
"Personal portfolio of Amirhossein Khalili, Product Engineer & Software Developer based in Iran.",
keywords: [
'Amirhossein Khalili',
'Product Engineer',
'Software Engineer',
'Full Stack Developer',
'Portfolio',
],
};
import type { Locale } from '@/i18n/content';
const themeScript = `
document.documentElement.dataset.siteLoading = 'true';
@@ -23,13 +10,19 @@ const themeScript = `
} catch {}
`;
export default function RootLayout({
export function SiteRoot({
children,
locale,
}: {
children: React.ReactNode;
children: ReactNode;
locale: Locale;
}) {
return (
<html lang="en" suppressHydrationWarning>
<html
lang={locale}
dir={locale === 'fa' ? 'rtl' : 'ltr'}
suppressHydrationWarning
>
<head>
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
</head>