TorbatYar/frontend/modules/hospitality/features/hub.tsx
2026-07-28 20:39:10 +03:30

84 lines
3.5 KiB
TypeScript
Raw 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 Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { useMe } from "@/hooks/useMe";
import { useHospitalityCapabilities } from "@/modules/hospitality/hooks/useHospitalityCapabilities";
import { useHospitalityProductBrand } from "@/modules/hospitality/hooks/useHospitalityProductBrand";
import { HOSPITALITY_PORTAL } from "@/modules/hospitality/constants/portals";
import { hospitalityApi } from "@/modules/hospitality/services/hospitality-api";
import { useTenantId } from "@/hooks/useTenantId";
import { Card, CardContent, Button, LoadingState, ErrorState, Badge, StatCard } from "@/components/ds";
export const HospitalityHub = function HospitalityHubPage() {
const { me, loading, error, reload } = useMe();
const { tenantId } = useTenantId();
const caps = useHospitalityCapabilities();
const brand = useHospitalityProductBrand();
const healthQ = useQuery({
queryKey: ["hospitality", "health"],
queryFn: () => hospitalityApi.health(),
});
if (loading || caps.isLoading) return <LoadingState label="در حال بارگذاری…" />;
if (error) return <ErrorState message={error} onRetry={reload} />;
if (!me?.current_tenant_id) {
return <ErrorState message="برای استفاده از Hospitality workspace فعال لازم است." />;
}
const activeBundles = Object.entries(caps.data?.features ?? {}).filter(([, v]) => v).length;
const productLabel = brand.data?.displayName || "Hospitality";
return (
<div className="mx-auto max-w-2xl space-y-6 p-6">
<div>
<h1 className="mb-2 text-2xl font-bold text-secondary">{productLabel}</h1>
<p className="text-sm text-[var(--muted)]">
پلتفرم مهماننوازی سازمانی
{brand.data?.productCode ? ` · ${brand.data.productCode}` : ""}
{!brand.data?.displayName && brand.data?.message ? `${brand.data.message}` : ""}
</p>
</div>
<div className="grid gap-3 sm:grid-cols-3">
<StatCard label="وضعیت API" value={healthQ.data?.status === "ok" ? "سالم" : "—"} />
<StatCard label="نسخه" value={caps.data?.version ?? "—"} />
<StatCard label="بسته فعال" value={String(activeBundles)} />
</div>
<Card>
<CardContent className="space-y-4 p-6">
<div className="flex items-center justify-between">
<p className="font-medium">{HOSPITALITY_PORTAL.label}</p>
<Badge tone="primary">Tenant {tenantId?.slice(0, 8)}</Badge>
</div>
<p className="text-sm text-[var(--muted)]">{HOSPITALITY_PORTAL.description}</p>
<div className="flex flex-col gap-2">
<Link href={HOSPITALITY_PORTAL.basePath}>
<Button className="w-full">ورود به پنل مدیریت</Button>
</Link>
<Link href="/hospitality/onboarding">
<Button variant="outline" className="w-full">
ویزارد راهاندازی رستوران
</Button>
</Link>
</div>
</CardContent>
</Card>
<div className="grid gap-2 sm:grid-cols-2">
<Link href="/hospitality/ops">
<Button variant="outline" className="w-full">
مرکز عملیات
</Button>
</Link>
<Link href="/hospitality/capabilities">
<Button variant="outline" className="w-full">
قابلیتها
</Button>
</Link>
</div>
</div>
);
};
export default HospitalityHub;