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

139 lines
4.4 KiB
TypeScript
Raw Normal View History

2025-11-13 08:38:25 +00:00
'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 grid-cols-3 grid-rows-2 gap-4 h-[328px]">
{Array.from({ length: 6 }).map((_, index) => (
<div
key={index}
className="bg-[#282233] rounded-[16px] border border-[rgba(251,222,255,0.2)] animate-pulse"
/>
))}
</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