TorbatYar/frontend/modules/loyalty/features/membership/digital-cards.tsx
Mortezakoohjani d579d0b142 feat(loyalty): add Loyalty Platform Frontend module
Add frontend/modules/loyalty with types, API client, design system, feature pages and thin App Router routes under app/loyalty/. BFF proxy at app/api/loyalty/. Include loyalty frontend docs.

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

47 lines
2.1 KiB
TypeScript

"use client";
import { useQuery } from "@tanstack/react-query";
import { PageHeader, Card, CardContent, EmptyState, Badge } from "@/components/ds";
import { loyaltyApi } from "@/modules/loyalty/services/loyalty-api";
import { useTenantId } from "@/hooks/useTenantId";
import { LoyaltyBreadcrumbs } from "@/modules/loyalty/components/LoyaltyBreadcrumbs";
import { LoyaltyPageLoader, LoyaltyPageError } from "@/modules/loyalty/pages/shared";
import { LoyaltyStatusChip } from "@/modules/loyalty/design-system";
export default function Page() {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["loyalty", tenantId, "members-cards-digital-cards.tsx"],
queryFn: () => loyaltyApi.members.list(tenantId!, { page: 1, page_size: 500 }),
enabled: !!tenantId,
});
if (!tenantId || q.isLoading) return <LoyaltyPageLoader />;
if (q.error) return <LoyaltyPageError error={q.error} onRetry={() => q.refetch()} />;
const rows = (q.data ?? []).filter((m) => !m.is_deleted);
return (
<div>
<LoyaltyBreadcrumbs items={[{ label: "کارت دیجیتال" }]} />
<PageHeader title="کارت دیجیتال" description="نمای کارت دیجیتال اعضا." />
{rows.length === 0 ? <EmptyState title="عضوی برای نمایش کارت نیست" /> : null}
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
{rows.map((m) => (
<Card key={m.id} className="overflow-hidden border-[var(--loyalty-accent)]/20">
<CardContent className="space-y-3 bg-gradient-to-br from-[var(--loyalty-accent-soft)] to-transparent pt-6">
<div className="flex items-center justify-between">
<Badge tone="primary">Loyalty</Badge>
<LoyaltyStatusChip status={m.status} domain="member" />
</div>
<p className="text-lg font-semibold">{m.display_name}</p>
<p className="font-mono text-sm tracking-wider">{m.membership_number}</p>
</CardContent>
</Card>
))}
</div>
</div>
);
}