/** * 견적 선택 팝업 * * SearchableSelectionModal 공통 컴포넌트 기반 * 확정된 견적 목록에서 수주 전환할 견적을 선택 */ 'use client'; import { useCallback } from 'react'; import { FileText, Check } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { formatAmount } from '@/lib/utils/amount'; import { cn } from '@/lib/utils'; import { SearchableSelectionModal } from '@/components/organisms/SearchableSelectionModal'; import { getQuotesForSelect, type QuotationForSelect } from './actions'; interface QuotationSelectDialogProps { open: boolean; onOpenChange: (open: boolean) => void; onSelect: (quotation: QuotationForSelect) => void; selectedId?: string; } // 등급 배지 컴포넌트 function GradeBadge({ grade }: { grade: string }) { const config: Record = { A: { label: 'A (우량)', className: 'bg-green-100 text-green-700 border-green-200' }, B: { label: 'B (관리)', className: 'bg-yellow-100 text-yellow-700 border-yellow-200' }, C: { label: 'C (주의)', className: 'bg-red-100 text-red-700 border-red-200' }, }; const cfg = config[grade] || config.B; return ( {cfg.label} ); } export function QuotationSelectDialog({ open, onOpenChange, onSelect, selectedId, }: QuotationSelectDialogProps) { const handleFetchData = useCallback(async (query: string) => { const result = await getQuotesForSelect({ q: query || undefined, size: 50 }); if (result.success && result.data) { return result.data.items; } throw new Error(result.error || '견적 목록 조회에 실패했습니다.'); }, []); return ( open={open} onOpenChange={onOpenChange} title={ 견적 선택 } searchPlaceholder="견적번호, 거래처, 현장명 검색..." fetchData={handleFetchData} keyExtractor={(q) => q.id} loadOnOpen dialogClassName="max-w-2xl max-h-[80vh] overflow-hidden flex flex-col" listContainerClassName="flex-1 overflow-y-auto space-y-3 pr-2" infoText={(items, isLoading) => isLoading ? null : `전환 가능한 견적 ${items.length}건 (최종확정 상태)` } mode="single" onSelect={onSelect} renderItem={(quotation) => (
{quotation.quoteNumber}
{selectedId === quotation.id && ( )}
{quotation.client}
[{quotation.siteName}] {formatAmount(quotation.amount)}
{quotation.itemCount}개 품목
)} /> ); }