feat(website): Next.js 16 marketing website with RTL/Farsi
Marketing website for Meezi platform: - Server-side rendered pages: home, demo, blog, pricing - RTL/Farsi layout with Vazirmatn font - SEO metadata and Open Graph tags - proxy.ts for Next.js 16 middleware convention - MEEZI_API_URL internal Docker network routing Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
import type { Metadata } from "next";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { Navbar } from "@/components/layout/navbar";
|
||||
import { Footer } from "@/components/layout/footer";
|
||||
import { Phone, Mail, MapPin, Clock, MessageSquare, ArrowLeft, ArrowRight } from "lucide-react";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: { locale: string };
|
||||
}): Promise<Metadata> {
|
||||
const { locale } = await Promise.resolve(params);
|
||||
const t = await getTranslations({ locale, namespace: "meta" });
|
||||
return { title: t("contactTitle") };
|
||||
}
|
||||
|
||||
const fa = {
|
||||
badge: "ارتباط با ما",
|
||||
title: "چطور میتوانیم کمک کنیم؟",
|
||||
subtitle: "تیم پشتیبانی ما آماده است. از طریق هر کانالی که راحتتری با ما در ارتباط باش.",
|
||||
channels: [
|
||||
{
|
||||
icon: Phone,
|
||||
title: "تلفن پشتیبانی",
|
||||
desc: "شنبه تا چهارشنبه، ۹ تا ۱۸",
|
||||
value: "۰۲۱-XXXX-XXXX",
|
||||
cta: "تماس بگیر",
|
||||
href: "tel:+9821XXXXXXXX",
|
||||
},
|
||||
{
|
||||
icon: Mail,
|
||||
title: "ایمیل",
|
||||
desc: "پاسخ در کمتر از ۲۴ ساعت",
|
||||
value: "support@meezi.ir",
|
||||
cta: "ارسال ایمیل",
|
||||
href: "mailto:support@meezi.ir",
|
||||
},
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "چت آنلاین",
|
||||
desc: "از داشبورد میزی در دسترس است",
|
||||
value: "چت زنده",
|
||||
cta: "ورود به داشبورد",
|
||||
href: "https://app.meezi.ir",
|
||||
},
|
||||
],
|
||||
officeTitle: "دفتر مرکزی",
|
||||
officeAddress: "تهران، ایران",
|
||||
officeHours: "شنبه تا چهارشنبه — ۹:۰۰ تا ۱۸:۰۰",
|
||||
demoTitle: "دمو رایگان میخواهی؟",
|
||||
demoDesc: "اگر میخواهی میزی را قبل از خرید امتحان کنی، یک جلسه دمو ۳۰ دقیقهای رایگان بگیر.",
|
||||
demoBtn: "درخواست دمو رایگان",
|
||||
};
|
||||
|
||||
const en = {
|
||||
badge: "Get in touch",
|
||||
title: "How can we help?",
|
||||
subtitle: "Our support team is ready. Reach us through whichever channel is most convenient for you.",
|
||||
channels: [
|
||||
{
|
||||
icon: Phone,
|
||||
title: "Phone Support",
|
||||
desc: "Saturday–Wednesday, 9 AM – 6 PM",
|
||||
value: "+98 21 XXXX XXXX",
|
||||
cta: "Call us",
|
||||
href: "tel:+9821XXXXXXXX",
|
||||
},
|
||||
{
|
||||
icon: Mail,
|
||||
title: "Email",
|
||||
desc: "Response within 24 hours",
|
||||
value: "support@meezi.ir",
|
||||
cta: "Send email",
|
||||
href: "mailto:support@meezi.ir",
|
||||
},
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "Live Chat",
|
||||
desc: "Available inside the Meezi dashboard",
|
||||
value: "Live chat",
|
||||
cta: "Go to dashboard",
|
||||
href: "https://app.meezi.ir",
|
||||
},
|
||||
],
|
||||
officeTitle: "Head Office",
|
||||
officeAddress: "Tehran, Iran",
|
||||
officeHours: "Saturday–Wednesday — 9:00 AM to 6:00 PM",
|
||||
demoTitle: "Want a free demo?",
|
||||
demoDesc: "If you'd like to try Meezi before signing up, book a free 30-minute demo session.",
|
||||
demoBtn: "Request Free Demo",
|
||||
};
|
||||
|
||||
export default async function ContactPage({
|
||||
params,
|
||||
}: {
|
||||
params: { locale: string };
|
||||
}) {
|
||||
const { locale } = await Promise.resolve(params);
|
||||
const c = locale === "fa" ? fa : en;
|
||||
const Arrow = locale === "fa" ? ArrowLeft : ArrowRight;
|
||||
const base = `/${locale}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
<main className="pt-16">
|
||||
{/* Hero */}
|
||||
<div className="bg-gradient-to-br from-brand-900 to-brand-700 pb-20 pt-16 text-center">
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full border border-white/20 bg-white/10 px-3 py-1 text-xs font-semibold text-white/80">
|
||||
{c.badge}
|
||||
</span>
|
||||
<h1 className="mt-4 text-3xl font-extrabold text-white sm:text-4xl">{c.title}</h1>
|
||||
<p className="mx-auto mt-3 max-w-lg text-lg text-white/60">{c.subtitle}</p>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto max-w-5xl px-4 pb-24 sm:px-6 lg:px-8">
|
||||
{/* Channel cards */}
|
||||
<div className="-mt-10 grid gap-6 sm:grid-cols-3">
|
||||
{c.channels.map(({ icon: Icon, title, desc, value, cta, href }) => (
|
||||
<div
|
||||
key={title}
|
||||
className="flex flex-col rounded-2xl border border-gray-100 bg-white p-7 shadow-xl shadow-gray-200/60"
|
||||
>
|
||||
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-brand-50">
|
||||
<Icon className="h-6 w-6 text-brand-700" />
|
||||
</div>
|
||||
<h2 className="mb-1 font-bold text-gray-900">{title}</h2>
|
||||
<p className="mb-1 text-xs text-gray-400">{desc}</p>
|
||||
<p className="mb-5 text-sm font-semibold text-gray-700">{value}</p>
|
||||
<a
|
||||
href={href}
|
||||
className="mt-auto inline-flex items-center gap-2 rounded-xl bg-brand-700 px-5 py-2.5 text-center text-sm font-semibold text-white transition-colors hover:bg-brand-800"
|
||||
>
|
||||
{cta}
|
||||
<Arrow className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Office info */}
|
||||
<div className="mt-12 grid gap-6 sm:grid-cols-2">
|
||||
<div className="flex gap-4 rounded-2xl border border-gray-100 bg-white p-6 shadow-sm">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-brand-50">
|
||||
<MapPin className="h-5 w-5 text-brand-700" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-1 font-semibold text-gray-900">{c.officeTitle}</h3>
|
||||
<p className="text-sm text-gray-500">{c.officeAddress}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-4 rounded-2xl border border-gray-100 bg-white p-6 shadow-sm">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-brand-50">
|
||||
<Clock className="h-5 w-5 text-brand-700" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-1 font-semibold text-gray-900">
|
||||
{locale === "fa" ? "ساعات کاری" : "Working Hours"}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500">{c.officeHours}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Demo CTA */}
|
||||
<div className="mt-12 rounded-2xl bg-gradient-to-br from-brand-900 to-brand-700 p-10 text-center">
|
||||
<h2 className="mb-3 text-2xl font-extrabold text-white">{c.demoTitle}</h2>
|
||||
<p className="mb-6 text-white/60">{c.demoDesc}</p>
|
||||
<a
|
||||
href={`${base}/demo`}
|
||||
className="inline-flex items-center gap-2 rounded-xl bg-white px-7 py-3.5 text-sm font-semibold text-brand-700 transition-colors hover:bg-brand-50"
|
||||
>
|
||||
{c.demoBtn}
|
||||
<Arrow className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user