From dac1d9bc2bc094b8dcdc3bb558e552e0b0b2f992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Fri, 16 Jan 2026 20:41:18 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=ED=9A=8C=EC=82=AC=EC=A0=95=EB=B3=B4=20API=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getCompanyInfo() API 함수 추가 (GET /api/v1/tenants) - EstimateDocumentModal에 회사정보 API 연동 - 하드코딩된 회사명/주소/연락처 제거 - 결재란 견적자명 동적 표시 - constants.ts 모듈 유효성 수정 --- .../construction/estimates/actions.ts | 74 +++++++++++++++++++ .../modals/EstimateDocumentModal.tsx | 47 ++++++++---- .../construction/estimates/utils/constants.ts | 19 +++-- 3 files changed, 118 insertions(+), 22 deletions(-) diff --git a/src/components/business/construction/estimates/actions.ts b/src/components/business/construction/estimates/actions.ts index f2f2763d..b40897e4 100644 --- a/src/components/business/construction/estimates/actions.ts +++ b/src/components/business/construction/estimates/actions.ts @@ -1138,4 +1138,78 @@ export async function getEstimateOptions(): Promise<{ console.error('견적서 옵션 일괄 조회 오류:', error); return { success: false, error: '견적서 옵션을 불러오는데 실패했습니다.' }; } +} + +// ======================================== +// 회사 정보 조회 (Tenant API) +// ======================================== + +/** + * 회사 정보 타입 (견적서용) + */ +export interface CompanyInfo { + companyName: string; + representativeName: string; + address: string; + phone: string; + fax: string; + email: string; + managerName: string; + managerPhone: string; +} + +/** + * 회사 정보 조회 (견적서 모달용) + * GET /api/v1/tenants + */ +export async function getCompanyInfo(): Promise<{ + success: boolean; + data?: CompanyInfo; + error?: string; +}> { + try { + const response = await apiClient.get<{ + success: boolean; + message: string; + data: { + id: number; + company_name: string; + ceo_name?: string; + email?: string; + phone?: string; + fax?: string; + address?: string; + options?: { + manager_name?: string; + address_detail?: string; + zip_code?: string; + }; + }; + }>('/tenants'); + + const tenant = response.data; + const opts = tenant.options || {}; + + // 주소 조합: 우편번호 + 주소 + 상세주소 + const fullAddress = [opts.zip_code, tenant.address, opts.address_detail] + .filter(Boolean) + .join(' '); + + return { + success: true, + data: { + companyName: tenant.company_name || '', + representativeName: tenant.ceo_name || '', + address: fullAddress || tenant.address || '', + phone: tenant.phone || '', + fax: tenant.fax || '', + email: tenant.email || '', + managerName: opts.manager_name || '', + managerPhone: tenant.phone || '', + }, + }; + } catch (error) { + console.error('회사 정보 조회 오류:', error); + return { success: false, error: '회사 정보를 불러오는데 실패했습니다.' }; + } } \ No newline at end of file diff --git a/src/components/business/construction/estimates/modals/EstimateDocumentModal.tsx b/src/components/business/construction/estimates/modals/EstimateDocumentModal.tsx index c0ecc78e..30c1d8d2 100644 --- a/src/components/business/construction/estimates/modals/EstimateDocumentModal.tsx +++ b/src/components/business/construction/estimates/modals/EstimateDocumentModal.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useCallback } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Printer, Pencil, Send, X as XIcon } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -12,6 +12,7 @@ import { } from '@/components/ui/dialog'; import { printArea } from '@/lib/print-utils'; import type { EstimateDetailFormData } from '../types'; +import { getCompanyInfo, type CompanyInfo } from '../actions'; // 금액 포맷팅 function formatAmount(amount: number): string { @@ -65,6 +66,20 @@ export function EstimateDocumentModal({ }: EstimateDocumentModalProps) { const router = useRouter(); + // 회사 정보 상태 + const [companyInfo, setCompanyInfo] = useState(null); + + // 회사 정보 로드 + useEffect(() => { + if (isOpen) { + getCompanyInfo().then((result) => { + if (result.success && result.data) { + setCompanyInfo(result.data); + } + }); + } + }, [isOpen]); + // 인쇄 const handlePrint = useCallback(() => { printArea({ title: '견적서 인쇄' }); @@ -78,22 +93,22 @@ export function EstimateDocumentModal({ } }, [estimateId, onClose, router]); - // 견적서 문서 데이터 + // 견적서 문서 데이터 (회사 정보는 API에서 로드) const documentData = { - documentNo: formData.estimateCode || 'ABC123', - createdDate: formData.siteBriefing.briefingDate || '2025년 11월 11일', + documentNo: formData.estimateCode || '', + createdDate: formData.siteBriefing.briefingDate || '', recipient: formData.siteBriefing.partnerName || '', - companyName: formData.siteBriefing.companyName || '(주) 주일기업', + companyName: companyInfo?.companyName || formData.siteBriefing.companyName || '', projectName: formData.bidInfo.projectName || '', - address: '주소', + address: companyInfo?.address || '', amount: formData.summaryItems.reduce((sum, item) => sum + item.totalCost, 0), - date: formData.bidInfo.bidDate || '2025년 12월 12일', - manager: formData.estimateCompanyManager || '', - managerContact: formData.estimateCompanyManagerContact || '', + date: formData.bidInfo.bidDate || '', + manager: companyInfo?.managerName || formData.estimateCompanyManager || '', + managerContact: companyInfo?.managerPhone || formData.estimateCompanyManagerContact || '', contact: { - hp: '010-3679-2188', - tel: '(02) 849-5130', - fax: '(02) 6911-6315', + hp: companyInfo?.managerPhone || '', + tel: companyInfo?.phone || '', + fax: companyInfo?.fax || '', }, note: '하기와 같이 보내합니다.', }; @@ -160,13 +175,13 @@ export function EstimateDocumentModal({ 결재 - 홍길동 - 이름 + {formData.estimatorName || ''} + - 부서명 - 부서명 + + diff --git a/src/components/business/construction/estimates/utils/constants.ts b/src/components/business/construction/estimates/utils/constants.ts index 8f88862d..1ef4b114 100644 --- a/src/components/business/construction/estimates/utils/constants.ts +++ b/src/components/business/construction/estimates/utils/constants.ts @@ -1,6 +1,13 @@ -// 견적서 상수 정의 -// 모든 MOCK 데이터는 API로 대체됨: -// - 재료(material_type): getCommonCodeOptions('material_type') -// - 공과 품목: getExpenseItemOptions() -// - 도장/모터/제어기/시공비: getCommonCodeOptions('{group}') -// - 거래처/견적자: getClientOptions(), getUserOptions() \ No newline at end of file +/** + * 견적서 상수 정의 + * + * 모든 MOCK 데이터는 API로 대체됨: + * - 재료(material_type): getCommonCodeOptions('material_type') + * - 공과 품목: getExpenseItemOptions() + * - 도장/모터/제어기/시공비: getCommonCodeOptions('{group}') + * - 거래처/견적자: getClientOptions(), getUserOptions() + * - 회사 정보: getCompanyInfo() + */ + +// 빈 export로 모듈 유효성 유지 +export {}; \ No newline at end of file