'use client'; import { useState, useMemo, useCallback } from 'react'; import { Receipt, FileText } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { TableRow, TableCell } from '@/components/ui/table'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@/components/ui/dialog'; import { IntegratedListTemplateV2, type TableColumn, } from '@/components/templates/IntegratedListTemplateV2'; import { ListMobileCard, InfoField } from '@/components/organisms/ListMobileCard'; import { getPayments } from './actions'; import type { PaymentHistory, SortOption } from './types'; // ===== Props 타입 ===== interface PaymentHistoryClientProps { initialData: PaymentHistory[]; initialPagination: { currentPage: number; lastPage: number; perPage: number; total: number; }; } export function PaymentHistoryClient({ initialData, initialPagination, }: PaymentHistoryClientProps) { // ===== 상태 관리 ===== const [searchQuery, setSearchQuery] = useState(''); const [sortOption, setSortOption] = useState('latest'); const [currentPage, setCurrentPage] = useState(initialPagination.currentPage); const [data, setData] = useState(initialData); const [totalPages, setTotalPages] = useState(initialPagination.lastPage); const [totalItems, setTotalItems] = useState(initialPagination.total); const [isLoading, setIsLoading] = useState(false); const itemsPerPage = initialPagination.perPage; // 거래명세서 팝업 상태 const [showInvoiceDialog, setShowInvoiceDialog] = useState(false); const [selectedPaymentId, setSelectedPaymentId] = useState(null); // ===== 페이지 변경 핸들러 ===== const handlePageChange = useCallback(async (page: number) => { setIsLoading(true); try { const result = await getPayments({ page, perPage: itemsPerPage }); if (result.success) { setData(result.data); setCurrentPage(result.pagination.currentPage); setTotalPages(result.pagination.lastPage); setTotalItems(result.pagination.total); } } catch (error) { console.error('[PaymentHistoryClient] Page change error:', error); } finally { setIsLoading(false); } }, [itemsPerPage]); // ===== 필터링된 데이터 (클라이언트 사이드 필터링) ===== const filteredData = useMemo(() => { let result = [...data]; // 검색 필터 (클라이언트 사이드) if (searchQuery) { result = result.filter(item => item.subscriptionName.includes(searchQuery) || item.paymentMethod.includes(searchQuery) || item.paymentDate.includes(searchQuery) ); } // 정렬 switch (sortOption) { case 'latest': result.sort((a, b) => new Date(b.paymentDate).getTime() - new Date(a.paymentDate).getTime()); break; case 'oldest': result.sort((a, b) => new Date(a.paymentDate).getTime() - new Date(b.paymentDate).getTime()); break; case 'amountHigh': result.sort((a, b) => b.amount - a.amount); break; case 'amountLow': result.sort((a, b) => a.amount - b.amount); break; } return result; }, [data, searchQuery, sortOption]); // ===== 거래명세서 버튼 클릭 ===== const handleViewInvoice = useCallback((paymentId: string) => { setSelectedPaymentId(paymentId); setShowInvoiceDialog(true); }, []); // ===== 테이블 컬럼 ===== const tableColumns: TableColumn[] = useMemo(() => [ { key: 'paymentDate', label: '결제일' }, { key: 'subscriptionName', label: '구독명' }, { key: 'paymentMethod', label: '결제 수단' }, { key: 'subscriptionPeriod', label: '구독 기간' }, { key: 'amount', label: '금액', className: 'text-right' }, { key: 'invoice', label: '거래명세서', className: 'text-center' }, ], []); // ===== 테이블 행 렌더링 ===== const renderTableRow = useCallback((item: PaymentHistory, index: number) => { const isLatest = index === 0; // 최신 항목 (초록색 버튼) return ( {/* 결제일 */} {item.paymentDate} {/* 구독명 */} {item.subscriptionName} {/* 결제 수단 */} {item.paymentMethod} {/* 구독 기간 */} {item.subscriptionPeriod.start && item.subscriptionPeriod.end ? `${item.subscriptionPeriod.start} ~ ${item.subscriptionPeriod.end}` : '-'} {/* 금액 */} {item.amount.toLocaleString()}원 {/* 거래명세서 */} {item.canViewInvoice ? ( ) : ( - )} ); }, [handleViewInvoice]); // ===== 모바일 카드 렌더링 ===== const renderMobileCard = useCallback(( item: PaymentHistory, index: number, globalIndex: number, isSelected: boolean, onToggle: () => void ) => { const isLatest = globalIndex === 1; return ( {}} infoGrid={
} actions={ item.canViewInvoice ? ( ) : null } /> ); }, [handleViewInvoice]); return ( <> {}} onToggleSelectAll={() => {}} getItemId={(item: PaymentHistory) => item.id} renderTableRow={renderTableRow} renderMobileCard={renderMobileCard} showCheckbox={false} showRowNumber={false} pagination={{ currentPage, totalPages, totalItems, itemsPerPage, onPageChange: handlePageChange, }} /> {/* ===== 거래명세서 안내 다이얼로그 ===== */} 거래명세서 MES 시스템의 문서 페이지에서 거래명세서를 확인할 수 있습니다.

해당 기능은 MES 모듈에서 제공되며, 추후 연동 예정입니다.
); }