TorbatYar/frontend/modules/hospitality/features/hub.tsx
Mortezakoohjani 31a0a34945 feat(loyalty): add complete Loyalty Platform Frontend module
Scaffold frontend/modules/loyalty with types, API client, design system, feature pages, and thin App Router routes. Wire all screens to backend Loyalty service via BFF proxy. Add loyalty docs and update progress.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 10:46:45 +03:30

62 lines
2.8 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 { 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 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="برای استفاده از تربت فود workspace فعال لازم است." />;
}
const activeBundles = Object.entries(caps.data?.features ?? {}).filter(([, v]) => v).length;
return (
<div className="mx-auto max-w-2xl space-y-6 p-6">
<div>
<h1 className="mb-2 text-2xl font-bold text-secondary">تربت فود</h1>
<p className="text-sm text-[var(--muted)]">پلتفرم مهماننوازی سازمانی Torbat Food</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>
<Link href={HOSPITALITY_PORTAL.basePath}>
<Button className="w-full">ورود به پنل مدیریت</Button>
</Link>
</CardContent>
</Card>
<div className="grid gap-2 sm:grid-cols-2">
<Link href="/hospitality/capabilities"><Button variant="outline" className="w-full">قابلیتها</Button></Link>
<Link href="/hospitality/health"><Button variant="outline" className="w-full">سلامت سرویس</Button></Link>
</div>
</div>
);
};
export default HospitalityHub;