From 02b1cf005cf3e1df64183d20ba42930eb2767a9f Mon Sep 17 00:00:00 2001 From: dujinkim Date: Thu, 21 Aug 2025 06:57:36 +0000 Subject: (대표님, 최겸) 설계메뉴추가, 작업사항 업데이트 설계메뉴 - 문서관리 설계메뉴 - 벤더 데이터 gtc 메뉴 업데이트 정보시스템 - 메뉴리스트 및 정보 업데이트 파일 라우트 업데이트 엑셀임포트 개선 기본계약 개선 벤더 가입과정 변경 및 개선 벤더 기본정보 - pq 돌체 오류 수정 및 개선 벤더 로그인 과정 이메일 오류 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ship-all/enhanced-doc-table-columns.tsx | 540 +++++++++++++++++++++ 1 file changed, 540 insertions(+) create mode 100644 lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx (limited to 'lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx') diff --git a/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx b/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx new file mode 100644 index 00000000..6c9a9ab6 --- /dev/null +++ b/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx @@ -0,0 +1,540 @@ +// simplified-doc-table-columns.tsx +"use client" + +import * as React from "react" +import { ColumnDef } from "@tanstack/react-table" +import { formatDate, formatDateTime } from "@/lib/utils" +import { Checkbox } from "@/components/ui/checkbox" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { DataTableRowAction } from "@/types/table" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { Button } from "@/components/ui/button" +import { + Ellipsis, + FileText, + Eye, + Edit, + Trash2, +} from "lucide-react" +import { cn } from "@/lib/utils" +import { SimplifiedDocumentsView } from "@/db/schema" + +// DocumentSelectionContext를 import (실제 파일 경로에 맞게 수정 필요) +// 예: import { DocumentSelectionContextAll } from "../user-vendor-document-display" +// 또는: import { DocumentSelectionContextAll } from "./user-vendor-document-display" +import { DocumentSelectionContextAll } from "@/components/ship-vendor-document-all/user-vendor-document-table-container" + +interface GetColumnsProps { + setRowAction: React.Dispatch | null>> +} + +// 날짜 표시 컴포넌트 (간단 버전) +const DateDisplay = ({ date, isSelected = false }: { date: string | null, isSelected?: boolean }) => { + if (!date) return - + + return ( + + {formatDate(date)} + + ) +} + +export function getSimplifiedDocumentColumns({ + setRowAction, +}: GetColumnsProps): ColumnDef[] { + + const columns: ColumnDef[] = [ + // 라디오 버튼 같은 체크박스 선택 + { + id: "select", + header: ({ table }) => ( +
+ Select +
+ ), + cell: ({ row }) => { + const doc = row.original + + return ( + + ) + }, + size: 40, + enableSorting: false, + enableHiding: false, + }, + + // 문서번호 (선택된 행 하이라이트 적용) + { + accessorKey: "docNumber", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const doc = row.original + + return ( + + ) + }, + size: 120, + enableResizing: true, + meta: { + excelHeader: "Document No" + }, + }, + + // 문서명 (선택된 행 하이라이트 적용) + { + accessorKey: "title", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const doc = row.original + + return ( + + ) + }, + enableResizing: true, + maxSize:300, + meta: { + excelHeader: "Title" + }, + }, + + // 프로젝트 코드 + { + accessorKey: "projectCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const projectCode = row.original.projectCode + + return ( + + ) + }, + enableResizing: true, + maxSize:100, + meta: { + excelHeader: "Project" + }, + }, + + // 벤더명 + { + accessorKey: "vendorName", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const vendorName = row.original.vendorName + + return ( + + ) + }, + enableResizing: true, + maxSize: 200, + meta: { + excelHeader: "Vendor Name" + }, + }, + + // 벤더 코드 + { + accessorKey: "vendorCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const vendorCode = row.original.vendorCode + + return ( + + ) + }, + enableResizing: true, + maxSize: 120, + meta: { + excelHeader: "Vendor Code" + }, + }, + + // 1차 스테이지 그룹 + { + id: "firstStageGroup", + header: ({ table }) => { + // 첫 번째 행의 firstStageName을 그룹 헤더로 사용 + const firstRow = table.getRowModel().rows[0]?.original + const stageName = firstRow?.firstStageName || "First Stage" + return ( +
+ {stageName} +
+ ) + }, + columns: [ + { + accessorKey: "firstStagePlanDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return + }, + enableResizing: true, + meta: { + excelHeader: "First Planned Date" + }, + }, + { + accessorKey: "firstStageActualDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return + }, + enableResizing: true, + meta: { + excelHeader: "First Actual Date" + }, + }, + ], + }, + + // 2차 스테이지 그룹 + { + id: "secondStageGroup", + header: ({ table }) => { + // 첫 번째 행의 secondStageName을 그룹 헤더로 사용 + const firstRow = table.getRowModel().rows[0]?.original + const stageName = firstRow?.secondStageName || "Second Stage" + return ( +
+ {stageName} +
+ ) + }, + columns: [ + { + accessorKey: "secondStagePlanDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return + }, + enableResizing: true, + meta: { + excelHeader: "Second Planned Date" + }, + }, + { + accessorKey: "secondStageActualDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return + }, + enableResizing: true, + meta: { + excelHeader: "Second Actual Date" + }, + }, + ], + }, + + // 첨부파일 수 + { + accessorKey: "attachmentCount", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const count = row.original.attachmentCount || 0 + + return ( + + ) + }, + size: 60, + enableResizing: true, + meta: { + excelHeader: "Attachments" + }, + }, + + // 업데이트 일시 + { + accessorKey: "updatedAt", + header: ({ column }) => ( + + ), + cell: ({ cell, row }) => { + return ( + + ) + }, + enableResizing: true, + meta: { + excelHeader: "Updated" + }, + }, + + // 액션 버튼 + // { + // id: "actions", + // header: () => Actions, + // cell: ({ row }) => { + // const doc = row.original + // return ( + // + // + // + // + // + // setRowAction({ type: "view", row: doc })} + // > + // + // 보기 + // + // setRowAction({ type: "edit", row: doc })} + // > + // + // 편집 + // + // + // setRowAction({ type: "delete", row: doc })} + // className="text-red-600" + // > + // + // 삭제 + // + // + // + // + // ) + // }, + // size: 50, + // enableSorting: false, + // enableHiding: false, + // }, + ] + + return columns +} + +// 개별 셀 컴포넌트들 (Context 사용) +function SelectCell({ documentId }: { documentId: number }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( +
+ { + const newSelection = isSelected ? null : documentId; + setSelectedDocumentId(newSelection); + }} + className="cursor-pointer w-4 h-4" + /> +
+ ); +} + +function DocNumberCell({ doc }: { doc: SimplifiedDocumentsView }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === doc.documentId; + + return ( +
{ + const newSelection = isSelected ? null : doc.documentId; + setSelectedDocumentId(newSelection); + }} + > + {doc.docNumber} +
+ ); +} + +function TitleCell({ doc }: { doc: SimplifiedDocumentsView }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === doc.documentId; + + return ( +
{ + const newSelection = isSelected ? null : doc.documentId; + setSelectedDocumentId(newSelection); + }} + > + {doc.title} +
+ ); +} + +function ProjectCodeCell({ projectCode, documentId }: { projectCode: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!projectCode) return -; + + return ( + + {projectCode} + + ); +} + +function VendorNameCell({ vendorName, documentId }: { vendorName: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!vendorName) return -; + + return ( +
+ {vendorName} +
+ ); +} + +function VendorCodeCell({ vendorCode, documentId }: { vendorCode: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!vendorCode) return -; + + return ( + + {vendorCode} + + ); +} + +function FirstStagePlanDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + + return ; +} + +function FirstStageActualDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + const date = row.original.firstStageActualDate; + + return ( +
+ + {date && ✓ 완료} +
+ ); +} + +function SecondStagePlanDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + + return ; +} + +function SecondStageActualDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + const date = row.original.secondStageActualDate; + + return ( +
+ + {date && ✓ 완료} +
+ ); +} + +function AttachmentCountCell({ count, documentId }: { count: number, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( +
+ + + {count} + +
+ ); +} + +function UpdatedAtCell({ updatedAt, documentId }: { updatedAt: Date, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( + + {formatDateTime(updatedAt)} + + ); +} \ No newline at end of file -- cgit v1.2.3