Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
74 lines
2.9 KiB
TypeScript
74 lines
2.9 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useMutation } from "@tanstack/react-query";
|
||
import { toast } from "sonner";
|
||
import { useTenantId } from "@/hooks/useTenantId";
|
||
import { sportsCenterApi } from "@/modules/sports-center/services/sports-center-api";
|
||
import { SportsCenterPageLoader } from "@/modules/sports-center/pages/shared";
|
||
import { PageHeader, Card, CardContent, Button, Input, FormField } from "@/components/ds";
|
||
import { SportsCenterBreadcrumbs } from "@/modules/sports-center/components/SportsCenterBreadcrumbs";
|
||
import { SportsCenterFeatureGate } from "@/modules/sports-center/components/SportsCenterFeatureGate";
|
||
import { useSportsCenterCapabilities } from "@/modules/sports-center/hooks/useSportsCenterCapabilities";
|
||
|
||
export function ReceptionCheckInPage() {
|
||
const { tenantId } = useTenantId();
|
||
const caps = useSportsCenterCapabilities();
|
||
const [memberId, setMemberId] = useState("");
|
||
const [centerId, setCenterId] = useState("");
|
||
|
||
const checkInM = useMutation({
|
||
mutationFn: () =>
|
||
sportsCenterApi.checkIn(tenantId!, {
|
||
sports_center_id: centerId,
|
||
member_id: memberId,
|
||
}),
|
||
onSuccess: () => toast.success("چکاین انجام شد"),
|
||
onError: (e: Error) => toast.error(e.message),
|
||
});
|
||
|
||
if (!tenantId || caps.isLoading) return <SportsCenterPageLoader />;
|
||
|
||
return (
|
||
<SportsCenterFeatureGate feature="attendance_engine" capabilities={caps.data}>
|
||
<div className="mx-auto max-w-lg space-y-6">
|
||
<SportsCenterBreadcrumbs current="چکاین سریع" />
|
||
<PageHeader title="چکاین سریع" description="ثبت حضور عضو از API واقعی" />
|
||
<Card>
|
||
<CardContent className="space-y-4 p-6">
|
||
<FormField label="شناسه مرکز ورزشی">
|
||
<Input value={centerId} onChange={(e) => setCenterId(e.target.value)} />
|
||
</FormField>
|
||
<FormField label="شناسه عضو">
|
||
<Input value={memberId} onChange={(e) => setMemberId(e.target.value)} />
|
||
</FormField>
|
||
<Button
|
||
className="w-full"
|
||
disabled={!memberId || !centerId || checkInM.isPending}
|
||
onClick={() => checkInM.mutate()}
|
||
>
|
||
ثبت ورود
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</SportsCenterFeatureGate>
|
||
);
|
||
}
|
||
|
||
export function QrScannerPage() {
|
||
return (
|
||
<div className="space-y-6">
|
||
<SportsCenterBreadcrumbs current="اسکن QR" />
|
||
<PageHeader title="اسکن QR" description="اعتبارسنجی عضویت از کارت دیجیتال" />
|
||
<Card>
|
||
<CardContent className="p-6 text-sm text-[var(--muted)]">
|
||
از صفحه عضویت دیجیتال یا کارت عضویت برای صدور QR استفاده کنید.
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default ReceptionCheckInPage;
|