feat: updated about content and design template
This commit is contained in:
+224
-108
@@ -1,133 +1,249 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { Icon } from "@iconify/react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Link } from "@/i18n/routing";
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
import { Badge, Card, Typography } from "poyraz-ui/atoms";
|
import { Badge, Button, ButtonIcon, ButtonLabel, Card, Typography } from "poyraz-ui/atoms";
|
||||||
import { Sheet, SheetContent, SheetTitle, SheetTrigger } from "poyraz-ui/molecules";
|
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 { BOOKMARKS } from "@/data/bookmarks";
|
||||||
import { certificates } from "@/data/certificates";
|
import { certificates } from "@/data/certificates";
|
||||||
import { EDUCATION } from "@/data/education";
|
import { EDUCATION } from "@/data/education";
|
||||||
import { EXPERIENCE } from "@/data/experience";
|
import { EXPERIENCE } from "@/data/experience";
|
||||||
import { useTranslations, useLocale } from "next-intl";
|
|
||||||
import { getLocalizedValue } from "@/lib/locale";
|
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() {
|
export function AboutContent() {
|
||||||
const t = useTranslations("About");
|
const t = useTranslations("About");
|
||||||
const locale = useLocale();
|
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 (
|
return (
|
||||||
<section className="flex h-full flex-col gap-3 overflow-hidden">
|
<section className="flex h-full flex-col gap-12 overflow-y-auto overflow-x-hidden">
|
||||||
<div className="grid gap-3 md:grid-cols-2">
|
<section className="space-y-3">
|
||||||
<Card className="rounded-sm border-border p-4">
|
<SectionHeading
|
||||||
<Typography variant="p" className="text-sm leading-relaxed text-muted-foreground">
|
title={t("title")}
|
||||||
{t("aboutText")}
|
action={
|
||||||
</Typography>
|
<Button
|
||||||
</Card>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid gap-3 md:grid-cols-2 md:items-start">
|
|
||||||
<Sheet>
|
|
||||||
<SheetTrigger asChild>
|
|
||||||
<button
|
|
||||||
type="button"
|
type="button"
|
||||||
className="cursor-pointer text-left"
|
size="sm"
|
||||||
aria-label="Tüm sertifikaları aç"
|
radius="sm"
|
||||||
|
effect="swap"
|
||||||
|
swapTarget="both"
|
||||||
|
onClick={() => router.push("/contact")}
|
||||||
>
|
>
|
||||||
<Card className="rounded-sm border-border p-4 transition-colors hover:border-zinc-700">
|
<ButtonLabel>{t("contactCta")}</ButtonLabel>
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<ButtonIcon>
|
||||||
{certificates.slice(0, 4).map((item) => (
|
<Icon icon="mdi:arrow-right" width={15} height={15} />
|
||||||
<div
|
</ButtonIcon>
|
||||||
key={getLocalizedValue(item.name, locale)}
|
</Button>
|
||||||
className="relative aspect-4/3 overflow-hidden rounded-sm border border-border"
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
variant="p"
|
||||||
|
className="max-w-3xl text-sm leading-7 text-muted-foreground"
|
||||||
|
>
|
||||||
|
{t("aboutText")}
|
||||||
|
</Typography>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="grid gap-8 lg:grid-cols-2">
|
||||||
|
<div className="space-y-3">
|
||||||
|
<SectionHeading title={t("educationTitle")} />
|
||||||
|
<TimelineList items={educationItems} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
radius="sm"
|
||||||
|
effect="swap"
|
||||||
|
swapTarget="both"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
>
|
>
|
||||||
<Image
|
<div className="flex gap-3">
|
||||||
src={item.image}
|
<div className="relative h-20 w-28 shrink-0 overflow-hidden rounded-sm border border-border">
|
||||||
alt={getLocalizedValue(item.name, locale)}
|
<Image
|
||||||
fill
|
src={item.image}
|
||||||
sizes="(max-width: 768px) 45vw, 22vw"
|
alt={getLocalizedValue(item.name, locale)}
|
||||||
className="object-cover"
|
fill
|
||||||
/>
|
sizes="112px"
|
||||||
</div>
|
className="object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0">
|
||||||
|
<Typography variant="large" className="leading-tight">
|
||||||
|
{getLocalizedValue(item.name, locale)}
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="small"
|
||||||
|
className="text-muted-foreground"
|
||||||
|
>
|
||||||
|
{item.organization}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="small" className="text-primary">
|
||||||
|
{getLocalizedValue(item.date, locale)}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<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-1 text-muted-foreground"
|
||||||
|
>
|
||||||
|
{item.organization}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</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">
|
|
||||||
<div className="flex gap-3">
|
|
||||||
<div className="relative h-20 w-28 shrink-0 overflow-hidden rounded-sm border border-border">
|
|
||||||
<Image
|
|
||||||
src={item.image}
|
|
||||||
alt={getLocalizedValue(item.name, locale)}
|
|
||||||
fill
|
|
||||||
sizes="112px"
|
|
||||||
className="object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="min-w-0">
|
|
||||||
<Typography variant="large" className="leading-tight">
|
|
||||||
{getLocalizedValue(item.name, locale)}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="small" className="text-muted-foreground">
|
|
||||||
{item.organization}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="small" className="text-red-600">
|
|
||||||
{getLocalizedValue(item.date, locale)}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
))}
|
|
||||||
</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)}
|
|
||||||
</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>
|
|
||||||
</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>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<div className="grid gap-3 md:grid-cols-3">
|
<div className="grid gap-3 md:grid-cols-3">
|
||||||
<Link href="/about/references" className="block">
|
<Link href="/about/references" className="block">
|
||||||
@@ -190,7 +306,7 @@ export function AboutContent() {
|
|||||||
href={item.href}
|
href={item.href}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
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://", "")}
|
{item.href.replace("https://", "")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
+6
-1
@@ -32,12 +32,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"About": {
|
"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.",
|
"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",
|
"allCertificates": "All Certificates",
|
||||||
"referencesTitle": "References",
|
"referencesTitle": "References",
|
||||||
"referencesDesc": "View all references on a separate detail page.",
|
"referencesDesc": "View all references on a separate detail page.",
|
||||||
"volunteerTitle": "Volunteering & Community",
|
"volunteerTitle": "Volunteering & Community",
|
||||||
"volunteerDesc": "Inspect timeline and contribution details on a separate page.",
|
"volunteerDesc": "Explore my community work and timeline.",
|
||||||
"bookmarksTitle": "Bookmarks",
|
"bookmarksTitle": "Bookmarks",
|
||||||
"bookmarksDesc": "View quick access links inside a sheet.",
|
"bookmarksDesc": "View quick access links inside a sheet.",
|
||||||
"timelineLabel": "Timeline:",
|
"timelineLabel": "Timeline:",
|
||||||
|
|||||||
+6
-1
@@ -32,12 +32,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"About": {
|
"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.",
|
"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",
|
"allCertificates": "Tüm Sertifikalar",
|
||||||
"referencesTitle": "Referanslar",
|
"referencesTitle": "Referanslar",
|
||||||
"referencesDesc": "Tüm referansları ayrı bir detay sayfasında görüntüle.",
|
"referencesDesc": "Tüm referansları ayrı bir detay sayfasında görüntüle.",
|
||||||
"volunteerTitle": "Gönüllülük ve Topluluk",
|
"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",
|
"bookmarksTitle": "Yer İmleri",
|
||||||
"bookmarksDesc": "Hızlı erişim bağlantılarını bir sheet içinde görüntüle.",
|
"bookmarksDesc": "Hızlı erişim bağlantılarını bir sheet içinde görüntüle.",
|
||||||
"timelineLabel": "Zaman Çizelgesi:",
|
"timelineLabel": "Zaman Çizelgesi:",
|
||||||
|
|||||||
Reference in New Issue
Block a user