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>
47 lines
2.1 KiB
TypeScript
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-membership-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>
|
|
);
|
|
}
|