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>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { useHospitalityCapabilities } from "@/modules/hospitality/hooks/useHospitalityCapabilities";
|
|
import { HospitalityPageLoader, HospitalityPageError } from "@/modules/hospitality/pages/shared";
|
|
import { PageHeader, Card, CardContent, Badge, Input } from "@/components/ds";
|
|
import { HospitalityBreadcrumbs } from "@/modules/hospitality/components/HospitalityBreadcrumbs";
|
|
import { useMemo, useState } from "react";
|
|
|
|
export const CapabilitiesPage = function HospitalityCapabilitiesPage() {
|
|
const q = useHospitalityCapabilities();
|
|
const [search, setSearch] = useState("");
|
|
|
|
const entries = useMemo(() => {
|
|
const features = q.data?.features ?? {};
|
|
return Object.entries(features).filter(([k]) => k.toLowerCase().includes(search.toLowerCase()));
|
|
}, [q.data?.features, search]);
|
|
|
|
if (q.isLoading) return <HospitalityPageLoader />;
|
|
if (q.error) return <HospitalityPageError error={q.error} onRetry={() => q.refetch()} />;
|
|
|
|
const enabled = entries.filter(([, v]) => v).length;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<HospitalityBreadcrumbs current="قابلیتها" />
|
|
<PageHeader
|
|
title="قابلیتها"
|
|
description={`${enabled} از ${entries.length} قابلیت فعال — Bundle gating و feature flags.`}
|
|
actions={<Badge tone="info">v{q.data?.version}</Badge>}
|
|
/>
|
|
<Input
|
|
value={search}
|
|
onChange={(e) => setSearch(e.target.value)}
|
|
placeholder="جستجوی قابلیت…"
|
|
aria-label="جستجو"
|
|
className="max-w-md"
|
|
/>
|
|
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
{entries.map(([k, v]) => (
|
|
<Card key={k}>
|
|
<CardContent className="flex items-center justify-between p-4">
|
|
<span className="text-sm font-mono">{k}</span>
|
|
<Badge tone={v ? "success" : "default"}>{v ? "فعال" : "غیرفعال"}</Badge>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CapabilitiesPage;
|