Files
sam-react-prod/src/components/quotes/QuotePreviewContent.tsx
유병철 9464a368ba refactor: 모달 Content 컴포넌트 분리 및 파일 입력 UI 공통화
- 모달 컴포넌트에서 Content 분리하여 재사용성 향상
  - EstimateDocumentContent, DirectConstructionContent 등
  - WorkLogContent, QuotePreviewContent, ReceivingReceiptContent
- 파일 입력 공통 UI 컴포넌트 추가
  - file-dropzone, file-input, file-list, image-upload
- 폼 컴포넌트 코드 정리 및 중복 제거 (-4,056줄)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:07:17 +09:00

219 lines
8.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
/**
* 견적서 문서 콘텐츠
*
* 공통 컴포넌트 사용:
* - DocumentHeader: simple 레이아웃 (결재란 없음)
* - SectionHeader: 섹션 제목
*/
import type { QuoteFormDataV2 } from './QuoteRegistrationV2';
import { DocumentHeader, SectionHeader } from '@/components/document-system';
interface QuotePreviewContentProps {
data: QuoteFormDataV2;
}
export function QuotePreviewContent({ data: quoteData }: QuotePreviewContentProps) {
// 총 금액 계산
const totalAmount = quoteData.locations.reduce(
(sum, loc) => sum + (loc.totalPrice || 0),
0
);
// 부가세
const vat = Math.round(totalAmount * 0.1);
const grandTotal = totalAmount + vat;
return (
<div className="max-w-[210mm] mx-auto bg-white shadow-lg rounded-lg p-8">
{/* 제목 (공통 컴포넌트) */}
<DocumentHeader
title="견 적 서"
subtitle={`문서번호: ${quoteData.id || "-"} | 작성일자: ${quoteData.registrationDate || "-"}`}
layout="simple"
approval={null}
/>
{/* 수요자 정보 */}
<div className="border border-gray-300 mb-4">
<div className="bg-gray-100 px-3 py-2 font-semibold border-b border-gray-300">
</div>
<div className="p-3 grid grid-cols-2 gap-2 text-sm">
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.clientName || "-"}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.manager || "-"}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.siteName || "-"}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.contact || "-"}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.registrationDate || "-"}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">{quoteData.dueDate || "-"}</span>
</div>
</div>
</div>
{/* 공급자 정보 */}
<div className="border border-gray-300 mb-6">
<div className="bg-gray-100 px-3 py-2 font-semibold border-b border-gray-300">
</div>
<div className="p-3 grid grid-cols-2 gap-2 text-sm">
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium">_테스트회사</span>
</div>
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium">123-45-67890</span>
</div>
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium"></span>
</div>
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium"></span>
</div>
<div className="flex col-span-2">
<span className="w-24 text-gray-600"></span>
<span className="font-medium"></span>
</div>
<div className="flex col-span-2">
<span className="w-24 text-gray-600"></span>
<span className="font-medium">07547 583 B-1602</span>
</div>
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium">01048209104</span>
</div>
<div className="flex">
<span className="w-24 text-gray-600"></span>
<span className="font-medium">codebridgex@codebridge-x.com</span>
</div>
</div>
</div>
{/* 총 견적금액 */}
<div className="border-2 border-gray-800 p-4 mb-6 text-center">
<p className="text-sm text-gray-600 mb-1"> </p>
<p className="text-3xl font-bold">
{grandTotal.toLocaleString()}
</p>
<p className="text-xs text-gray-500 mt-1"> </p>
</div>
{/* 제품 구성정보 */}
<div className="border border-gray-300 mb-6">
<SectionHeader> </SectionHeader>
<div className="p-3 grid grid-cols-2 gap-2 text-sm">
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">
{quoteData.locations[0]?.productCode || "-"}
</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"> </span>
<span className="font-medium">{quoteData.locations.length}</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">
{quoteData.locations[0]?.openWidth || "-"} × {quoteData.locations[0]?.openHeight || "-"}
</span>
</div>
<div className="flex">
<span className="w-20 text-gray-600"></span>
<span className="font-medium">-</span>
</div>
</div>
</div>
{/* 품목 내역 */}
<div className="border border-gray-300 mb-6">
<SectionHeader> </SectionHeader>
<table className="w-full text-sm">
<thead>
<tr className="bg-gray-100 border-b border-gray-300">
<th className="px-3 py-2 text-left">No.</th>
<th className="px-3 py-2 text-left"></th>
<th className="px-3 py-2 text-center"></th>
<th className="px-3 py-2 text-center"></th>
<th className="px-3 py-2 text-center"></th>
<th className="px-3 py-2 text-right"></th>
<th className="px-3 py-2 text-right"></th>
</tr>
</thead>
<tbody>
{quoteData.locations.map((loc, index) => (
<tr key={loc.id} className="border-b border-gray-200">
<td className="px-3 py-2">{index + 1}</td>
<td className="px-3 py-2">{loc.productCode}</td>
<td className="px-3 py-2 text-center">
{loc.openWidth}×{loc.openHeight}
</td>
<td className="px-3 py-2 text-center">{loc.quantity}</td>
<td className="px-3 py-2 text-center">EA</td>
<td className="px-3 py-2 text-right">
{(loc.unitPrice || 0).toLocaleString()}
</td>
<td className="px-3 py-2 text-right">
{(loc.totalPrice || 0).toLocaleString()}
</td>
</tr>
))}
</tbody>
<tfoot>
<tr className="border-t-2 border-gray-400">
<td colSpan={5}></td>
<td className="px-3 py-2 text-right font-medium"> </td>
<td className="px-3 py-2 text-right font-bold">
{totalAmount.toLocaleString()}
</td>
</tr>
<tr>
<td colSpan={5}></td>
<td className="px-3 py-2 text-right font-medium"> (10%)</td>
<td className="px-3 py-2 text-right font-bold">
{vat.toLocaleString()}
</td>
</tr>
<tr className="bg-gray-100">
<td colSpan={5}></td>
<td className="px-3 py-2 text-right font-medium"> </td>
<td className="px-3 py-2 text-right font-bold text-lg">
{grandTotal.toLocaleString()}
</td>
</tr>
</tfoot>
</table>
</div>
{/* 비고사항 */}
<div className="border border-gray-300">
<SectionHeader> </SectionHeader>
<div className="p-3 min-h-[80px] text-sm text-gray-600">
{quoteData.remarks || "비고 테스트"}
</div>
</div>
</div>
);
}