'use client'; /** * 카드 내역 불러오기 팝업 (팝업 in 팝업) * * - ManualEntryModal 위에 z-index로 표시 * - 날짜범위 + 가맹점/승인번호 검색 + 조회 * - 빈 상태: "카드 내역이 없습니다." * - 테이블: 날짜, 가맹점, 금액, 승인번호, 선택 버튼 * - 선택 시 부모에 데이터 전달 후 닫기 */ import { useState, useCallback } from 'react'; import { toast } from 'sonner'; import { formatNumber } from '@/lib/utils/amount'; import { Search } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { DatePicker } from '@/components/ui/date-picker'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { getTodayString, getLocalDateString } from '@/lib/utils/date'; import { getCardHistory } from './actions'; import type { CardHistoryRecord } from './types'; interface CardHistoryModalProps { open: boolean; onOpenChange: (open: boolean) => void; onSelect: (record: CardHistoryRecord) => void; } export function CardHistoryModal({ open, onOpenChange, onSelect, }: CardHistoryModalProps) { const today = getTodayString(); const monthAgo = getLocalDateString(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)); const [startDate, setStartDate] = useState(monthAgo); const [endDate, setEndDate] = useState(today); const [searchText, setSearchText] = useState(''); const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [hasSearched, setHasSearched] = useState(false); const handleSearch = useCallback(async () => { setIsLoading(true); setHasSearched(true); try { const result = await getCardHistory({ startDate, endDate, search: searchText, page: 1, perPage: 50, }); if (result.success) { setData(result.data ?? []); } else { toast.error(result.error || '카드 내역 조회에 실패했습니다.'); } } catch { toast.error('서버 오류가 발생했습니다.'); } finally { setIsLoading(false); } }, [startDate, endDate, searchText]); return ( 카드 내역 불러오기 {/* 검색 영역 */}
{/* Row1: 날짜 범위 */}
~
{/* Row2: 검색어 + 조회 */}
setSearchText(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} className="flex-1 h-9 text-sm" />
{/* 테이블 영역 */}
{!hasSearched ? (
조회 버튼을 클릭하여 카드 내역을 검색하세요.
) : isLoading ? (
조회 중...
) : data.length === 0 ? (
카드 내역이 없습니다.
) : ( 날짜 가맹점 금액 승인번호 선택 {data.map((item) => ( {item.transactionDate} {item.merchantName} {formatNumber(item.amount)}원 {item.approvalNumber} ))}
)}
); }