견적 시스템: - 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>
134 lines
3.4 KiB
TypeScript
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>
|
|
);
|
|
}
|