import React, { useRef } from 'react'; import { Card, Col, Row } from 'antd'; import { ArrowRightOutlined, BankOutlined, DollarOutlined, ExclamationCircleOutlined, } from '@ant-design/icons'; import { useLocation, useNavigate } from 'react-router'; import { MARGIN_BOTTOM_16_STYLE, TODO_CARD_DANGER, TODO_CARD_DRAFT, TODO_CARD_OK, TODO_CARD_WARN } from './Dashboard.types'; /** 冷却期内忽略重复点击,避免快速/幽灵点击压入多条历史记录。 */ const TODO_CLICK_LOCK_MS = 400; export function shouldNavigateTodoCard( currentPath: string, targetPath: string, lastNavAt: number, now: number, ): boolean { if (currentPath === targetPath) return false; return now - lastNavAt >= TODO_CLICK_LOCK_MS; } export const DashboardTodoCards: React.FC<{ absentCount: number; draftCount: number; draftTotal: number; pendingDeposits: number; }> = ({ absentCount, draftCount, draftTotal, pendingDeposits }) => { const navigate = useNavigate(); const location = useLocation(); const lastNavAtRef = useRef(0); const go = (target: string) => { const now = Date.now(); if (!shouldNavigateTodoCard(location.pathname, target, lastNavAtRef.current, now)) return; lastNavAtRef.current = now; navigate(target); }; return ( 0 ? TODO_CARD_WARN : TODO_CARD_OK} styles={{ body: { padding: 16 } }} onClick={() => go('/attendance')} >
0 ? '#FF9500' : '#999' }} />
0 ? '#FF9500' : '#999', }} > {absentCount}
今日缺勤人数
{absentCount > 0 ? (
需要关注
) : (
全员到齐
)}
0 ? TODO_CARD_DRAFT : TODO_CARD_OK} styles={{ body: { padding: 16 } }} onClick={() => go('/bills')} >
0 ? '#AF52DE' : '#999' }} />
0 ? '#AF52DE' : '#999', }} > {draftCount}
待处理账单
0 ? '#AF52DE' : '#999', marginTop: 4 }} > {draftCount > 0 ? `合计 ¥${draftTotal.toLocaleString()}` : '暂无待处理'}
0 ? TODO_CARD_DANGER : TODO_CARD_OK} styles={{ body: { padding: 16 } }} onClick={() => go('/deposits')} >
0 ? '#FF3B30' : '#999' }} />
0 ? '#FF3B30' : '#999', }} > ¥{pendingDeposits.toLocaleString()}
待退押金
0 ? '#FF3B30' : '#999', marginTop: 4, }} > {pendingDeposits > 0 ? '需要处理' : '暂无待退'}
); };