crush-level-web/src/app/(main)/crushcoin/components/CheckInGrid.tsx

141 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useGetSevenDaysSignList, useSignIn } from '@/hooks/useHome';
import { SignInListOutput } from '@/services/home/types';
import { useQueryClient } from '@tanstack/react-query';
import { homeKeys } from '@/lib/query-keys';
import { CheckInCard } from './CheckInCard';
import { useEffect, useRef } from 'react';
import { toast } from 'sonner';
export function CheckInGrid() {
const queryClient = useQueryClient();
const { data: signListData, isLoading } = useGetSevenDaysSignList();
const signInMutation = useSignIn();
const hasSignRef = useRef(false);
useEffect(() => {
const initializeCheckIn = async () => {
if (hasSignRef.current) return;
hasSignRef.current = true;
try {
// 先进行签到
const resp = await signInMutation.mutateAsync();
if (resp) {
toast.success('Check-in Successful');
}
// 签到成功后再获取列表数据
await queryClient.invalidateQueries({
queryKey: homeKeys.getSevenDaysSignList(),
});
await queryClient.invalidateQueries({
queryKey: ['wallet'],
});
} catch (error) {
console.error('初始化签到失败:', error);
// 即使签到失败,也要获取列表数据显示界面
queryClient.invalidateQueries({
queryKey: homeKeys.getSevenDaysSignList(),
});
queryClient.invalidateQueries({
queryKey: ['wallet'],
});
}
};
if (signListData) {
initializeCheckIn();
}
}, [signListData]);
if (isLoading) {
return (
<div className="grid h-[328px] grid-cols-3 grid-rows-2 gap-4">
{Array.from({ length: 6 }).map((_, index) => (
<div
key={index}
className="animate-pulse rounded-[16px] border border-[rgba(251,222,255,0.2)] bg-[#282233]"
/>
))}
</div>
);
}
const signList = signListData?.list || [];
const today = new Date();
const todayStr = today.toISOString().split('T')[0]; // yyyy-MM-dd 格式
// 确保有7天的数据如果不足则补充默认数据
const fullSignList: (SignInListOutput & { day: number })[] = Array.from(
{ length: 7 },
(_, index) => {
const day = index + 1;
const existingData = signList.find((item, itemIndex) => itemIndex === index);
return {
day,
coinNum: existingData?.coinNum || [5, 10, 15, 20, 30, 50, 80][index],
dayStr: existingData?.dayStr || '',
signIn: existingData?.signIn || false,
};
}
);
// 找到今天应该签到的是第几天
const todayIndex = fullSignList.findIndex((item) => {
if (!item.dayStr) return false;
return item.dayStr === todayStr;
});
// 如果没有找到今天的数据,假设是按顺序签到,找到第一个未签到的
const currentDayIndex =
todayIndex >= 0 ? todayIndex : fullSignList.findIndex((item) => !item.signIn);
return (
<div className="grid grid-cols-4 grid-rows-2 gap-4">
{fullSignList.map((item, index) => {
if (index === 3) {
return (
<CheckInCard
key={fullSignList[6].day}
day={fullSignList[6].day}
coinNum={fullSignList[6].coinNum || 0}
signIn={fullSignList[6].signIn || false}
isToday={fullSignList[6].dayStr === todayStr}
loading={signInMutation.isPending}
className="col-span-1 row-span-2"
/>
);
}
if (index < 3) {
return (
<CheckInCard
key={item.day}
day={item.day}
coinNum={item.coinNum || 0}
signIn={item.signIn || false}
isToday={index === currentDayIndex}
loading={signInMutation.isPending}
className="col-span-1 row-span-1"
/>
);
} else {
return (
<CheckInCard
key={fullSignList[index - 1].day}
day={fullSignList[index - 1].day}
coinNum={fullSignList[index - 1].coinNum || 0}
signIn={fullSignList[index - 1].signIn || false}
isToday={fullSignList[index - 1].dayStr === todayStr}
loading={signInMutation.isPending}
className="col-span-1 row-span-1"
/>
);
}
})}
</div>
);
}
export default CheckInGrid;