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,559 @@
|
||||
import type { Metadata } from "next";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { Navbar } from "@/components/layout/navbar";
|
||||
import { Footer } from "@/components/layout/footer";
|
||||
import { CtaBanner } from "@/components/sections/cta-banner";
|
||||
import { JsonLd } from "@/components/seo/json-ld";
|
||||
import {
|
||||
Printer, Wifi, Settings, CheckCircle2, ChevronRight,
|
||||
AlertCircle, Zap, FileText, ChefHat, Receipt, BarChart3, Smartphone,
|
||||
} from "lucide-react";
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://meezi.ir";
|
||||
|
||||
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("printerGuideTitle"),
|
||||
description: t("printerGuideDesc"),
|
||||
alternates: {
|
||||
canonical: `${BASE_URL}/${locale}/printer-guide`,
|
||||
languages: { fa: `${BASE_URL}/fa/printer-guide`, en: `${BASE_URL}/en/printer-guide` },
|
||||
},
|
||||
openGraph: { title: t("printerGuideTitle"), description: t("printerGuideDesc"), url: `${BASE_URL}/${locale}/printer-guide` },
|
||||
};
|
||||
}
|
||||
|
||||
// ── Receipt Mockups ──────────────────────────────────────────────────────────
|
||||
|
||||
function CustomerReceiptMockup({ locale }: { locale: string }) {
|
||||
const isEn = locale === "en";
|
||||
return (
|
||||
<div className="mx-auto w-52 rounded-lg border border-gray-300 bg-white font-mono shadow-lg">
|
||||
{/* Tear edge */}
|
||||
<div className="h-3 w-full rounded-t-lg bg-gray-100" style={{
|
||||
backgroundImage: "repeating-linear-gradient(90deg, transparent, transparent 6px, #d1d5db 6px, #d1d5db 8px)"
|
||||
}} />
|
||||
<div className="p-3 text-center">
|
||||
<p className="text-[11px] font-bold text-gray-900">{isEn ? "☕ Café Dorná" : "☕ کافه درنا"}</p>
|
||||
<p className="text-[9px] text-gray-500">{isEn ? "Tehran, Valiasr St." : "تهران، خ ولیعصر"}</p>
|
||||
<p className="text-[9px] text-gray-500">{isEn ? "021-88001234" : "۰۲۱-۸۸۰۰۱۲۳۴"}</p>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<p className="text-[9px] text-gray-500">
|
||||
{isEn ? "Table 7 · Order #1042" : "میز ۷ · سفارش #۱۰۴۲"}
|
||||
</p>
|
||||
<p className="text-[9px] text-gray-500">
|
||||
{isEn ? "14 Oct 2025 · 15:32" : "۱۴۰۴/۰۷/۲۲ · ۱۵:۳۲"}
|
||||
</p>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<div className="space-y-1 text-start">
|
||||
<div className="flex justify-between text-[10px]">
|
||||
<span>{isEn ? "Double Espresso ×2" : "اسپرسو دوبل ×۲"}</span>
|
||||
<span>{isEn ? "90,000" : "۹۰,۰۰۰"}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-[10px]">
|
||||
<span>{isEn ? "Chocolate Cake ×1" : "کیک شکلاتی ×۱"}</span>
|
||||
<span>{isEn ? "58,000" : "۵۸,۰۰۰"}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-[10px]">
|
||||
<span>{isEn ? "Caramel Latte ×1" : "لاته کارامل ×۱"}</span>
|
||||
<span>{isEn ? "65,000" : "۶۵,۰۰۰"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<div className="flex justify-between text-[10px]">
|
||||
<span>{isEn ? "Subtotal" : "جمع"}</span>
|
||||
<span>{isEn ? "213,000" : "۲۱۳,۰۰۰"}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-[10px]">
|
||||
<span>{isEn ? "Tax (9%)" : "مالیات (۹٪)"}</span>
|
||||
<span>{isEn ? "19,170" : "۱۹,۱۷۰"}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-[10px] font-bold">
|
||||
<span>{isEn ? "TOTAL" : "مجموع"}</span>
|
||||
<span>{isEn ? "232,170 T" : "۲۳۲,۱۷۰ ت"}</span>
|
||||
</div>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<p className="text-[10px] font-semibold">{isEn ? "💳 Card Payment" : "💳 پرداخت کارتی"}</p>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
{/* WiFi QR placeholder */}
|
||||
<div className="mx-auto mb-1 flex h-12 w-12 items-center justify-center rounded border border-gray-200 bg-gray-50">
|
||||
<Wifi className="h-6 w-6 text-gray-400" />
|
||||
</div>
|
||||
<p className="text-[9px] text-gray-500">{isEn ? "📶 WiFi: Cafe_Dorna" : "📶 WiFi: Cafe_Dorna"}</p>
|
||||
<p className="text-[9px] text-gray-500">{isEn ? "Pass: 12345678" : "پسورد: ۱۲۳۴۵۶۷۸"}</p>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<p className="text-[9px] text-gray-500">{isEn ? "Thank you! Visit again 🙏" : "ممنون از انتخاب شما 🙏"}</p>
|
||||
<p className="mt-1 text-[9px] text-gray-400">meezi.ir</p>
|
||||
</div>
|
||||
<div className="h-3 w-full rounded-b-lg bg-gray-100" style={{
|
||||
backgroundImage: "repeating-linear-gradient(90deg, transparent, transparent 6px, #d1d5db 6px, #d1d5db 8px)"
|
||||
}} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function KitchenSlipMockup({ locale }: { locale: string }) {
|
||||
const isEn = locale === "en";
|
||||
return (
|
||||
<div className="mx-auto w-52 rounded-lg border border-gray-300 bg-white font-mono shadow-lg">
|
||||
<div className="h-3 w-full rounded-t-lg bg-gray-100" style={{
|
||||
backgroundImage: "repeating-linear-gradient(90deg, transparent, transparent 6px, #d1d5db 6px, #d1d5db 8px)"
|
||||
}} />
|
||||
<div className="p-3">
|
||||
<p className="text-center text-[10px] font-bold text-gray-900">
|
||||
{isEn ? "— KITCHEN —" : "— آشپزخانه —"}
|
||||
</p>
|
||||
<div className="my-1 border-t border-gray-300" />
|
||||
<div className="flex justify-between text-[11px] font-bold text-gray-900">
|
||||
<span>{isEn ? "Table 7" : "میز ۷"}</span>
|
||||
<span>#۱۰۴۲</span>
|
||||
</div>
|
||||
<p className="text-[9px] text-gray-500">
|
||||
{isEn ? "15:32:44" : "۱۵:۳۲:۴۴"}
|
||||
</p>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<div className="space-y-1.5">
|
||||
<div className="text-[11px] font-bold text-gray-900">
|
||||
{isEn ? "2× Double Espresso" : "۲× اسپرسو دوبل"}
|
||||
</div>
|
||||
<div className="text-[11px] font-bold text-gray-900">
|
||||
{isEn ? "1× Chocolate Cake" : "۱× کیک شکلاتی"}
|
||||
</div>
|
||||
<div className="text-[11px] font-bold text-gray-900">
|
||||
{isEn ? "1× Caramel Latte" : "۱× لاته کارامل"}
|
||||
<div className="text-[9px] font-normal text-gray-600">
|
||||
{isEn ? " ↳ less sugar" : " ↳ کمشیرین"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-2 border-t border-dashed border-gray-300" />
|
||||
<p className="text-[9px] text-gray-500 text-center">
|
||||
{isEn ? "Printed by Meezi POS" : "چاپ شده توسط میزی"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="h-3 w-full rounded-b-lg bg-gray-100" style={{
|
||||
backgroundImage: "repeating-linear-gradient(90deg, transparent, transparent 6px, #d1d5db 6px, #d1d5db 8px)"
|
||||
}} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Feature cards ────────────────────────────────────────────────────────────
|
||||
|
||||
const PRINT_FEATURES = [
|
||||
{
|
||||
icon: Zap,
|
||||
titleFa: "چاپ خودکار سفارش",
|
||||
titleEn: "Auto-Print on Order",
|
||||
descFa: "به محض ثبت سفارش، فیش آشپزخانه بدون دخالت کسی به پرینتر ارسال میشود. صفر تأخیر، صفر خطا.",
|
||||
descEn: "The moment an order is placed, the kitchen slip auto-prints with zero intervention. Zero delay, zero errors.",
|
||||
color: "bg-brand-50 text-brand-700",
|
||||
},
|
||||
{
|
||||
icon: ChefHat,
|
||||
titleFa: "پرینتر KDS آشپزخانه",
|
||||
titleEn: "Kitchen Station Printer",
|
||||
descFa: "چند ایستگاه آشپزخانه؟ هر ایستگاه پرینتر جداگانه میتواند داشته باشد. نوشیدنی به بار، غذای گرم به گریل.",
|
||||
descEn: "Multiple kitchen stations? Each station gets its own printer. Drinks to bar, hot food to grill.",
|
||||
color: "bg-orange-50 text-orange-700",
|
||||
},
|
||||
{
|
||||
icon: Receipt,
|
||||
titleFa: "فیش مشتری سفارشی",
|
||||
titleEn: "Customizable Customer Receipt",
|
||||
descFa: "لوگو، سرتیتر، پاورقی، پسورد WiFi، لینک نظرسنجی و پیامهای دلخواه را روی فیش مشتری قرار دهید.",
|
||||
descEn: "Logo, header, footer, WiFi password, survey link, and custom messages on the customer receipt.",
|
||||
color: "bg-blue-50 text-blue-700",
|
||||
},
|
||||
{
|
||||
icon: FileText,
|
||||
titleFa: "تقسیم صورتحساب",
|
||||
titleEn: "Bill Splitting",
|
||||
descFa: "صورتحساب را بین مشتریان تقسیم کنید. هر بخش فیش جداگانه دارد — نقد، کارت یا ترکیبی.",
|
||||
descEn: "Split the bill among guests. Each portion prints separately — cash, card, or mixed payment.",
|
||||
color: "bg-purple-50 text-purple-700",
|
||||
},
|
||||
{
|
||||
icon: BarChart3,
|
||||
titleFa: "گزارش پایان شیفت",
|
||||
titleEn: "End-of-Shift Report",
|
||||
descFa: "با بستن شیفت، خلاصه فروش نقد/کارت و جمع سفارشها بهصورت خودکار چاپ میشود.",
|
||||
descEn: "When a shift closes, a summary of cash/card sales and total orders prints automatically.",
|
||||
color: "bg-amber-50 text-amber-700",
|
||||
},
|
||||
{
|
||||
icon: Smartphone,
|
||||
titleFa: "چاپ دستی از اپ گارسون",
|
||||
titleEn: "Manual Print from Waiter App",
|
||||
descFa: "گارسون میتواند در هر لحظه از اپ موبایل فیش مشتری یا فیش آشپزخانه را برای یک سفارش مجدداً چاپ کند.",
|
||||
descEn: "The waiter can reprint the customer receipt or kitchen slip for any order directly from the mobile app.",
|
||||
color: "bg-teal-50 text-teal-700",
|
||||
},
|
||||
];
|
||||
|
||||
const CONNECTION_STEPS_FA = [
|
||||
{
|
||||
step: "۱",
|
||||
title: "اتصال پرینتر به شبکه WiFi",
|
||||
desc: "پرینتر را به همان WiFi کافه وصل کنید. از دکمه Feed روی پرینتر برای چاپ صفحه تنظیمات استفاده کنید — آدرس IP در آن چاپ شده.",
|
||||
note: "پرینترهای رایج: Epson TM-T88, XPrinter XP-58, Bixolon SRP-350",
|
||||
},
|
||||
{
|
||||
step: "۲",
|
||||
title: "وارد کردن IP و پورت در میزی",
|
||||
desc: "در داشبورد میزی، بخش تنظیمات → پرینتر را باز کنید. آدرس IP (مثلاً 192.168.1.105) و پورت (معمولاً 9100) را وارد کنید.",
|
||||
note: "پورت پیشفرض اکثر پرینترهای ESC/POS از جمله Epson و XPrinter برابر ۹۱۰۰ است.",
|
||||
},
|
||||
{
|
||||
step: "۳",
|
||||
title: "تست چاپ",
|
||||
desc: "دکمه «چاپ تست» را بزنید. یک صفحه تست با عنوان «میزی» چاپ میشود و اتصال تأیید میشود.",
|
||||
note: "در صورت عدم چاپ: مطمئن شوید پرینتر و دستگاهی که داشبورد روی آن باز است روی یک شبکه هستند.",
|
||||
},
|
||||
{
|
||||
step: "۴",
|
||||
title: "تنظیم عرض کاغذ و قالب",
|
||||
desc: "عرض کاغذ (۵۸ یا ۸۰ میلیمتر)، سرتیتر، پاورقی، پسورد WiFi و برش خودکار را از همان صفحه تنظیم کنید.",
|
||||
note: "در صورت داشتن پرینتر آشپزخانه جداگانه، برای هر ایستگاه IP جداگانه وارد کنید.",
|
||||
},
|
||||
];
|
||||
|
||||
const CONNECTION_STEPS_EN = [
|
||||
{
|
||||
step: "1",
|
||||
title: "Connect the printer to WiFi",
|
||||
desc: "Connect the printer to the same WiFi as your cafe. Press the Feed button to print a self-test page — the IP address is printed on it.",
|
||||
note: "Common printers: Epson TM-T88, XPrinter XP-58, Bixolon SRP-350",
|
||||
},
|
||||
{
|
||||
step: "2",
|
||||
title: "Enter IP and port in Meezi",
|
||||
desc: "In the Meezi dashboard, go to Settings → Printer. Enter the IP address (e.g. 192.168.1.105) and port (usually 9100).",
|
||||
note: "Default port for most ESC/POS printers including Epson and XPrinter is 9100.",
|
||||
},
|
||||
{
|
||||
step: "3",
|
||||
title: "Test print",
|
||||
desc: "Click the 'Test Print' button. A test page with the 'Meezi' header will print, confirming the connection.",
|
||||
note: "If nothing prints: make sure the printer and the device running the dashboard are on the same network.",
|
||||
},
|
||||
{
|
||||
step: "4",
|
||||
title: "Configure paper width and template",
|
||||
desc: "Set paper width (58mm or 80mm), header, footer, WiFi password, and auto-cut from the same settings page.",
|
||||
note: "For a separate kitchen printer, enter a separate IP for each station.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function PrinterGuidePage({ params }: { params: { locale: string } }) {
|
||||
const { locale } = await Promise.resolve(params);
|
||||
const isEn = locale === "en";
|
||||
const base = `/${locale}`;
|
||||
const steps = isEn ? CONNECTION_STEPS_EN : CONNECTION_STEPS_FA;
|
||||
|
||||
return (
|
||||
<>
|
||||
<JsonLd type="SoftwareApplication" locale={locale} />
|
||||
<Navbar />
|
||||
<main className="pt-16">
|
||||
{/* Hero */}
|
||||
<div className="bg-gradient-to-br from-brand-900 to-brand-700 py-20 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">
|
||||
{isEn ? "Printer Guide" : "راهنمای پرینتر"}
|
||||
</span>
|
||||
<h1 className="mt-4 text-3xl font-extrabold text-white sm:text-4xl">
|
||||
{isEn ? "Connect your printer in 4 steps" : "پرینتر را در ۴ مرحله وصل کنید"}
|
||||
</h1>
|
||||
<p className="mx-auto mt-4 max-w-2xl text-lg text-white/60">
|
||||
{isEn
|
||||
? "Meezi supports any ESC/POS thermal printer over WiFi. No drivers, no USB — just the IP address and you're done."
|
||||
: "میزی با هر پرینتر حرارتی ESC/POS از طریق WiFi کار میکند. بدون درایور، بدون USB — فقط آدرس IP وارد کنید."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Connection Steps */}
|
||||
<section className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
|
||||
<div className="mb-12 text-center">
|
||||
<h2 className="text-2xl font-bold text-gray-900">
|
||||
{isEn ? "Setup in 4 steps" : "راهاندازی در ۴ مرحله"}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="relative space-y-0">
|
||||
{/* Vertical connector line */}
|
||||
<div className="absolute start-7 top-8 bottom-8 w-0.5 bg-brand-100 sm:start-8" />
|
||||
|
||||
{steps.map((s, i) => (
|
||||
<div key={i} className="relative flex gap-5 pb-10 last:pb-0">
|
||||
{/* Step bubble */}
|
||||
<div className="relative z-10 flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-brand-700 text-sm font-bold text-white shadow-md">
|
||||
{s.step}
|
||||
</div>
|
||||
<div className="flex-1 rounded-2xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<h3 className="mb-2 text-base font-semibold text-gray-900">{s.title}</h3>
|
||||
<p className="text-sm leading-relaxed text-gray-600">{s.desc}</p>
|
||||
<div className="mt-3 flex items-start gap-2 rounded-xl bg-brand-50 p-3">
|
||||
<AlertCircle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-brand-600" />
|
||||
<p className="text-xs text-brand-800">{s.note}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Receipt examples */}
|
||||
<section className="bg-gray-50 py-16">
|
||||
<div className="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="mb-10 text-center">
|
||||
<h2 className="text-2xl font-bold text-gray-900">
|
||||
{isEn ? "Receipt examples" : "نمونه فیشهای چاپی"}
|
||||
</h2>
|
||||
<p className="mt-2 text-gray-500">
|
||||
{isEn
|
||||
? "This is what your receipts will look like — fully customizable."
|
||||
: "این شکل فیشهای شما خواهد بود — کاملاً قابل سفارشیسازی."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-12 md:grid-cols-2">
|
||||
{/* Customer receipt */}
|
||||
<div>
|
||||
<div className="mb-5 flex items-center gap-2">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-xl bg-brand-50">
|
||||
<Receipt className="h-4 w-4 text-brand-700" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-gray-900">
|
||||
{isEn ? "Customer receipt" : "فیش مشتری"}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{isEn ? "80mm · ESC/POS" : "۸۰ میلیمتر · ESC/POS"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<CustomerReceiptMockup locale={locale} />
|
||||
<ul className="mt-5 space-y-1.5">
|
||||
{(isEn ? [
|
||||
"Cafe name, address, phone",
|
||||
"Table number and order ID",
|
||||
"All items with quantity and price",
|
||||
"Subtotal, tax, total",
|
||||
"Payment method (cash/card/mixed)",
|
||||
"WiFi password QR code",
|
||||
"Custom footer message",
|
||||
"Meezi.ir branding (optional)",
|
||||
] : [
|
||||
"نام کافه، آدرس، تلفن",
|
||||
"شماره میز و شناسه سفارش",
|
||||
"تمام آیتمها با تعداد و قیمت",
|
||||
"جمع جزء، مالیات، مجموع",
|
||||
"روش پرداخت (نقد/کارت/ترکیبی)",
|
||||
"QR کد پسورد WiFi",
|
||||
"پیام پاورقی دلخواه",
|
||||
"برندینگ میزی (اختیاری)",
|
||||
]).map((item) => (
|
||||
<li key={item} className="flex items-start gap-1.5 text-xs text-gray-600">
|
||||
<CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-brand-600" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Kitchen slip */}
|
||||
<div>
|
||||
<div className="mb-5 flex items-center gap-2">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-xl bg-orange-50">
|
||||
<ChefHat className="h-4 w-4 text-orange-700" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-gray-900">
|
||||
{isEn ? "Kitchen slip" : "فیش آشپزخانه"}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{isEn ? "58mm or 80mm · Large bold font" : "۵۸ یا ۸۰ میلیمتر · فونت درشت"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<KitchenSlipMockup locale={locale} />
|
||||
<ul className="mt-5 space-y-1.5">
|
||||
{(isEn ? [
|
||||
"Table number prominent at top",
|
||||
"Exact order time (hh:mm:ss)",
|
||||
"All items in large bold font",
|
||||
"Per-item notes (less sugar, no onion…)",
|
||||
"Order ID for tracking",
|
||||
"Separate slip per kitchen station",
|
||||
"Auto-print on order confirmation",
|
||||
"Reprint via waiter app anytime",
|
||||
] : [
|
||||
"شماره میز برجسته در بالا",
|
||||
"زمان دقیق سفارش (ثانیه:دقیقه:ساعت)",
|
||||
"تمام آیتمها با فونت درشت",
|
||||
"یادداشت هر آیتم (کمشیرین، بدون پیاز…)",
|
||||
"شناسه سفارش برای پیگیری",
|
||||
"فیش جداگانه برای هر ایستگاه",
|
||||
"چاپ خودکار پس از تأیید سفارش",
|
||||
"چاپ مجدد از اپ گارسون در هر زمان",
|
||||
]).map((item) => (
|
||||
<li key={item} className="flex items-start gap-1.5 text-xs text-gray-600">
|
||||
<CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-orange-600" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* All printing features */}
|
||||
<section className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
|
||||
<div className="mb-10 text-center">
|
||||
<h2 className="text-2xl font-bold text-gray-900">
|
||||
{isEn ? "All printing features" : "تمام ویژگیهای چاپ"}
|
||||
</h2>
|
||||
<p className="mt-2 text-gray-500">
|
||||
{isEn
|
||||
? "Everything you need for a paperless-by-choice, not paperless-by-force cafe."
|
||||
: "همهچیزی که برای یک کافه با مدیریت کاغذی کارآمد نیاز دارید."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{PRINT_FEATURES.map((f) => (
|
||||
<div
|
||||
key={f.titleFa}
|
||||
className="rounded-2xl border border-gray-100 bg-white p-6 shadow-sm hover:-translate-y-0.5 hover:shadow-md transition-all duration-200"
|
||||
>
|
||||
<div className={`mb-4 inline-flex h-11 w-11 items-center justify-center rounded-xl ${f.color}`}>
|
||||
<f.icon className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className="mb-2 text-base font-semibold text-gray-900">
|
||||
{isEn ? f.titleEn : f.titleFa}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-gray-500">
|
||||
{isEn ? f.descEn : f.descFa}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Supported printers table */}
|
||||
<section className="bg-gray-50 py-14">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="mb-6 text-center text-xl font-bold text-gray-900">
|
||||
{isEn ? "Supported printers" : "پرینترهای پشتیبانیشده"}
|
||||
</h2>
|
||||
<div className="overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-sm">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-gray-100 bg-gray-50/60">
|
||||
<th className="px-4 py-3 text-start text-xs font-semibold text-gray-500">
|
||||
{isEn ? "Model" : "مدل"}
|
||||
</th>
|
||||
<th className="px-4 py-3 text-start text-xs font-semibold text-gray-500">
|
||||
{isEn ? "Width" : "عرض"}
|
||||
</th>
|
||||
<th className="px-4 py-3 text-start text-xs font-semibold text-gray-500">
|
||||
{isEn ? "Connection" : "اتصال"}
|
||||
</th>
|
||||
<th className="px-4 py-3 text-start text-xs font-semibold text-gray-500">
|
||||
{isEn ? "Status" : "وضعیت"}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-100">
|
||||
{[
|
||||
{ model: "Epson TM-T88VI/VII", width: "80mm", conn: "WiFi / LAN", status: "✅" },
|
||||
{ model: "Epson TM-T20III", width: "80mm", conn: "WiFi / LAN", status: "✅" },
|
||||
{ model: "XPrinter XP-58IIH", width: "58mm", conn: "WiFi", status: "✅" },
|
||||
{ model: "XPrinter XP-80C", width: "80mm", conn: "WiFi / LAN", status: "✅" },
|
||||
{ model: "Bixolon SRP-350plusV", width: "80mm", conn: "LAN", status: "✅" },
|
||||
{ model: "Star TSP143IV", width: "80mm", conn: "LAN / CloudPRNT", status: "✅" },
|
||||
{ model: isEn ? "Any ESC/POS (port 9100)" : "هر ESC/POS (پورت ۹۱۰۰)", width: "58 / 80mm", conn: "WiFi / LAN", status: isEn ? "✅ Compatible" : "✅ سازگار" },
|
||||
].map((row) => (
|
||||
<tr key={row.model} className="hover:bg-gray-50/60">
|
||||
<td className="px-4 py-3 font-medium text-gray-800">{row.model}</td>
|
||||
<td className="px-4 py-3 text-gray-600">{row.width}</td>
|
||||
<td className="px-4 py-3 text-gray-600">{row.conn}</td>
|
||||
<td className="px-4 py-3 text-green-600 font-medium">{row.status}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p className="mt-4 text-center text-xs text-gray-400">
|
||||
{isEn
|
||||
? "USB printing requires the device running the dashboard to have the printer driver installed."
|
||||
: "چاپ USB نیاز به نصب درایور روی دستگاهی دارد که داشبورد روی آن اجرا میشود."}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Dashboard settings screenshot guide */}
|
||||
<section className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
|
||||
<div className="rounded-2xl border border-brand-100 bg-brand-50 p-8">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-brand-700">
|
||||
<Settings className="h-6 w-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-2 text-lg font-bold text-gray-900">
|
||||
{isEn ? "Where to find printer settings" : "کجا تنظیمات پرینتر را پیدا کنم؟"}
|
||||
</h3>
|
||||
<p className="text-gray-600 text-sm leading-relaxed">
|
||||
{isEn
|
||||
? "In your Meezi dashboard: Settings (تنظیمات) → Printer (پرینتر). You'll find sections for: Receipt Printer, Kitchen Printer, Paper Width, Auto Cut, Receipt Header, Receipt Footer, WiFi on Receipt, and Test Print."
|
||||
: "در داشبورد میزی: تنظیمات → پرینتر. بخشهای زیر را پیدا میکنید: پرینتر رسید، پرینتر آشپزخانه، عرض کاغذ، برش خودکار، سرتیتر رسید، پاورقی رسید، رمز WiFi روی رسید و تست پرینت."}
|
||||
</p>
|
||||
<div className="mt-4 grid gap-2 sm:grid-cols-2">
|
||||
{(isEn ? [
|
||||
"Receipt Printer IP + Port",
|
||||
"Kitchen Printer IP + Port",
|
||||
"Paper Width: 58mm / 80mm",
|
||||
"Auto-cut after each receipt",
|
||||
"Header text (cafe name, address)",
|
||||
"Footer text (thank you message)",
|
||||
"WiFi SSID + password on receipt",
|
||||
"Test print button",
|
||||
] : [
|
||||
"IP + پورت پرینتر رسید",
|
||||
"IP + پورت پرینتر آشپزخانه",
|
||||
"عرض کاغذ: ۵۸ یا ۸۰ میلیمتر",
|
||||
"برش خودکار پس از هر فیش",
|
||||
"سرتیتر (نام کافه، آدرس)",
|
||||
"پاورقی (پیام تشکر)",
|
||||
"SSID + پسورد WiFi روی فیش",
|
||||
"دکمه تست پرینت",
|
||||
]).map((item) => (
|
||||
<div key={item} className="flex items-center gap-2 text-sm text-gray-700">
|
||||
<Printer className="h-3.5 w-3.5 text-brand-600" />
|
||||
{item}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<a
|
||||
href="https://app.meezi.ir/fa/settings"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-5 inline-flex items-center gap-2 rounded-xl bg-brand-700 px-5 py-2.5 text-sm font-semibold text-white hover:bg-brand-800 transition-colors"
|
||||
>
|
||||
{isEn ? "Open Printer Settings" : "باز کردن تنظیمات پرینتر"}
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CtaBanner />
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user