Files
soroush.asadi 5d38312ef0
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
Marketing site (bargevasat.ir) + admin-editable store links + subdomain split
- 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>
2026-06-08 07:19:43 +03:30

86 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useState } from "react";
import { Play, Smartphone, Download } from "lucide-react";
import { fetchLinks, FALLBACK_LINKS, type SiteLinks } from "@/lib/links";
import { APP_URL } from "@/lib/site";
function BazaarIcon() {
return <span className="text-lg">🛒</span>;
}
function MyketIcon() {
return <span className="text-lg">🟢</span>;
}
export function DownloadButtons({ variant = "hero" }: { variant?: "hero" | "full" }) {
const [links, setLinks] = useState<SiteLinks>(FALLBACK_LINKS);
useEffect(() => {
let on = true;
fetchLinks().then((l) => on && setLinks(l));
return () => {
on = false;
};
}, []);
const webUrl = links.webPlayUrl || APP_URL;
return (
<div className={variant === "hero" ? "flex flex-wrap gap-3" : "grid gap-3 sm:grid-cols-2"}>
{/* Always available: play in browser */}
<a href={webUrl} className="flex items-center justify-center gap-2 rounded-2xl btn-gold px-6 py-3.5 text-base">
<Play size={18} /> بازی در مرورگر (رایگان)
</a>
{links.bazaarEnabled && links.bazaarUrl && (
<a
href={links.bazaarUrl}
target="_blank"
rel="noopener"
className="flex items-center justify-center gap-2 rounded-2xl glass px-6 py-3.5 text-base text-cream hover:border-gold/40"
>
<BazaarIcon /> کافهبازار
</a>
)}
{links.myketEnabled && links.myketUrl && (
<a
href={links.myketUrl}
target="_blank"
rel="noopener"
className="flex items-center justify-center gap-2 rounded-2xl glass px-6 py-3.5 text-base text-cream hover:border-gold/40"
>
<MyketIcon /> مایکت
</a>
)}
{links.iosPwaEnabled && (
<a
href="/download#ios"
className="flex items-center justify-center gap-2 rounded-2xl glass px-6 py-3.5 text-base text-cream hover:border-gold/40"
>
<span className="text-lg">🍏</span> نصب روی آیفون (iOS)
</a>
)}
{variant === "full" && links.iosPwaEnabled && (
<a
href="/download#android"
className="flex items-center justify-center gap-2 rounded-2xl glass px-6 py-3.5 text-base text-cream hover:border-gold/40"
>
<Smartphone size={18} /> نصب روی اندروید (PWA)
</a>
)}
{links.directApkEnabled && links.directApkUrl && (
<a
href={links.directApkUrl}
className="flex items-center justify-center gap-2 rounded-2xl glass px-6 py-3.5 text-base text-cream hover:border-gold/40"
>
<Download size={18} /> دانلود مستقیم APK
</a>
)}
</div>
);
}