Files
sam-react-prod/src/components/quotes/QuotePreviewModal.tsx
유병철 afd7bda269 feat(WEB): 견적 시스템 개선, 엑셀 다운로드, PDF 생성 기능 추가
견적 시스템:
- QuoteRegistrationV2: 할인 모달, 거래명세서 모달, vatType 필드 추가
- DiscountModal: 할인율/할인금액 상호 계산 모달
- QuoteTransactionModal: 거래명세서 미리보기 모달
- LocationDetailPanel, LocationListPanel 개선

템플릿 기능:
- UniversalListPage: 엑셀 다운로드 기능 추가 (전체/선택 다운로드)
- DocumentViewer: PDF 생성 기능 개선

신규 API:
- /api/pdf/generate: Puppeteer 기반 PDF 생성 엔드포인트

UI 개선:
- 입력 컴포넌트 placeholder 스타일 개선 (opacity 50%)
- 각종 리스트 컴포넌트 정렬/필터링 개선

패키지 추가:
- html2canvas, jspdf, puppeteer, dom-to-image-more

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:49:03 +09:00

134 lines
3.4 KiB
TypeScript

'use client';
/**
* 견적서 미리보기 모달
*
* 양식 선택:
* - 업체발송용 (부가세 포함/별도는 기본정보에서 선택한 값 사용)
* - 산출내역서
*/
import { useState } from 'react';
import { Copy, Pencil, FileText } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { DocumentViewer } from '@/components/document-system';
import type { QuoteFormDataV2 } from './QuoteRegistrationV2';
import { QuotePreviewContent } from './QuotePreviewContent';
// 양식 타입: 업체발송용 / 산출내역서
type TemplateType = 'vendor' | 'calculation';
interface QuotePreviewModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
quoteData: QuoteFormDataV2 | null;
/** 할인율 (%) */
discountRate?: number;
/** 할인금액 (원) */
discountAmount?: number;
/** 복제 핸들러 */
onDuplicate?: () => void;
/** 수정 핸들러 */
onEdit?: () => void;
}
export function QuotePreviewModal({
open,
onOpenChange,
quoteData,
discountRate = 0,
discountAmount = 0,
onDuplicate,
onEdit,
}: QuotePreviewModalProps) {
// 양식 타입 상태 (기본: 업체발송용)
const [templateType, setTemplateType] = useState<TemplateType>('vendor');
if (!quoteData) return null;
// 부가세 포함 여부는 기본정보에서 선택한 값 사용
const vatIncluded = quoteData.vatType === 'included';
const handleDuplicate = () => {
console.log('[테스트] 복제');
onDuplicate?.();
};
const handleEdit = () => {
console.log('[테스트] 수정');
onEdit?.();
};
const toolbarExtra = (
<>
{/* 복제 버튼 */}
<Button
variant="outline"
size="sm"
onClick={handleDuplicate}
>
<Copy className="h-4 w-4 mr-1" />
</Button>
{/* 수정 버튼 */}
<Button
variant="outline"
size="sm"
onClick={handleEdit}
>
<Pencil className="h-4 w-4 mr-1" />
</Button>
{/* 양식 선택 드롭다운 */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm">
<FileText className="h-4 w-4 mr-1" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => setTemplateType('vendor')}
className={templateType === 'vendor' ? 'bg-blue-50' : ''}
>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => setTemplateType('calculation')}
className={templateType === 'calculation' ? 'bg-blue-50' : ''}
>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
);
return (
<DocumentViewer
title={templateType === 'calculation' ? '산출내역서' : '견적서'}
preset="inspection"
open={open}
onOpenChange={onOpenChange}
toolbarExtra={toolbarExtra}
>
<QuotePreviewContent
data={quoteData}
templateType={templateType}
vatIncluded={vatIncluded}
discountRate={discountRate}
discountAmount={discountAmount}
/>
</DocumentViewer>
);
}