feat: render locale-aware portfolio routes
This commit is contained in:
12
src/app/(en)/layout.tsx
Normal file
12
src/app/(en)/layout.tsx
Normal 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
5
src/app/(en)/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { PortfolioPage } from '@/app/PortfolioPage';
|
||||
|
||||
export default function Home() {
|
||||
return <PortfolioPage locale="en" />;
|
||||
}
|
||||
12
src/app/(fa)/fa/layout.tsx
Normal file
12
src/app/(fa)/fa/layout.tsx
Normal 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
5
src/app/(fa)/fa/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { PortfolioPage } from '@/app/PortfolioPage';
|
||||
|
||||
export default function PersianHome() {
|
||||
return <PortfolioPage locale="fa" />;
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user