feat(client): check in

Signed-off-by: Noa Virellia <noa@requiem.garden>
This commit is contained in:
2025-12-25 02:17:41 +08:00
committed by Asai Neko
parent 606c74c587
commit 9ac598cd98
5 changed files with 52 additions and 31 deletions

View File

@@ -1,31 +1,9 @@
import { Badge } from '@/components/ui/badge';
import {
Card,
CardAction,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Button } from './ui/button';
import { CheckinCard } from './workbenchCards/checkin';
export function SectionCards() {
return (
<div className="*:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card grid grid-cols-1 gap-4 px-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:shadow-xs lg:px-6 @xl/main:grid-cols-2 @5xl/main:grid-cols-4">
<Card className="@container/card">
<CardHeader>
<CardDescription></CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
</CardTitle>
<CardAction>
<Badge variant="outline">Day 1</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<Button className="w-20"></Button>
</CardFooter>
</Card>
<CheckinCard />
</div>
);
}

View File

@@ -0,0 +1,38 @@
import { toast } from 'sonner';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardAction, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { useCheckin } from '@/hooks/data/useCheckin';
export function CheckinCard() {
const { mutateAsync, isPending } = useCheckin();
return (
<Card className="@container/card">
<CardHeader>
<CardDescription></CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
</CardTitle>
<CardAction>
<Badge variant="outline">Day 1</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<Button
className="w-20"
onClick={() => {
mutateAsync().then(() => {
toast('签到成功');
}).catch((error) => {
console.error(error);
toast('签到失败');
});
}}
disabled={isPending}
>
</Button>
</CardFooter>
</Card>
);
}

View File

@@ -0,0 +1,10 @@
import { useMutation } from '@tanstack/react-query';
import { axiosClient } from '@/lib/axios';
export function useCheckin() {
return useMutation({
mutationFn: async () => {
return axiosClient.post<object>('/checkin');
},
});
}

View File

@@ -22,9 +22,7 @@ axiosClient.interceptors.response.use(undefined, async (error: AxiosError) => {
await router.navigate({ to: '/login' });
return;
}
if (error.config) {
return axiosClient(error.config);
}
else { return Promise.reject(error); }
}
return Promise.reject(error);
});

View File

@@ -4,13 +4,10 @@ import { hasToken } from '@/lib/token';
export const Route = createFileRoute('/_sidebarLayout/')({
component: Index,
beforeLoad: async ({ location }) => {
beforeLoad: async () => {
if (!hasToken()) {
throw redirect({
to: '/login',
search: {
redirect: location.href,
},
});
}
},