refactor(WEB): CEO 대시보드 대규모 개선 및 문서/권한/스토어 리팩토링
- CEO 대시보드: 섹션별 API 연동 강화 (매출/매입/생산 실데이터 표시) - DashboardSettingsDialog 드래그 정렬 및 설정 UX 개선 - dashboard transformers 모듈 분리 (파일 분할) - DocumentTable/DocumentWrapper 공통 문서 컴포넌트 추출 - LineItemsTable organisms 컴포넌트 추가 - PurchaseOrderDocument/InspectionRequestDocument 문서 컴포넌트 리팩토링 - PermissionContext → permissionStore(Zustand) 전환 - useUIStore, stores/utils/userStorage 추가 - favoritesStore/useTableColumnStore 사용자별 저장 지원 - DepositDetail/WithdrawalDetail 삭제 (통합) - PurchaseDetail/SalesDetail 간소화 - amount.ts/formatters.ts 유틸 확장 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,13 @@
|
||||
|
||||
/**
|
||||
* 발주서 문서 컴포넌트
|
||||
* - 스크린샷 형식 + 지출결의서 디자인 스타일
|
||||
* - DocumentWrapper + DocumentTable building block 활용
|
||||
*/
|
||||
|
||||
import { getTodayString } from "@/lib/utils/date";
|
||||
import { OrderItem } from "../actions";
|
||||
import { formatNumber } from '@/lib/utils/amount';
|
||||
import { DocumentWrapper, DocumentTable, DOC_STYLES } from '@/components/document-system';
|
||||
|
||||
/**
|
||||
* 수량 포맷 함수
|
||||
@@ -61,7 +62,7 @@ export function PurchaseOrderDocument({
|
||||
remarks,
|
||||
}: PurchaseOrderDocumentProps) {
|
||||
return (
|
||||
<div className="bg-white p-8 min-h-full">
|
||||
<DocumentWrapper fontSize="text-sm">
|
||||
{/* 헤더: 제목 + 로트번호/결재란 */}
|
||||
<div className="flex justify-between items-start mb-6">
|
||||
<h1 className="text-2xl font-bold tracking-widest">발 주 서</h1>
|
||||
@@ -98,101 +99,95 @@ export function PurchaseOrderDocument({
|
||||
</div>
|
||||
|
||||
{/* 신청업체 */}
|
||||
<div className="border border-gray-300 mb-4">
|
||||
<table className="w-full text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowSpan={2} className="bg-gray-100 border-r border-b border-gray-300 p-2 text-center font-medium w-20">
|
||||
신청업체
|
||||
</td>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2 w-20">발주처</td>
|
||||
<td className="border-r border-b border-gray-300 p-2">{client}</td>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2 w-20">발주일</td>
|
||||
<td className="border-b border-gray-300 p-2">{orderDate}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2">담당자</td>
|
||||
<td className="border-r border-b border-gray-300 p-2">{manager}</td>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2">연락처</td>
|
||||
<td className="border-b border-gray-300 p-2">{managerContact}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-100 border-r border-gray-300 p-2 text-center font-medium"></td>
|
||||
<td className="bg-gray-100 border-r border-gray-300 p-2">FAX</td>
|
||||
<td className="border-r border-gray-300 p-2">-</td>
|
||||
<td className="bg-gray-100 border-r border-gray-300 p-2">설치개소<br/>(동)</td>
|
||||
<td className="border-gray-300 p-2">{installationCount}개소</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<DocumentTable spacing="mb-4" className="text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowSpan={2} className={`${DOC_STYLES.label} text-center w-20`}>
|
||||
신청업체
|
||||
</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>발주처</td>
|
||||
<td className={DOC_STYLES.value}>{client}</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>발주일</td>
|
||||
<td className={DOC_STYLES.value}>{orderDate}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>담당자</td>
|
||||
<td className={DOC_STYLES.value}>{manager}</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>연락처</td>
|
||||
<td className={DOC_STYLES.value}>{managerContact}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={`${DOC_STYLES.label} text-center w-20`}></td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>FAX</td>
|
||||
<td className={DOC_STYLES.value}>-</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>설치개소<br/>(동)</td>
|
||||
<td className={DOC_STYLES.value}>{installationCount}개소</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</DocumentTable>
|
||||
|
||||
{/* 신청내용 */}
|
||||
<div className="border border-gray-300 mb-4">
|
||||
<table className="w-full text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowSpan={3} className="bg-gray-100 border-r border-gray-300 p-2 text-center font-medium w-20">
|
||||
신청내용
|
||||
</td>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2 w-20">현장명</td>
|
||||
<td colSpan={3} className="border-b border-gray-300 p-2">{siteName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2">납기요청<br/>일</td>
|
||||
<td className="border-r border-b border-gray-300 p-2">{deliveryRequestDate}</td>
|
||||
<td className="bg-gray-100 border-r border-b border-gray-300 p-2 w-20">배송방법</td>
|
||||
<td className="border-b border-gray-300 p-2">{deliveryMethod}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bg-gray-100 border-r border-gray-300 p-2">출고일</td>
|
||||
<td className="border-r border-gray-300 p-2">{expectedShipDate}</td>
|
||||
<td className="bg-gray-100 border-r border-gray-300 p-2">납품주소</td>
|
||||
<td className="border-gray-300 p-2">{address}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<DocumentTable spacing="mb-4" className="text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowSpan={3} className={`${DOC_STYLES.label} text-center w-20`}>
|
||||
신청내용
|
||||
</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>현장명</td>
|
||||
<td colSpan={3} className={DOC_STYLES.value}>{siteName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>납기요청<br/>일</td>
|
||||
<td className={DOC_STYLES.value}>{deliveryRequestDate}</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>배송방법</td>
|
||||
<td className={DOC_STYLES.value}>{deliveryMethod}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>출고일</td>
|
||||
<td className={DOC_STYLES.value}>{expectedShipDate}</td>
|
||||
<td className={`${DOC_STYLES.label} w-20`}>납품주소</td>
|
||||
<td className={DOC_STYLES.value}>{address}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</DocumentTable>
|
||||
|
||||
{/* 부자재 */}
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-medium mb-2">■ 부자재</p>
|
||||
<div className="border border-gray-300">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b border-gray-300">
|
||||
<th className="p-2 text-center font-medium border-r border-gray-300 w-16">구분</th>
|
||||
<th className="p-2 text-left font-medium border-r border-gray-300">품명</th>
|
||||
<th className="p-2 text-center font-medium border-r border-gray-300 w-20">규격</th>
|
||||
<th className="p-2 text-center font-medium border-r border-gray-300 w-24">길이(mm)</th>
|
||||
<th className="p-2 text-center font-medium border-r border-gray-300 w-16">수량</th>
|
||||
<th className="p-2 text-center font-medium w-24">비고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.length > 0 ? (
|
||||
items.map((item, index) => (
|
||||
<tr key={item.id} className="border-b border-gray-300">
|
||||
<td className="p-2 text-center border-r border-gray-300">{index + 1}</td>
|
||||
<td className="p-2 border-r border-gray-300">{item.itemName}</td>
|
||||
<td className="p-2 text-center border-r border-gray-300">{item.spec}</td>
|
||||
<td className="p-2 text-center border-r border-gray-300">
|
||||
{item.width ? `${item.width}` : "-"}
|
||||
</td>
|
||||
<td className="p-2 text-center border-r border-gray-300">{formatQuantity(item.quantity, item.unit)}</td>
|
||||
<td className="p-2 text-center">{item.symbol || "-"}</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr className="border-b border-gray-300">
|
||||
<td colSpan={6} className="p-4 text-center text-gray-400">
|
||||
등록된 품목이 없습니다
|
||||
<DocumentTable spacing="">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className={`${DOC_STYLES.th} w-16`}>구분</th>
|
||||
<th className={`${DOC_STYLES.th} text-left`}>품명</th>
|
||||
<th className={`${DOC_STYLES.th} w-20`}>규격</th>
|
||||
<th className={`${DOC_STYLES.th} w-24`}>길이(mm)</th>
|
||||
<th className={`${DOC_STYLES.th} w-16`}>수량</th>
|
||||
<th className={`${DOC_STYLES.th} w-24`}>비고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.length > 0 ? (
|
||||
items.map((item, index) => (
|
||||
<tr key={item.id}>
|
||||
<td className={DOC_STYLES.tdCenter}>{index + 1}</td>
|
||||
<td className={DOC_STYLES.td}>{item.itemName}</td>
|
||||
<td className={DOC_STYLES.tdCenter}>{item.spec}</td>
|
||||
<td className={DOC_STYLES.tdCenter}>
|
||||
{item.width ? `${item.width}` : "-"}
|
||||
</td>
|
||||
<td className={DOC_STYLES.tdCenter}>{formatQuantity(item.quantity, item.unit)}</td>
|
||||
<td className={DOC_STYLES.tdCenter}>{item.symbol || "-"}</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={6} className="p-4 text-center text-gray-400 border border-gray-300">
|
||||
등록된 품목이 없습니다
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</DocumentTable>
|
||||
</div>
|
||||
|
||||
{/* 특이사항 */}
|
||||
@@ -219,6 +214,6 @@ export function PurchaseOrderDocument({
|
||||
<div className="text-center text-sm text-gray-600">
|
||||
문의: 홍길동 | 010-1234-5678
|
||||
</div>
|
||||
</div>
|
||||
</DocumentWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user