feat: updated about content and design template

This commit is contained in:
poyrazavsever
2026-07-16 09:13:33 +03:00
parent 79661e564d
commit f86e103b70
3 changed files with 236 additions and 110 deletions
+185 -69
View File
@@ -1,85 +1,179 @@
"use client";
import { Icon } from "@iconify/react";
import Image from "next/image";
import { Link } from "@/i18n/routing";
import { Badge, Card, Typography } from "poyraz-ui/atoms";
import { useLocale, useTranslations } from "next-intl";
import { Badge, Button, ButtonIcon, ButtonLabel, Card, Typography } from "poyraz-ui/atoms";
import { Sheet, SheetContent, SheetTitle, SheetTrigger } from "poyraz-ui/molecules";
import { StaggerContainer, StaggerItem } from "@/components/motion-wrapper";
import { Link, useRouter } from "@/i18n/routing";
import { BOOKMARKS } from "@/data/bookmarks";
import { certificates } from "@/data/certificates";
import { EDUCATION } from "@/data/education";
import { EXPERIENCE } from "@/data/experience";
import { useTranslations, useLocale } from "next-intl";
import { getLocalizedValue } from "@/lib/locale";
type TimelineItem = {
id: string;
title: string;
subtitle: string;
period: string;
description?: string;
};
function SectionHeading({
title,
action,
}: {
title: string;
action?: React.ReactNode;
}) {
return (
<div className="flex items-center justify-between gap-4">
<Typography
variant="h3"
component="h2"
className="tracking-[-0.035em]"
>
{title}
</Typography>
{action}
</div>
);
}
function TimelineList({ items }: { items: TimelineItem[] }) {
return (
<div className="relative space-y-3 before:absolute before:top-3 before:bottom-3 before:left-3 before:w-px before:bg-border">
{items.map((item) => (
<div key={item.id} className="relative grid grid-cols-[1.5rem_1fr] gap-3">
<span className="mt-3 size-6 rounded-full border border-border bg-background p-1">
<span className="block size-full rounded-full bg-primary" />
</span>
<Card className="rounded-sm border-border p-4">
<div className="flex flex-wrap items-start justify-between gap-2">
<div className="min-w-0">
<Typography variant="large" className="text-base leading-tight">
{item.title}
</Typography>
<Typography
variant="small"
className="mt-0.5 text-muted-foreground"
>
{item.subtitle}
</Typography>
</div>
<Badge variant="soft" className="rounded-sm text-primary">
{item.period}
</Badge>
</div>
{item.description ? (
<Typography
variant="small"
className="mt-3 leading-relaxed text-muted-foreground"
>
{item.description}
</Typography>
) : null}
</Card>
</div>
))}
</div>
);
}
export function AboutContent() {
const t = useTranslations("About");
const locale = useLocale();
const router = useRouter();
const educationItems: TimelineItem[] = EDUCATION.map((item) => ({
id: item.id,
title: getLocalizedValue(item.title, locale),
subtitle: item.institution,
period: getLocalizedValue(item.period, locale),
description: getLocalizedValue(item.description, locale),
}));
const experienceItems: TimelineItem[] = EXPERIENCE.map((item) => ({
id: item.id,
title: getLocalizedValue(item.role, locale),
subtitle: item.company,
period: getLocalizedValue(item.period, locale),
}));
return (
<section className="flex h-full flex-col gap-3 overflow-hidden">
<div className="grid gap-3 md:grid-cols-2">
<Card className="rounded-sm border-border p-4">
<Typography variant="p" className="text-sm leading-relaxed text-muted-foreground">
<section className="flex h-full flex-col gap-12 overflow-y-auto overflow-x-hidden">
<section className="space-y-3">
<SectionHeading
title={t("title")}
action={
<Button
type="button"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
onClick={() => router.push("/contact")}
>
<ButtonLabel>{t("contactCta")}</ButtonLabel>
<ButtonIcon>
<Icon icon="mdi:arrow-right" width={15} height={15} />
</ButtonIcon>
</Button>
}
/>
<Typography
variant="p"
className="max-w-3xl text-sm leading-7 text-muted-foreground"
>
{t("aboutText")}
</Typography>
</Card>
</section>
<div>
<StaggerContainer className="grid gap-2">
{EDUCATION.map((item) => (
<StaggerItem key={item.id}>
<Card className="rounded-sm border-border p-3">
<Typography variant="large" className="text-base leading-tight">
{getLocalizedValue(item.title, locale)}
</Typography>
<Typography variant="small" className="mt-0.5 text-muted-foreground">
{item.institution}
</Typography>
<Typography variant="small" className="mt-1 text-red-600">
{getLocalizedValue(item.period, locale)}
</Typography>
</Card>
</StaggerItem>
))}
</StaggerContainer>
</div>
<section className="grid gap-8 lg:grid-cols-2">
<div className="space-y-3">
<SectionHeading title={t("educationTitle")} />
<TimelineList items={educationItems} />
</div>
<div className="grid gap-3 md:grid-cols-2 md:items-start">
<div className="space-y-3">
<SectionHeading title={t("experienceTitle")} />
<TimelineList items={experienceItems} />
</div>
</section>
<section className="space-y-3">
<SectionHeading
title={t("certificatesTitle")}
action={
<Sheet>
<SheetTrigger asChild>
<button
<Button
type="button"
className="cursor-pointer text-left"
aria-label="Tüm sertifikaları"
size="sm"
radius="sm"
effect="swap"
swapTarget="both"
>
<Card className="rounded-sm border-border p-4 transition-colors hover:border-zinc-700">
<div className="grid grid-cols-2 gap-2">
{certificates.slice(0, 4).map((item) => (
<div
key={getLocalizedValue(item.name, locale)}
className="relative aspect-4/3 overflow-hidden rounded-sm border border-border"
>
<Image
src={item.image}
alt={getLocalizedValue(item.name, locale)}
fill
sizes="(max-width: 768px) 45vw, 22vw"
className="object-cover"
/>
</div>
))}
</div>
</Card>
</button>
<ButtonLabel>{t("allCertificates")}</ButtonLabel>
<ButtonIcon>
<Icon icon="mdi:arrow-right" width={15} height={15} />
</ButtonIcon>
</Button>
</SheetTrigger>
<SheetContent side="right" className="w-full max-w-xl p-4">
<SheetTitle>{t("allCertificates")}</SheetTitle>
<div className="mt-4 grid max-h-[90dvh] gap-3 overflow-y-auto pr-1">
{certificates.map((item) => (
<Card key={`${getLocalizedValue(item.name, locale)}-${getLocalizedValue(item.date, locale)}`} className="rounded-sm border-border p-3">
<Card
key={`${getLocalizedValue(item.name, locale)}-${getLocalizedValue(item.date, locale)}`}
className="rounded-sm border-border p-3"
>
<div className="flex gap-3">
<div className="relative h-20 w-28 shrink-0 overflow-hidden rounded-sm border border-border">
<Image
@@ -94,10 +188,13 @@ export function AboutContent() {
<Typography variant="large" className="leading-tight">
{getLocalizedValue(item.name, locale)}
</Typography>
<Typography variant="small" className="text-muted-foreground">
<Typography
variant="small"
className="text-muted-foreground"
>
{item.organization}
</Typography>
<Typography variant="small" className="text-red-600">
<Typography variant="small" className="text-primary">
{getLocalizedValue(item.date, locale)}
</Typography>
</div>
@@ -107,27 +204,46 @@ export function AboutContent() {
</div>
</SheetContent>
</Sheet>
}
/>
<div className="h-full">
<StaggerContainer className="grid gap-2">
{EXPERIENCE.map((item) => (
<StaggerItem key={item.id}>
<Card className="rounded-sm border-border p-3">
<Typography variant="large" className="text-base leading-tight">
{getLocalizedValue(item.role, locale)}
<div className="relative overflow-hidden py-1">
<div className="flex w-max items-stretch gap-3">
{certificates.slice(0, 8).map((item) => (
<Card
key={`${getLocalizedValue(item.name, locale)}-${getLocalizedValue(item.date, locale)}`}
className="w-56 shrink-0 overflow-hidden rounded-sm border-border p-0"
>
<div className="relative aspect-4/3 overflow-hidden border-b border-border">
<Image
src={item.image}
alt={getLocalizedValue(item.name, locale)}
fill
sizes="224px"
className="object-cover"
/>
</div>
<div className="p-3">
<Typography variant="large" className="line-clamp-2 text-sm leading-tight">
{getLocalizedValue(item.name, locale)}
</Typography>
<Typography variant="small" className="mt-0.5 text-muted-foreground">
{item.company}
</Typography>
<Typography variant="small" className="mt-1 text-red-600">
{getLocalizedValue(item.period, locale)}
<Typography
variant="small"
className="mt-1 text-muted-foreground"
>
{item.organization}
</Typography>
</div>
</Card>
</StaggerItem>
))}
</StaggerContainer>
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute top-0 right-0 h-full w-24 bg-gradient-to-l from-background via-background/80 to-transparent"
/>
</div>
</section>
<div className="grid gap-3 md:grid-cols-3">
<Link href="/about/references" className="block">
@@ -190,7 +306,7 @@ export function AboutContent() {
href={item.href}
target="_blank"
rel="noreferrer"
className="mt-2 inline-flex text-sm text-red-600 hover:underline"
className="mt-2 inline-flex text-sm text-primary hover:underline"
>
{item.href.replace("https://", "")}
</Link>
+6 -1
View File
@@ -32,12 +32,17 @@
}
},
"About": {
"title": "About me",
"contactCta": "Contact me",
"educationTitle": "Education",
"experienceTitle": "Experience",
"certificatesTitle": "My certificates",
"aboutText": "Ever since I met software in middle school, I've been constantly learning and improving. My passion for learning grew in high school, where I explored different web development technologies. Near the end of high school, I stepped into the mobile world. Today, I actively build, develop, and most importantly, I am still learning.",
"allCertificates": "All Certificates",
"referencesTitle": "References",
"referencesDesc": "View all references on a separate detail page.",
"volunteerTitle": "Volunteering & Community",
"volunteerDesc": "Inspect timeline and contribution details on a separate page.",
"volunteerDesc": "Explore my community work and timeline.",
"bookmarksTitle": "Bookmarks",
"bookmarksDesc": "View quick access links inside a sheet.",
"timelineLabel": "Timeline:",
+6 -1
View File
@@ -32,12 +32,17 @@
}
},
"About": {
"title": "Hakkımda",
"contactCta": "İletişime geç",
"educationTitle": "Eğitim",
"experienceTitle": "Deneyim",
"certificatesTitle": "Sertifikalarım",
"aboutText": "Ortaokulda yazılımla tanıştığımdan beri sürekli öğrenmeye ve kendimi geliştirmeye çalışıyorum. Lise yıllarında öğrenme hevesim daha da arttı ve web geliştirme tarafında farklı teknolojileri keşfetme fırsatı buldum. Lisenin sonlarına doğru mobil dünyasına da adım attım. Şu an aktif olarak üretiyor, geliştiriyor ve en önemlisi hâlâ öğrenmeye devam ediyorum.",
"allCertificates": "Tüm Sertifikalar",
"referencesTitle": "Referanslar",
"referencesDesc": "Tüm referansları ayrı bir detay sayfasında görüntüle.",
"volunteerTitle": "Gönüllülük ve Topluluk",
"volunteerDesc": "Zaman çizelgesi ve katkı detaylarını ayrı bir detay sayfasında incele.",
"volunteerDesc": "Topluluk katkılarımı ve zaman çizelgemi incele.",
"bookmarksTitle": "Yer İmleri",
"bookmarksDesc": "Hızlı erişim bağlantılarını bir sheet içinde görüntüle.",
"timelineLabel": "Zaman Çizelgesi:",