first commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { dict, SERVICE_IDS, type ServiceId } from '@/lib/i18n/dictionaries';
|
||||
|
||||
type Params = { slug: string };
|
||||
|
||||
export function generateStaticParams() {
|
||||
return SERVICE_IDS.map((slug) => ({ slug }));
|
||||
}
|
||||
|
||||
export function generateMetadata({ params }: { params: Params }) {
|
||||
const id = params.slug as ServiceId;
|
||||
const fa = dict.fa.services.items.find((s) => s.id === id);
|
||||
const en = dict.en.services.items.find((s) => s.id === id);
|
||||
if (!en) return {};
|
||||
return {
|
||||
title: en.title,
|
||||
description: en.description,
|
||||
openGraph: { title: en.title, description: en.description },
|
||||
alternates: { canonical: `/services/${id}`, languages: { 'fa-IR': `/services/${id}`, 'en-US': `/services/${id}` } },
|
||||
other: { 'fa-title': fa?.title ?? '' },
|
||||
};
|
||||
}
|
||||
|
||||
export default function ServiceDetailPage({ params }: { params: Params }) {
|
||||
const id = params.slug as ServiceId;
|
||||
if (!SERVICE_IDS.includes(id)) notFound();
|
||||
|
||||
const en = dict.en.services.items.find((s) => s.id === id)!;
|
||||
const fa = dict.fa.services.items.find((s) => s.id === id)!;
|
||||
|
||||
return (
|
||||
<article className="relative px-5 py-32 sm:px-8">
|
||||
<div className="mx-auto max-w-3xl">
|
||||
<Link
|
||||
href="/#services"
|
||||
className="label-mono inline-flex items-center gap-2 text-slate-400 hover:text-electric"
|
||||
>
|
||||
← {dict.en.nav.services}
|
||||
</Link>
|
||||
|
||||
<h1 className="mt-6 font-display text-[clamp(2rem,4.5vw,3.4rem)] font-extrabold leading-tight text-white">
|
||||
{en.title}
|
||||
</h1>
|
||||
<p
|
||||
dir="rtl"
|
||||
className="mt-2 font-fa text-[clamp(1.1rem,2vw,1.5rem)] text-slate-400"
|
||||
>
|
||||
{fa.title}
|
||||
</p>
|
||||
|
||||
<div className="mt-8 flex flex-wrap gap-2">
|
||||
{en.tags.map((t) => (
|
||||
<span
|
||||
key={t}
|
||||
className="rounded-full border border-electric/30 bg-electric/5 px-3 py-1 font-mono text-xs text-electric"
|
||||
>
|
||||
{t}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="mt-10 text-[1.05rem] leading-relaxed text-slate-300">
|
||||
{en.description}
|
||||
</p>
|
||||
<p
|
||||
dir="rtl"
|
||||
className="mt-6 font-fa text-[1rem] leading-loose text-slate-400"
|
||||
>
|
||||
{fa.description}
|
||||
</p>
|
||||
|
||||
<div className="mt-12 flex flex-wrap gap-3">
|
||||
<Link href="/#contact" className="btn-primary">
|
||||
Book a consultation
|
||||
</Link>
|
||||
<Link href="/#services" className="btn-ghost">
|
||||
All services
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user