From d4d7b7e6798b7b6466473c696bc3bb794aaea12a Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Mon, 15 Jun 2026 19:00:10 +0330 Subject: [PATCH] feat(website): full Meezi knowledge base with per-feature wireframes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns the static /docs page into a real help center. Every feature now has a detail page at /docs/{slug} with a minimal wireframe mockup + concrete Persian how-to steps (English mirror), grouped into 6 sections. - guide-data.tsx: typed GUIDE_FEATURES (21 features — pos, tables, kds, queue, reservations, menu, inventory, crm, coupons, sms, reviews, reports, expenses, shifts, taxes, hr, branches, subscription, settings, qr-menu, koja) with fa/en title, tagline, 5–8 steps, tips, tier badge, group, wireframe variant. - wireframes.tsx: 7 reusable minimal line-art variants (board/order/menu/list/ dashboard/form/phone), brand-colored, RTL-aware. - docs/[slug]/page.tsx: dynamic guide page (hero, wireframe + numbered steps, tips, prev/next, support CTA); generateStaticParams + generateMetadata; 404 for unknown slugs. - docs/page.tsx: module cards now sourced from GUIDE_FEATURES, grouped, linking to the detail pages. Verified via SSR: index lists all 21, detail pages render titles + wireframe, en mirror 200, unknown slug 404, tsc clean. Co-Authored-By: Claude Opus 4.8 --- .../src/app/[locale]/docs/[slug]/page.tsx | 254 +++++ .../src/app/[locale]/docs/guide-data.tsx | 873 ++++++++++++++++++ web/website/src/app/[locale]/docs/page.tsx | 111 +-- .../src/app/[locale]/docs/wireframes.tsx | 256 +++++ 4 files changed, 1434 insertions(+), 60 deletions(-) create mode 100644 web/website/src/app/[locale]/docs/[slug]/page.tsx create mode 100644 web/website/src/app/[locale]/docs/guide-data.tsx create mode 100644 web/website/src/app/[locale]/docs/wireframes.tsx diff --git a/web/website/src/app/[locale]/docs/[slug]/page.tsx b/web/website/src/app/[locale]/docs/[slug]/page.tsx new file mode 100644 index 0000000..814f94c --- /dev/null +++ b/web/website/src/app/[locale]/docs/[slug]/page.tsx @@ -0,0 +1,254 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { Navbar } from "@/components/layout/navbar"; +import { Footer } from "@/components/layout/footer"; +import { + ArrowLeft, + ArrowRight, + ChevronLeft, + ChevronRight, + Lightbulb, + LifeBuoy, +} from "lucide-react"; +import { + GUIDE_FEATURES, + getFeatureBySlug, + TIER_LABELS, + type GuideFeature, +} from "../guide-data"; +import { Wireframe } from "../wireframes"; + +const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://meezi.ir"; + +export function generateStaticParams() { + return GUIDE_FEATURES.map((f) => ({ slug: f.slug })); +} + +export async function generateMetadata({ + params, +}: { + params: Promise<{ locale: string; slug: string }>; +}): Promise { + const { locale, slug } = await params; + const feature = getFeatureBySlug(slug); + if (!feature) return {}; + const c = locale === "fa" ? feature.fa : feature.en; + return { + title: c.title, + description: c.tagline, + alternates: { + canonical: `${BASE_URL}/${locale}/docs/${slug}`, + languages: { + fa: `${BASE_URL}/fa/docs/${slug}`, + en: `${BASE_URL}/en/docs/${slug}`, + }, + }, + openGraph: { + title: c.title, + description: c.tagline, + url: `${BASE_URL}/${locale}/docs/${slug}`, + }, + }; +} + +function siblings(feature: GuideFeature): { prev?: GuideFeature; next?: GuideFeature } { + const i = GUIDE_FEATURES.findIndex((f) => f.slug === feature.slug); + return { + prev: i > 0 ? GUIDE_FEATURES[i - 1] : undefined, + next: i < GUIDE_FEATURES.length - 1 ? GUIDE_FEATURES[i + 1] : undefined, + }; +} + +const COPY = { + fa: { + backToDocs: "راهنمای میزی", + howTo: "گام‌به‌گام", + tips: "نکته‌ها", + prev: "قبلی", + next: "بعدی", + supportTitle: "نیاز به کمک؟", + supportDesc: "تیم پشتیبانی ما آماده است. از طریق داشبورد یا ایمیل با ما در ارتباط باش.", + supportBtn: "تماس با پشتیبانی", + demoBtn: "درخواست آموزش رایگان", + }, + en: { + backToDocs: "Help Center", + howTo: "Step by step", + tips: "Tips", + prev: "Previous", + next: "Next", + supportTitle: "Need help?", + supportDesc: "Our support team is ready. Reach us through the dashboard or by email.", + supportBtn: "Contact Support", + demoBtn: "Request free training", + }, +}; + +export default async function FeatureGuidePage({ + params, +}: { + params: Promise<{ locale: string; slug: string }>; +}) { + const { locale, slug } = await params; + const feature = getFeatureBySlug(slug); + if (!feature) notFound(); + + const isEn = locale === "en"; + const base = `/${locale}`; + const c = isEn ? feature.en : feature.fa; + const t = isEn ? COPY.en : COPY.fa; + const Icon = feature.icon; + const Arrow = isEn ? ArrowRight : ArrowLeft; + // Chevron pointing "back toward docs" — start-aligned, mirrors in RTL. + const BackChevron = isEn ? ChevronLeft : ChevronRight; + const { prev, next } = siblings(feature); + + return ( + <> + +
+ {/* Hero */} +
+
+ {/* Breadcrumb back to docs */} + + + {t.backToDocs} + + +
+
+ +
+
+
+

{c.title}

+ {feature.tier && feature.tier !== "free" && ( + + {isEn ? TIER_LABELS[feature.tier].en : TIER_LABELS[feature.tier].fa} + + )} +
+

{c.tagline}

+
+
+
+
+ + {/* Two-column: wireframe + how-to */} +
+
+ {/* Wireframe (sticky on desktop) */} +
+ +
+ + {/* Numbered how-to steps */} +
+

{t.howTo}

+
    + {c.steps.map((step, i) => ( +
  1. + + {isEn ? i + 1 : toFa(i + 1)} + +

    {step}

    +
  2. + ))} +
+
+
+ + {/* Tips callout */} + {c.tips && c.tips.length > 0 && ( +
+
+ +

{t.tips}

+
+
    + {c.tips.map((tip, i) => ( +
  • + + {tip} +
  • + ))} +
+
+ )} + + {/* Prev / Next */} +
+ {prev ? ( + + +
+
{t.prev}
+
{isEn ? prev.en.title : prev.fa.title}
+
+
+ ) : ( + + + {/* Support CTA (copied from docs index) */} +
+
+
+ +
+
+

{t.supportTitle}

+

{t.supportDesc}

+
+ +
+
+
+
+