diff --git a/client/cms/src/client/types.gen.ts b/client/cms/src/client/types.gen.ts
index cb65abf..1e2729a 100644
--- a/client/cms/src/client/types.gen.ts
+++ b/client/cms/src/client/types.gen.ts
@@ -10,6 +10,7 @@ export type DataEventIndexDoc = {
enable_kyc?: boolean;
end_time?: string;
event_id?: string;
+ is_checked_in?: boolean;
is_joined?: boolean;
join_count?: number;
name?: string;
@@ -501,16 +502,6 @@ export type GetEventAttendanceResponse = GetEventAttendanceResponses[keyof GetEv
export type GetEventCheckinData = {
body?: never;
- headers: {
- /**
- * latest
- */
- 'X-Api-Version': string;
- /**
- * Bearer token
- */
- Authorization: string;
- };
path?: never;
query: {
/**
@@ -610,16 +601,6 @@ export type PostEventCheckinSubmitData = {
* Checkin Code Data
*/
body: ServiceEventCheckinSubmitData;
- headers: {
- /**
- * latest
- */
- 'X-Api-Version': string;
- /**
- * Bearer token
- */
- Authorization: string;
- };
path?: never;
query?: never;
url: '/event/checkin/submit';
diff --git a/client/cms/src/client/zod.gen.ts b/client/cms/src/client/zod.gen.ts
index 0dcffaa..6e13fae 100644
--- a/client/cms/src/client/zod.gen.ts
+++ b/client/cms/src/client/zod.gen.ts
@@ -8,6 +8,7 @@ export const zDataEventIndexDoc = z.object({
enable_kyc: z.boolean().optional(),
end_time: z.string().optional(),
event_id: z.string().optional(),
+ is_checked_in: z.boolean().optional(),
is_joined: z.boolean().optional(),
join_count: z.number().int().optional(),
name: z.string().optional(),
@@ -234,10 +235,6 @@ export const zGetEventCheckinData = z.object({
path: z.never().optional(),
query: z.object({
event_id: z.string()
- }),
- headers: z.object({
- 'X-Api-Version': z.string(),
- Authorization: z.string()
})
});
@@ -266,11 +263,7 @@ export const zGetEventCheckinQueryResponse = zUtilsRespStatus.and(z.object({
export const zPostEventCheckinSubmitData = z.object({
body: zServiceEventCheckinSubmitData,
path: z.never().optional(),
- query: z.never().optional(),
- headers: z.object({
- 'X-Api-Version': z.string(),
- Authorization: z.string()
- })
+ query: z.never().optional()
});
/**
diff --git a/client/cms/src/components/checkin/checkin-qr.dialog.container.tsx b/client/cms/src/components/checkin/checkin-qr.dialog.container.tsx
new file mode 100644
index 0000000..c59b01a
--- /dev/null
+++ b/client/cms/src/components/checkin/checkin-qr.dialog.container.tsx
@@ -0,0 +1,28 @@
+import type { EventInfo } from '../events/types';
+import { isNil } from 'lodash-es';
+import { useState } from 'react';
+import { useCheckinCode } from '@/hooks/data/useCheckinCode';
+import { Dialog } from '../ui/dialog';
+import { CheckinQrDialogError } from './checkin-qr.dialog.error';
+import { CheckinQrDialogSkeleton } from './checkin-qr.dialog.skeleton';
+import { CheckinQrDialogView } from './checkin-qr.dialog.view';
+
+export function CheckinQrDialogContainer({ event, children }: { event: EventInfo; children: React.ReactNode }) {
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
+ const { data, isLoading, isError } = useCheckinCode(event.eventId, isDialogOpen);
+
+ return (
+
+ );
+}
diff --git a/client/cms/src/components/checkin/checkin-qr.dialog.error.tsx b/client/cms/src/components/checkin/checkin-qr.dialog.error.tsx
new file mode 100644
index 0000000..5fcc7f5
--- /dev/null
+++ b/client/cms/src/components/checkin/checkin-qr.dialog.error.tsx
@@ -0,0 +1,18 @@
+import { TicketX } from 'lucide-react';
+import { DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/dialog';
+
+export function CheckinQrDialogError() {
+ return (
+
+
+ 签到码
+
+ 签到码获取出错。请稍后重试。
+
+
+
+
+
+
+ );
+}
diff --git a/client/cms/src/components/checkin/checkin-qr.dialog.skeleton.tsx b/client/cms/src/components/checkin/checkin-qr.dialog.skeleton.tsx
new file mode 100644
index 0000000..64d4c84
--- /dev/null
+++ b/client/cms/src/components/checkin/checkin-qr.dialog.skeleton.tsx
@@ -0,0 +1,23 @@
+import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog';
+import { QRCode } from '../ui/shadcn-io/qr-code';
+
+export function CheckinQrDialogSkeleton() {
+ return (
+
+
+ 签到码
+
+ 请工作人员扫描下面的二维码为你签到。
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+ );
+}
diff --git a/client/cms/src/components/checkin/checkin-qr.dialog.view.tsx b/client/cms/src/components/checkin/checkin-qr.dialog.view.tsx
new file mode 100644
index 0000000..3453d45
--- /dev/null
+++ b/client/cms/src/components/checkin/checkin-qr.dialog.view.tsx
@@ -0,0 +1,23 @@
+import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog';
+import { QRCode } from '../ui/shadcn-io/qr-code';
+
+export function CheckinQrDialogView({ checkinCode }: { checkinCode: string }) {
+ return (
+
+
+ 签到码
+
+ 请工作人员扫描下面的二维码为你签到。
+
+
+
+
+
+
+
+ {checkinCode}
+
+
+
+ );
+}
diff --git a/client/cms/src/components/checkin/qr-dialog.tsx b/client/cms/src/components/checkin/qr-dialog.tsx
deleted file mode 100644
index df2a81c..0000000
--- a/client/cms/src/components/checkin/qr-dialog.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { useState } from 'react';
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
-} from '@/components/ui/dialog';
-import { QRCode } from '@/components/ui/shadcn-io/qr-code';
-import { Button } from '../ui/button';
-
-export function QrDialog(
- { eventId }: { eventId: string },
-) {
- const [open, setOpen] = useState(false);
- return (
-
- );
-}
-
-function QrSection({ eventId, enabled }: { eventId: string; enabled: boolean }) {
- // const { data } = useCheckinCode(eventId, enabled);
- const data = { data: { checkin_code: `dummy${eventId}${enabled}` } };
- return data
- ? (
- <>
-
-
-
-
-
- {data.data.checkin_code}
-
-
- >
- )
- : (
-
- );
-}
-
-function QrSectionSkeleton() {
- return (
- <>
-
-
-
-
-
- Loading...
-
-
- >
- );
-}
diff --git a/client/cms/src/components/events/event-grid/event-grid.container.tsx b/client/cms/src/components/events/event-grid/event-grid.container.tsx
index f2d258e..13e7da5 100644
--- a/client/cms/src/components/events/event-grid/event-grid.container.tsx
+++ b/client/cms/src/components/events/event-grid/event-grid.container.tsx
@@ -7,12 +7,6 @@ import { toEventInfo } from '../types';
import { EventGridSkeleton } from './event-grid.skeleton';
import { EventGridView } from './event-grid.view';
-function JoinButton() {
- return (
-
- );
-}
-
export function EventGridContainer() {
const { data, isLoading } = useEvents();
@@ -29,14 +23,14 @@ export function EventGridContainer() {
? (
-
+
)
: (
-
+
)
diff --git a/client/cms/src/components/events/joined-events.containers.tsx b/client/cms/src/components/events/joined-events.containers.tsx
index 4ebdc54..05585a0 100644
--- a/client/cms/src/components/events/joined-events.containers.tsx
+++ b/client/cms/src/components/events/joined-events.containers.tsx
@@ -1,16 +1,31 @@
import type { EventInfo } from './types';
+import { useNavigate } from '@tanstack/react-router';
import { useJoinedEvents } from '@/hooks/data/useJoinedEvents';
import { isInDateRange } from '@/lib/utils';
+import { CheckinQrDialogContainer } from '../checkin/checkin-qr.dialog.container';
import { Button } from '../ui/button';
+import { DialogTrigger } from '../ui/dialog';
import { EventGridSkeleton } from './event-grid/event-grid.skeleton';
import { EventGridView } from './event-grid/event-grid.view';
import { toEventInfo } from './types';
export function JoinedEventGridFooter({ event }: { event: EventInfo }) {
+ const isOutOfDateRange = !isInDateRange(event.startTime, event.endTime);
+ const isCheckedIn = event.isCheckedIn;
+ const canCheckIn = !isOutOfDateRange && !isCheckedIn;
+ const navigate = useNavigate();
return (
-
-
+
+
+
+
+
+
);
}
diff --git a/client/cms/src/components/events/kyc/kyc.dialog.container.tsx b/client/cms/src/components/events/kyc/kyc.dialog.container.tsx
index 1e043ee..198805c 100644
--- a/client/cms/src/components/events/kyc/kyc.dialog.container.tsx
+++ b/client/cms/src/components/events/kyc/kyc.dialog.container.tsx
@@ -1,12 +1,11 @@
import type { EventInfo } from '../types';
import type { KycSubmission } from './kyc.types';
import { Dialog } from '@radix-ui/react-dialog';
-import { useQueryClient } from '@tanstack/react-query';
import { useCallback, useEffect, useState } from 'react';
import { useStore } from 'zustand';
-import { postEventJoin, postKycQuery } from '@/client';
-import { getEventListInfiniteQueryKey } from '@/client/@tanstack/react-query.gen';
+import { postKycQuery } from '@/client';
import { useCreateKycSession } from '@/hooks/data/useCreateKycSession';
+import { useJoinEvent } from '@/hooks/data/useJoinEvent';
import { KycFailedDialogView } from './kyc-failed.dialog.view';
import { KycMethodSelectionDialogView } from './kyc-method-selection.dialog.view';
import { KycPendingDialogView } from './kyc-pending.dialog.view';
@@ -22,12 +21,12 @@ export function KycDialogContainer({ event, children }: { event: EventInfo; chil
const setStage = useStore(store, s => s.setStage);
const setKycId = useStore(store, s => s.setKycId);
- const { mutateAsync } = useCreateKycSession();
- const queryClient = useQueryClient();
+ const { mutateAsync: createKycSessionAsync } = useCreateKycSession();
+ const { mutateAsync: joinEventAsync } = useJoinEvent();
const joinEvent = useCallback(async (eventId: string, kycId: string, abortSignal?: AbortSignal) => {
try {
- await postEventJoin({
+ await joinEventAsync({
signal: abortSignal,
body: { event_id: eventId, kyc_id: kycId },
});
@@ -37,11 +36,11 @@ export function KycDialogContainer({ event, children }: { event: EventInfo; chil
console.error('Error joining event:', e);
setStage('failed');
}
- }, [setStage]);
+ }, [joinEventAsync, setStage]);
const onKycSessionCreate = useCallback(async (submission: KycSubmission) => {
try {
- const { data } = await mutateAsync(submission);
+ const { data } = await createKycSessionAsync(submission);
setKycId(data!.kyc_id!);
if (data!.status === 'success') {
await joinEvent(event.eventId, data!.kyc_id!, undefined);
@@ -55,7 +54,7 @@ export function KycDialogContainer({ event, children }: { event: EventInfo; chil
console.error(e);
setStage('failed');
}
- }, [event.eventId, joinEvent, mutateAsync, setKycId, setStage]);
+ }, [event.eventId, joinEvent, createKycSessionAsync, setKycId, setStage]);
useEffect(() => {
if (stage !== 'pending' || !isDialogOpen) {
@@ -107,14 +106,7 @@ export function KycDialogContainer({ event, children }: { event: EventInfo; chil
return (