feat(links): integrate directory into the main layout
This commit is contained in:
+140
-115
@@ -1,19 +1,26 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Icon } from "@iconify/react";
|
|
||||||
import Image from "next/image";
|
|
||||||
import { Link } from "@/i18n/routing";
|
|
||||||
import { useLocale, useTranslations } from "next-intl";
|
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
|
import { Icon } from "@iconify/react";
|
||||||
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
AvatarFallback,
|
AvatarFallback,
|
||||||
AvatarImage,
|
AvatarImage,
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Input,
|
Input,
|
||||||
Typography,
|
Typography,
|
||||||
} from "poyraz-ui/atoms";
|
} from "poyraz-ui/atoms";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "poyraz-ui/molecules";
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "poyraz-ui/molecules";
|
||||||
|
import { Link } from "@/i18n/routing";
|
||||||
import {
|
import {
|
||||||
getResumeHref,
|
getResumeHref,
|
||||||
LINK_DIRECTORY,
|
LINK_DIRECTORY,
|
||||||
@@ -37,12 +44,12 @@ const CATEGORY_ORDER = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const DIRECTORY_ITEMS = [...LINK_DIRECTORY].sort((left, right) => {
|
const DIRECTORY_ITEMS = [...LINK_DIRECTORY].sort((left, right) => {
|
||||||
const categoryCompare = CATEGORY_ORDER[left.category] - CATEGORY_ORDER[right.category];
|
const categoryCompare =
|
||||||
if (categoryCompare !== 0) {
|
CATEGORY_ORDER[left.category] - CATEGORY_ORDER[right.category];
|
||||||
return categoryCompare;
|
|
||||||
}
|
|
||||||
|
|
||||||
return left.label.localeCompare(right.label, "tr");
|
return categoryCompare !== 0
|
||||||
|
? categoryCompare
|
||||||
|
: left.label.localeCompare(right.label, "tr");
|
||||||
});
|
});
|
||||||
|
|
||||||
function normalize(value: string) {
|
function normalize(value: string) {
|
||||||
@@ -53,13 +60,8 @@ function normalize(value: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatHref(href: string) {
|
function formatHref(href: string) {
|
||||||
if (href.startsWith("mailto:")) {
|
if (href.startsWith("mailto:")) return href.replace("mailto:", "");
|
||||||
return href.replace("mailto:", "");
|
if (href.startsWith("/")) return `poyrazavsever.com${href}`;
|
||||||
}
|
|
||||||
|
|
||||||
if (href.startsWith("/")) {
|
|
||||||
return `poyrazavsever.com${href}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return href.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
return href.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
||||||
}
|
}
|
||||||
@@ -72,6 +74,10 @@ function parseCategoryFilter(value?: string): CategoryFilter {
|
|||||||
return "all";
|
return "all";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function LinkIcon({ icon, size = 18 }: { icon: string; size?: number }) {
|
||||||
|
return <Icon icon={icon} width={size} height={size} />;
|
||||||
|
}
|
||||||
|
|
||||||
export function LinksContent({
|
export function LinksContent({
|
||||||
initialCategory,
|
initialCategory,
|
||||||
initialQuery = "",
|
initialQuery = "",
|
||||||
@@ -79,19 +85,21 @@ export function LinksContent({
|
|||||||
const t = useTranslations("Links");
|
const t = useTranslations("Links");
|
||||||
const tNav = useTranslations("Nav");
|
const tNav = useTranslations("Nav");
|
||||||
const locale = useLocale();
|
const locale = useLocale();
|
||||||
|
|
||||||
const [activeCategory, setActiveCategory] = useState<CategoryFilter>(() =>
|
const [activeCategory, setActiveCategory] = useState<CategoryFilter>(() =>
|
||||||
parseCategoryFilter(initialCategory),
|
parseCategoryFilter(initialCategory),
|
||||||
);
|
);
|
||||||
const [query, setQuery] = useState(initialQuery);
|
const [query, setQuery] = useState(initialQuery);
|
||||||
|
|
||||||
const filterItems = useMemo(() => [
|
const filterItems = useMemo(
|
||||||
|
() => [
|
||||||
{ id: "all" as const, label: t("allCategories") },
|
{ id: "all" as const, label: t("allCategories") },
|
||||||
...LINK_DIRECTORY_CATEGORIES.map((item) => ({
|
...LINK_DIRECTORY_CATEGORIES.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
label: t(`categories.${item.id}`),
|
label: t(`categories.${item.id}`),
|
||||||
})),
|
})),
|
||||||
], [t]);
|
],
|
||||||
|
[t],
|
||||||
|
);
|
||||||
|
|
||||||
const filteredItems = useMemo(() => {
|
const filteredItems = useMemo(() => {
|
||||||
const normalizedQuery = normalize(query.trim());
|
const normalizedQuery = normalize(query.trim());
|
||||||
@@ -102,9 +110,7 @@ export function LinksContent({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryTokens.length === 0) {
|
if (queryTokens.length === 0) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const haystack = normalize(
|
const haystack = normalize(
|
||||||
[
|
[
|
||||||
@@ -120,116 +126,133 @@ export function LinksContent({
|
|||||||
}, [activeCategory, query, t, tNav]);
|
}, [activeCategory, query, t, tNav]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="relative isolate min-h-dvh overflow-hidden px-4 py-8 sm:px-6 sm:py-10">
|
<section className="flex h-full flex-col gap-10">
|
||||||
|
<header className="border-b border-border py-4 sm:py-5">
|
||||||
<div className="relative mx-auto flex w-full max-w-xl justify-center">
|
<div className="flex flex-col gap-5 sm:flex-row sm:items-start sm:justify-between">
|
||||||
<Card className="w-full overflow-hidden rounded-[28px] border-border/80 bg-background/95 shadow-[0_24px_80px_rgba(15,23,42,0.16)] backdrop-blur">
|
<div className="flex min-w-0 items-start gap-4">
|
||||||
<div className="relative aspect-1878/410 overflow-hidden border-b border-border/70">
|
<Avatar className="size-16 shrink-0 rounded-sm border border-border bg-background sm:size-20">
|
||||||
<Image
|
|
||||||
src="/logo/cover.png"
|
|
||||||
alt="Poyraz Avsever kapak görseli"
|
|
||||||
fill
|
|
||||||
priority
|
|
||||||
sizes="(max-width: 640px) 100vw, 576px"
|
|
||||||
className="object-cover"
|
|
||||||
/>
|
|
||||||
<div className="absolute inset-0 bg-linear-to-t from-background/20 via-transparent to-transparent" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="px-5 pb-5 pt-0 sm:px-6 sm:pb-6">
|
|
||||||
<div className="-mt-14 flex flex-col gap-4">
|
|
||||||
<Avatar className="h-24 w-24 rounded-[28px] border-4 border-background bg-background shadow-lg sm:h-28 sm:w-28">
|
|
||||||
<AvatarImage src="/logo/logo.webp" alt="Poyraz Avsever" />
|
<AvatarImage src="/logo/logo.webp" alt="Poyraz Avsever" />
|
||||||
<AvatarFallback className="rounded-3xl bg-muted text-lg font-semibold">
|
<AvatarFallback className="rounded-sm bg-muted font-semibold">
|
||||||
PA
|
PA
|
||||||
</AvatarFallback>
|
</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="min-w-0">
|
||||||
<div className="flex flex-wrap items-center gap-x-2 gap-y-1">
|
|
||||||
<Typography variant="h2" className="text-[1.75rem] leading-none sm:text-[2rem]">
|
|
||||||
Poyraz
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="h2"
|
variant="h2"
|
||||||
secondaryFont
|
component="h1"
|
||||||
className="text-[1.75rem] leading-none text-red-600 sm:text-[2rem]"
|
className="font-secondary text-2xl font-semibold leading-none tracking-[-0.045em] text-foreground"
|
||||||
>
|
>
|
||||||
Avsever
|
{t("title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
<Typography
|
||||||
|
variant="small"
|
||||||
<Typography variant="small" className="max-w-lg text-sm leading-6 text-muted-foreground">
|
className="mt-2 max-w-xl text-xs leading-5 text-muted-foreground sm:text-sm"
|
||||||
|
>
|
||||||
{t("desc")}
|
{t("desc")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
{SOCIAL_LINKS.map((item) => (
|
|
||||||
<a
|
|
||||||
key={item.id}
|
|
||||||
href={item.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
aria-label={item.label}
|
|
||||||
title={item.label}
|
|
||||||
className="inline-flex h-11 w-11 items-center justify-center rounded-2xl border border-border bg-background text-muted-foreground transition-all hover:-translate-y-0.5 hover:border-red-600/40 hover:text-foreground"
|
|
||||||
>
|
|
||||||
<Icon icon={item.icon} width={18} height={18} />
|
|
||||||
</a>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-2 sm:grid-cols-2">
|
<div
|
||||||
|
className="flex max-w-sm flex-wrap gap-2 sm:justify-end"
|
||||||
|
aria-label={t("socialLinks")}
|
||||||
|
>
|
||||||
|
{SOCIAL_LINKS.map((item) => (
|
||||||
|
<Button
|
||||||
|
key={item.id}
|
||||||
|
asChild
|
||||||
|
variant="secondary"
|
||||||
|
size="icon-sm"
|
||||||
|
radius="sm"
|
||||||
|
effect="shine"
|
||||||
|
aria-label={item.label}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href={item.href}
|
||||||
|
target={item.id === "email" ? undefined : "_blank"}
|
||||||
|
rel={item.id === "email" ? undefined : "noreferrer"}
|
||||||
|
title={item.label}
|
||||||
|
>
|
||||||
|
<LinkIcon icon={item.icon} size={16} />
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="space-y-3" aria-labelledby="quick-links-title">
|
||||||
|
<div>
|
||||||
|
<Typography
|
||||||
|
id="quick-links-title"
|
||||||
|
variant="h3"
|
||||||
|
component="h2"
|
||||||
|
className="tracking-[-0.035em]"
|
||||||
|
>
|
||||||
|
{t("quickLinks")}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="small" className="mt-1 text-muted-foreground">
|
||||||
|
{t("quickLinksDesc")}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
{TOP_ICON_LINKS.map((item) => {
|
{TOP_ICON_LINKS.map((item) => {
|
||||||
const href = item.id === "cv" ? getResumeHref(locale) : item.href;
|
const href = item.id === "cv" ? getResumeHref(locale) : item.href;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={item.id}
|
key={item.id}
|
||||||
href={href}
|
href={href}
|
||||||
target={item.id === "cv" || item.external ? "_blank" : undefined}
|
target={item.id === "cv" || item.external ? "_blank" : undefined}
|
||||||
rel={item.id === "cv" || item.external ? "noreferrer" : undefined}
|
rel={item.id === "cv" || item.external ? "noreferrer" : undefined}
|
||||||
className="block"
|
className="group block"
|
||||||
>
|
>
|
||||||
<Card className="rounded-2xl border-border bg-muted/35 p-3 transition-all hover:-translate-y-0.5 hover:border-red-600/40 hover:bg-background">
|
<Card className="h-full rounded-sm border-border p-3 transition-[border-color,transform] duration-200 group-hover:-translate-y-0.5 group-hover:border-primary/40">
|
||||||
<div className="flex items-center gap-3">
|
<span className="inline-flex size-9 items-center justify-center rounded-sm border border-border bg-muted/35 text-muted-foreground">
|
||||||
<span className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-border bg-background text-muted-foreground">
|
<LinkIcon icon={item.icon} />
|
||||||
<Icon icon={item.icon} width={18} height={18} />
|
|
||||||
</span>
|
</span>
|
||||||
<div className="min-w-0">
|
<Typography variant="large" className="mt-3 text-sm leading-tight">
|
||||||
<Typography variant="large" className="truncate text-base">
|
|
||||||
{tNav.has(item.id) ? tNav(item.id) : item.label}
|
{tNav.has(item.id) ? tNav(item.id) : item.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
variant="small"
|
variant="small"
|
||||||
className="truncate text-xs text-muted-foreground"
|
className="mt-1 truncate text-xs text-muted-foreground"
|
||||||
>
|
>
|
||||||
{formatHref(href)}
|
{formatHref(href)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div className="space-y-3 pt-1">
|
<section className="space-y-3" aria-labelledby="all-links-title">
|
||||||
|
<div className="flex flex-col gap-3 border-b border-border pb-4 md:flex-row md:items-end md:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="large" className="text-base">
|
<Typography
|
||||||
|
id="all-links-title"
|
||||||
|
variant="h3"
|
||||||
|
component="h2"
|
||||||
|
className="tracking-[-0.035em]"
|
||||||
|
>
|
||||||
{t("allLinks")}
|
{t("allLinks")}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="small" className="text-muted-foreground">
|
<Typography variant="small" className="mt-1 text-muted-foreground">
|
||||||
{t("allLinksDesc")}
|
{t("allLinksDesc")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-2 sm:grid-cols-[190px_1fr]">
|
<div className="grid w-full gap-2 sm:grid-cols-[180px_1fr] md:max-w-lg">
|
||||||
<Select
|
<Select
|
||||||
value={activeCategory}
|
value={activeCategory}
|
||||||
onValueChange={(value) => setActiveCategory(value as CategoryFilter)}
|
onValueChange={(value) =>
|
||||||
|
setActiveCategory(value as CategoryFilter)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-11 rounded-2xl border-border bg-background px-4 text-sm">
|
<SelectTrigger className="h-10 rounded-sm border-border bg-background px-3 text-sm">
|
||||||
<SelectValue placeholder={t("selectCategory")} />
|
<SelectValue placeholder={t("selectCategory")} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
@@ -245,32 +268,37 @@ export function LinksContent({
|
|||||||
value={query}
|
value={query}
|
||||||
onChange={(event) => setQuery(event.target.value)}
|
onChange={(event) => setQuery(event.target.value)}
|
||||||
placeholder={t("searchPlaceholder")}
|
placeholder={t("searchPlaceholder")}
|
||||||
aria-label={t("allLinks")}
|
aria-label={t("searchAriaLabel")}
|
||||||
className="h-11 rounded-2xl"
|
className="h-10 rounded-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2 md:grid-cols-2">
|
||||||
{filteredItems.map((item) => {
|
{filteredItems.map((item) => {
|
||||||
const href = item.id === "cv" ? getResumeHref(locale) : item.href;
|
const href = item.id === "cv" ? getResumeHref(locale) : item.href;
|
||||||
const isStaticOrExternal = item.external || item.id === "rss" || item.id === "cv" || href.endsWith(".xml") || href.endsWith(".pdf");
|
const isStaticOrExternal =
|
||||||
const CardContent = (
|
item.external ||
|
||||||
<Card className="rounded-2xl border-border p-3 transition-all hover:-translate-y-0.5 hover:border-red-600/40">
|
item.id === "rss" ||
|
||||||
|
item.id === "cv" ||
|
||||||
|
href.endsWith(".xml") ||
|
||||||
|
href.endsWith(".pdf");
|
||||||
|
const content = (
|
||||||
|
<Card className="h-full rounded-sm border-border p-3 transition-[border-color,transform] duration-200 group-hover:-translate-y-0.5 group-hover:border-primary/40">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-xl border border-border bg-muted/35 text-muted-foreground">
|
<span className="inline-flex size-10 shrink-0 items-center justify-center rounded-sm border border-border bg-muted/35 text-muted-foreground">
|
||||||
<Icon icon={item.icon} width={18} height={18} />
|
<LinkIcon icon={item.icon} />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
<Typography variant="large" className="text-base leading-tight">
|
<Typography variant="large" className="text-sm leading-tight">
|
||||||
{tNav.has(item.id) ? tNav(item.id) : item.label}
|
{tNav.has(item.id) ? tNav(item.id) : item.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
<span className="inline-flex rounded-full border border-border px-2.5 py-0.5 text-[11px] text-muted-foreground">
|
<Badge variant="secondary" radius="sm" className="text-[10px]">
|
||||||
{t(`categories.${item.category}`)}
|
{t(`categories.${item.category}`)}
|
||||||
</span>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="small"
|
variant="small"
|
||||||
className="mt-1 truncate text-xs text-muted-foreground"
|
className="mt-1 truncate text-xs text-muted-foreground"
|
||||||
@@ -279,13 +307,16 @@ export function LinksContent({
|
|||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className="text-muted-foreground">
|
|
||||||
<Icon
|
<Icon
|
||||||
icon={isStaticOrExternal ? "mdi:arrow-top-right" : "mdi:arrow-right"}
|
icon={
|
||||||
width={18}
|
isStaticOrExternal
|
||||||
height={18}
|
? "mdi:arrow-top-right"
|
||||||
|
: "mdi:arrow-right"
|
||||||
|
}
|
||||||
|
width={17}
|
||||||
|
height={17}
|
||||||
|
className="shrink-0 text-muted-foreground transition-transform duration-200 group-hover:translate-x-0.5"
|
||||||
/>
|
/>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
@@ -296,36 +327,30 @@ export function LinksContent({
|
|||||||
href={href}
|
href={href}
|
||||||
target={item.id === "cv" || item.external ? "_blank" : undefined}
|
target={item.id === "cv" || item.external ? "_blank" : undefined}
|
||||||
rel={item.id === "cv" || item.external ? "noreferrer" : undefined}
|
rel={item.id === "cv" || item.external ? "noreferrer" : undefined}
|
||||||
className="block"
|
className="group block"
|
||||||
>
|
>
|
||||||
{CardContent}
|
{content}
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<Link
|
<Link
|
||||||
key={`${item.category}-${item.id}`}
|
key={`${item.category}-${item.id}`}
|
||||||
href={href}
|
href={href}
|
||||||
target={item.external ? "_blank" : undefined}
|
className="group block"
|
||||||
rel={item.external ? "noreferrer" : undefined}
|
|
||||||
className="block"
|
|
||||||
>
|
>
|
||||||
{CardContent}
|
{content}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{filteredItems.length === 0 ? (
|
{filteredItems.length === 0 ? (
|
||||||
<Card className="rounded-2xl border-border px-4 py-5">
|
<Card className="rounded-sm border-border px-4 py-5 md:col-span-2">
|
||||||
<Typography variant="small" className="text-muted-foreground">
|
<Typography variant="small" className="text-muted-foreground">
|
||||||
{t("empty")}
|
{t("empty")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Card>
|
</Card>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-9
@@ -56,12 +56,6 @@ export const SOCIAL_LINKS = [
|
|||||||
href: "https://behance.net/poyrazavsever",
|
href: "https://behance.net/poyrazavsever",
|
||||||
icon: "mdi:behance",
|
icon: "mdi:behance",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "spotify",
|
|
||||||
label: "Spotify",
|
|
||||||
href: "https://open.spotify.com/user/3136fdjkc5p4cbzmuxhvqdd4b2hu",
|
|
||||||
icon: "mdi:spotify",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "buy-me-a-coffee",
|
id: "buy-me-a-coffee",
|
||||||
label: "Bana kahve ısmarla",
|
label: "Bana kahve ısmarla",
|
||||||
@@ -153,15 +147,67 @@ export const LINK_DIRECTORY_CATEGORIES: ReadonlyArray<{
|
|||||||
{ id: "resources", label: "Kaynaklar" },
|
{ id: "resources", label: "Kaynaklar" },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const LINK_DIRECTORY: LinkDirectoryItem[] = [
|
const STATIC_PAGE_LINKS = [
|
||||||
|
{
|
||||||
|
id: "home",
|
||||||
|
label: "Ana Sayfa",
|
||||||
|
href: "/",
|
||||||
|
icon: "mdi:home-outline",
|
||||||
|
keywords: ["ana sayfa", "home", "portfolio"],
|
||||||
|
},
|
||||||
...NAV_LINKS.map((item) => ({
|
...NAV_LINKS.map((item) => ({
|
||||||
|
...item,
|
||||||
|
icon: "mdi:compass-outline",
|
||||||
|
keywords: [item.label, item.href, "sayfa", "navigasyon", "internal"],
|
||||||
|
})),
|
||||||
|
...NAV_DROPDOWN_GROUPS.flatMap((group) =>
|
||||||
|
group.items.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
label: item.label,
|
label: item.label,
|
||||||
href: item.href,
|
href: item.href,
|
||||||
icon: "mdi:compass-outline",
|
icon: item.icon,
|
||||||
|
keywords: [...item.keywords],
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
{
|
||||||
|
id: "references",
|
||||||
|
label: "Referanslar",
|
||||||
|
href: "/about/references",
|
||||||
|
icon: "mdi:comment-quote-outline",
|
||||||
|
keywords: ["referans", "references", "testimonial", "yorum"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "volunteerCommunity",
|
||||||
|
label: "Gönüllülük ve Topluluk",
|
||||||
|
href: "/about/volunteer-community",
|
||||||
|
icon: "mdi:account-group-outline",
|
||||||
|
keywords: ["gönüllülük", "topluluk", "volunteer", "community"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "mediaKit",
|
||||||
|
label: "Medya Kiti",
|
||||||
|
href: "/media-kit",
|
||||||
|
icon: "mdi:chart-box-outline",
|
||||||
|
keywords: ["medya kiti", "media kit", "sponsor", "iş birliği"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "links",
|
||||||
|
label: "Bağlantılar",
|
||||||
|
href: "/links",
|
||||||
|
icon: "mdi:link-variant",
|
||||||
|
keywords: ["bağlantılar", "links", "link in bio"],
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const LINK_DIRECTORY: LinkDirectoryItem[] = [
|
||||||
|
...STATIC_PAGE_LINKS.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
label: item.label,
|
||||||
|
href: item.href,
|
||||||
|
icon: item.icon,
|
||||||
external: false,
|
external: false,
|
||||||
category: "navigation" as const,
|
category: "navigation" as const,
|
||||||
keywords: [item.label, item.href, "sayfa", "navigasyon", "internal"],
|
keywords: [...item.keywords],
|
||||||
})),
|
})),
|
||||||
...SOCIAL_LINKS.map((item) => ({
|
...SOCIAL_LINKS.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user