Marketing site (bargevasat.ir) + admin-editable store links + subdomain split
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 4m40s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 41s

- New standalone Next.js marketing site under site/ (static export, SEO):
  landing, download/install guide (Bazaar/Myket/iOS-PWA/web), FAQ (JSON-LD),
  privacy, terms, support, /admin link editor. fa RTL, sitemap/robots/manifest.
- Backend: SiteLinksService (JSON-file persisted) + GET /api/site/links (public)
  + POST /api/admin/site/links (X-Admin-Token). ADMIN_TOKEN + Site__DataDir via env.
- compose: hokm-site service (:1520) + hokm_data volume for links JSON.
- CI deploy job builds + deploys the site container.
- deploy/SUBDOMAIN_SPLIT.md: nginx blocks, cert reissue, DNS, ENV split.
- Exclude site/ from root tsc + web docker context.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-08 07:19:43 +03:30
parent 8d0d4dc991
commit 5d38312ef0
39 changed files with 8207 additions and 2 deletions
+45
View File
@@ -0,0 +1,45 @@
import type { Metadata } from "next";
import { PageShell } from "@/components/PageShell";
export const metadata: Metadata = {
title: "سوال‌های متداول",
description: "پاسخ پرسش‌های رایج دربارهٔ بازی حکم آنلاین برگ وسط — رایگان بودن، نصب، بازی با دوستان و سکه‌ها.",
alternates: { canonical: "/faq" },
};
const FAQ = [
{ q: "بازی رایگان است؟", a: "بله، برگ وسط کاملاً رایگان است. می‌توانی همهٔ بخش‌ها را بدون پرداخت بازی کنی. خرید سکه فقط اختیاری است." },
{ q: "چطور با دوستانم بازی کنم؟", a: "یک اتاق خصوصی بساز، کد اتاق را برای دوستانت بفرست و هم‌تیمی و حریف‌هایت را انتخاب کن." },
{ q: "اینترنت لازم دارم؟", a: "برای بازی آنلاین بله، اما بخش «بازی با کامپیوتر» کاملاً آفلاین کار می‌کند." },
{ q: "روی آیفون نصب می‌شود؟", a: "بله، روی iOS از طریق Safari بازی را به صفحهٔ اصلی اضافه کن (PWA). راهنمای کامل در صفحهٔ دانلود هست." },
{ q: "سکه‌ها به چه درد می‌خورند؟", a: "با سکه در لیگ‌های بالاتر بازی می‌کنی و آیتم‌های ظاهری مثل آواتار، طرح کارت و عنوان می‌خری." },
{ q: "اگر وسط بازی قطع شوم چه می‌شود؟", a: "بازی‌ات زنده می‌ماند و می‌توانی برگردی و ادامه دهی." },
{ q: "کُت (کوت) یعنی چه؟", a: "اگر تیم حاکم همهٔ ۷ دست را ببرد، حریف «کُت» می‌شود و امتیاز و جایزهٔ بیشتری می‌گیری." },
];
export default function FaqPage() {
const jsonLd = {
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: FAQ.map((f) => ({
"@type": "Question",
name: f.q,
acceptedAnswer: { "@type": "Answer", text: f.a },
})),
};
return (
<PageShell title="سوال‌های متداول">
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
<div className="space-y-3">
{FAQ.map((f) => (
<details key={f.q} className="glass group rounded-2xl p-5">
<summary className="cursor-pointer list-none text-lg font-bold text-cream marker:hidden">
{f.q}
</summary>
<p className="mt-3 text-cream/70">{f.a}</p>
</details>
))}
</div>
</PageShell>
);
}