Files
sam-react-prod/src/components/business/CEODashboard/sections/ReceivableSection.tsx
유병철 23fa9c0ea2 feat: CEO 대시보드 접대비/복리후생비/매출채권/캘린더 섹션 개선 및 회계 페이지 확장
- 접대비/복리후생비 섹션: 리스크감지형 구조로 변경
- 매출채권 섹션: transformer/타입 정비
- 캘린더 섹션: ScheduleDetailModal 개선
- 카드관리 모달 transformer 확장
- useCEODashboard 훅 리팩토링 및 정리
- dashboard endpoints/types/transformers (expense, receivable, tax-benefits) 대폭 확장
- 회계 5개 페이지(은행거래, 카드거래, 매출채권, 세금계산서, 거래처원장) 기능 개선
- ApprovalBox 소폭 수정
- CLAUDE.md 업데이트
2026-03-04 22:19:10 +09:00

70 lines
2.2 KiB
TypeScript

'use client';
import { useRouter } from 'next/navigation';
import { Banknote, CircleDollarSign, Building2, TrendingUp, ChevronRight } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { AmountCardItem, CheckPointItem, CollapsibleDashboardCard, type SectionColorTheme } from '../components';
import type { ReceivableData } from '../types';
// 카드별 아이콘 매핑 (누적미수금, 당월미수금, 거래처, Top3)
const CARD_ICONS = [CircleDollarSign, Banknote, Building2, TrendingUp];
const CARD_THEMES: SectionColorTheme[] = ['amber', 'green', 'orange', 'red'];
interface ReceivableSectionProps {
data: ReceivableData;
}
export function ReceivableSection({ data }: ReceivableSectionProps) {
const router = useRouter();
const handleDetailClick = () => {
if (data.detailButtonPath) {
router.push(data.detailButtonPath);
}
};
return (
<CollapsibleDashboardCard
icon={<Banknote style={{ color: '#ffffff' }} className="h-5 w-5" />}
title="미수금 현황"
subtitle="미수금 관리 현황"
rightElement={
data.detailButtonLabel ? (
<Button
variant="ghost"
size="sm"
onClick={(e) => { e.stopPropagation(); handleDetailClick(); }}
className="text-white hover:bg-white/10 gap-1 text-xs"
>
{data.detailButtonLabel}
<ChevronRight className="h-3 w-3" />
</Button>
) : undefined
}
>
<div className="grid grid-cols-1 xs:grid-cols-2 md:grid-cols-4 gap-3 xs:gap-4 mb-4">
{data.cards.map((card, idx) => (
<AmountCardItem
key={card.id}
card={card}
onClick={handleDetailClick}
icon={CARD_ICONS[idx] || Banknote}
colorTheme={CARD_THEMES[idx] || 'amber'}
showTrend={!!card.previousLabel}
trendValue={card.previousLabel}
trendDirection={idx === 3 ? 'down' : 'up'}
/>
))}
</div>
{data.checkPoints.length > 0 && (
<div className="border-t pt-4 space-y-1">
{data.checkPoints.map((cp) => (
<CheckPointItem key={cp.id} checkpoint={cp} />
))}
</div>
)}
</CollapsibleDashboardCard>
);
}