chore: save current workspace changes

This commit is contained in:
MOH
2026-03-14 15:57:33 +01:00
parent 143b441d0c
commit 3e9edc5873
10 changed files with 162 additions and 693 deletions
+11 -289
View File
@@ -1,16 +1,10 @@
import type { Metadata } from "next";
import { ArrowRight, BriefcaseBusiness, GraduationCap, Layers3, MapPin, Sparkles, Wrench } from "lucide-react";
import Link from "next/link";
import { getTranslations } from "next-intl/server";
import { Container } from "@/components/layout/container";
import { PageHero } from "@/components/layout/page-hero";
import { SiteLogo } from "@/components/layout/site-logo";
import { MotionFade } from "@/components/motion-fade";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { getSiteSettings, getSiteSettingsMediaBindings } from "@/lib/app-config";
import { getLocalizedPath, resolveLocale } from "@/lib/locale";
import { AppCard } from "@/components/ui/app-card";
import { resolveLocale } from "@/lib/locale";
import { buildLocalizedMetadata } from "@/lib/metadata";
type AboutPageProps = {
@@ -30,300 +24,28 @@ export async function generateMetadata({ params }: AboutPageProps): Promise<Meta
locale: localeKey,
pathname: "/about",
title: t("title"),
description: t("intro"),
description: t("description"),
});
}
export default async function AboutPage({ params }: AboutPageProps) {
const { locale } = await params;
const localeKey = resolveLocale(locale);
const [t, siteSettings, mediaBindings] = await Promise.all([
getTranslations({ locale: localeKey, namespace: "aboutPage" }),
getSiteSettings(),
getSiteSettingsMediaBindings(),
]);
const siteName = siteSettings.locales[localeKey].siteName;
const workItems = [
{
period: t("workOnePeriod"),
role: t("workOneRole"),
company: t("workOneCompany"),
text: t("workOneText"),
},
{
period: t("workTwoPeriod"),
role: t("workTwoRole"),
company: t("workTwoCompany"),
text: t("workTwoText"),
},
{
period: t("workThreePeriod"),
role: t("workThreeRole"),
company: t("workThreeCompany"),
text: t("workThreeText"),
},
];
const educationItems = [
{
title: t("educationOneTitle"),
place: t("educationOnePlace"),
text: t("educationOneText"),
},
{
title: t("educationTwoTitle"),
place: t("educationTwoPlace"),
text: t("educationTwoText"),
},
];
const skillItems = [t("skillOne"), t("skillTwo"), t("skillThree"), t("skillFour"), t("skillFive"), t("skillSix")];
const toolItems = [t("toolOne"), t("toolTwo"), t("toolThree"), t("toolFour")];
const focusItems = [t("focusOne"), t("focusTwo"), t("focusThree")];
const t = await getTranslations({ locale: localeKey, namespace: "aboutPage" });
return (
<>
<PageHero
locale={localeKey}
badge={t("heroBadge")}
title={t("heroTitle")}
description={t("intro")}
badge={t("heroEyebrow")}
title={t("title")}
description={t("description")}
/>
<Container className="relative z-10 flex flex-col gap-8 pb-12 lg:pb-16">
<MotionFade delay={0.05}>
<section className="grid gap-8 border-b border-border/70 pb-8 lg:grid-cols-12">
<div className="lg:col-span-9">
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("storyEyebrow")}
</Badge>
<h2 className="mt-5 max-w-[11ch] text-balance text-4xl font-semibold leading-[0.92] tracking-[-0.06em] text-foreground sm:text-5xl lg:text-6xl">
{t("storyTitle")}
</h2>
<div className="mt-6 grid gap-5 lg:grid-cols-[minmax(0,1fr)_minmax(15rem,18rem)]">
<div className="space-y-4">
<p className="text-sm leading-7 text-muted-foreground sm:text-base">
{t("storyTextOne")}
</p>
<p className="text-sm leading-7 text-muted-foreground sm:text-base">
{t("storyTextTwo")}
</p>
</div>
<div className="space-y-3">
{focusItems.map((item) => (
<div key={item} className="rounded-nested border border-border/70 bg-surface-2/70 px-4 py-4 text-sm font-medium leading-6 text-foreground/84">
{item}
</div>
))}
</div>
</div>
<div className="mt-8 flex flex-wrap gap-3">
<Button asChild size="lg" className="min-w-[11rem]">
<Link href={getLocalizedPath(localeKey, "/contact")}>
{t("primaryCta")}
<ArrowRight className="h-4 w-4" />
</Link>
</Button>
<Button
asChild
size="lg"
variant="outline"
className="min-w-[11rem] border-border/80 bg-background/70 hover:bg-background"
>
<Link href={getLocalizedPath(localeKey, "/portfolio")}>
{t("secondaryCta")}
</Link>
</Button>
</div>
</div>
<aside className="flex flex-col gap-5 lg:col-span-3">
<div className="rounded-surface border border-border/70 bg-surface-2/65 p-5">
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("snapshotEyebrow")}
</Badge>
<div className="mt-5 flex items-center justify-between gap-4">
<div>
<h3 className="text-lg font-semibold text-foreground">{t("snapshotTitle")}</h3>
<p className="mt-2 text-sm leading-6 text-muted-foreground">{t("snapshotText")}</p>
</div>
<SiteLogo
alt={siteName}
priority
lightLogoUrl={mediaBindings.siteLogoLight?.url}
darkLogoUrl={mediaBindings.siteLogoDark?.url}
className="h-10 sm:h-11"
/>
</div>
</div>
<div className="rounded-surface border border-border/70 bg-background/40 p-5">
<div className="flex items-start gap-3">
<MapPin className="mt-0.5 h-4 w-4 text-brand-primary" />
<div>
<p className="text-sm font-semibold text-foreground">{t("locationTitle")}</p>
<p className="mt-1 text-sm leading-6 text-muted-foreground">{t("locationText")}</p>
</div>
</div>
</div>
</aside>
</section>
</MotionFade>
<MotionFade delay={0.1}>
<section className="grid gap-8 border-b border-border/70 pb-8 lg:grid-cols-10">
<div className="lg:col-span-4">
<div className="flex items-start justify-between gap-4">
<div>
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("experienceEyebrow")}
</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-[-0.04em] text-foreground">
{t("experienceTitle")}
</h2>
</div>
<BriefcaseBusiness className="h-5 w-5 text-brand-primary" />
</div>
<div className="mt-6 space-y-5">
{workItems.map((item, index) => (
<div
key={`${item.period}-${item.role}`}
className={index === 0 ? "" : "border-t border-border/70 pt-5"}
>
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-foreground/50">
{item.period}
</p>
<h3 className="mt-3 text-lg font-semibold text-foreground">{item.role}</h3>
<p className="mt-1 text-sm font-medium text-foreground/72">{item.company}</p>
<p className="mt-3 text-sm leading-6 text-muted-foreground">{item.text}</p>
</div>
))}
</div>
</div>
<div className="lg:col-span-6">
<div className="flex items-start justify-between gap-4">
<div>
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("educationEyebrow")}
</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-[-0.04em] text-foreground">
{t("educationTitle")}
</h2>
<p className="mt-4 max-w-[34rem] text-sm leading-7 text-muted-foreground">
{t("educationIntro")}
</p>
</div>
<GraduationCap className="h-5 w-5 text-brand-primary" />
</div>
<div className="mt-6 grid gap-6 md:grid-cols-2">
{educationItems.map((item) => (
<div key={item.title} className="rounded-surface border border-border/70 bg-surface-2/60 p-5">
<p className="text-sm font-semibold uppercase tracking-[0.16em] text-foreground/50">
{item.place}
</p>
<h3 className="mt-3 text-xl font-semibold text-foreground">{item.title}</h3>
<p className="mt-3 text-sm leading-6 text-muted-foreground">{item.text}</p>
</div>
))}
</div>
</div>
</section>
</MotionFade>
<MotionFade delay={0.15}>
<section className="grid gap-8 lg:grid-cols-10">
<div className="lg:col-span-6">
<div className="flex items-start justify-between gap-4">
<div>
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("skillsEyebrow")}
</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-[-0.04em] text-foreground">
{t("skillsTitle")}
</h2>
<p className="mt-4 max-w-[34rem] text-sm leading-7 text-muted-foreground">
{t("skillsIntro")}
</p>
</div>
<Layers3 className="h-5 w-5 text-brand-primary" />
</div>
<div className="mt-6 flex flex-wrap gap-3">
{skillItems.map((item) => (
<span
key={item}
className="inline-flex items-center rounded-pill border border-border/70 bg-surface-2/70 px-4 py-2 text-sm font-medium text-foreground/84"
>
{item}
</span>
))}
</div>
</div>
<div className="lg:col-span-2">
<div className="flex items-center justify-between gap-3">
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("toolsEyebrow")}
</Badge>
<Wrench className="h-4 w-4 text-brand-primary" />
</div>
<div className="mt-5 space-y-3">
{toolItems.map((item) => (
<div key={item} className="rounded-surface border border-border/70 bg-surface-2/60 px-4 py-3 text-sm font-medium text-foreground/84">
{item}
</div>
))}
</div>
</div>
<div className="lg:col-span-2">
<div className="flex items-center justify-between gap-3">
<Badge
variant="outline"
className="border-border/70 bg-background/80 px-3 py-1.5 text-[0.72rem] font-semibold tracking-[0.18em] text-foreground/60"
>
{t("focusEyebrow")}
</Badge>
<Sparkles className="h-4 w-4 text-brand-primary" />
</div>
<div className="mt-5 space-y-3">
{focusItems.map((item) => (
<div key={item} className="rounded-surface border border-border/70 bg-background/40 px-4 py-4 text-sm leading-6 text-foreground/84">
{item}
</div>
))}
</div>
</div>
</section>
</MotionFade>
<Container className="pb-16 lg:pb-20">
<AppCard level={3} padding="lg" className="mx-auto max-w-3xl text-center">
<p className="text-lg font-medium text-foreground">{t("placeholder")}</p>
</AppCard>
</Container>
</>
);