"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 { ProcurementRfqsView } from "@/db/schema" import { Check, Pencil, X } from "lucide-react" import { Button } from "@/components/ui/button" import { toast } from "sonner" import { Input } from "@/components/ui/input" import { updateRfqRemark } from "../services" interface GetColumnsProps { setRowAction: React.Dispatch | null>>; // 상태와 상태 설정 함수를 props로 받음 editingCell: EditingCellState | null; setEditingCell: (state: EditingCellState | null) => void; updateRemark: (rfqId: number, remark: string) => Promise; } export interface EditingCellState { rowId: string | number; value: string; } export function getColumns({ setRowAction, editingCell, setEditingCell, updateRemark, }: GetColumnsProps): ColumnDef[] { return [ { id: "select", // Remove the "Select all" checkbox in header since we're doing single-select header: () => Select, cell: ({ row, table }) => ( { // If selecting this row if (value) { // First deselect all rows (to ensure single selection) table.toggleAllRowsSelected(false) // Then select just this row row.toggleSelected(true) // Trigger the same action that was in the "Select" button setRowAction({ row, type: "select" }) } else { // Just deselect this row row.toggleSelected(false) } }} aria-label="Select row" className="translate-y-0.5" /> ), enableSorting: false, enableHiding: false, enableResizing: false, size: 40, minSize: 40, maxSize: 40, }, { accessorKey: "status", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("status")}
, meta: { excelHeader: "status" }, enableResizing: true, minSize: 80, size: 100, }, { accessorKey: "projectCode", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("projectCode")}
, meta: { excelHeader: "프로젝트" }, enableResizing: true, size: 120, }, { accessorKey: "series", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("series")}
, meta: { excelHeader: "시리즈" }, enableResizing: true, minSize: 80, size: 100, }, { accessorKey: "rfqSealedYn", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("rfqSealedYn") ? "Y":"N"}
, meta: { excelHeader: "RFQ 밀봉" }, enableResizing: true, minSize: 80, size: 100, }, { accessorKey: "rfqCode", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("rfqCode")}
, meta: { excelHeader: "RFQ NO." }, enableResizing: true, size: 120, }, { accessorKey: "po_no", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("po_no")}
, meta: { excelHeader: "대표 PR NO." }, enableResizing: true, size: 120, }, { accessorKey: "itemCode", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("itemCode")}
, meta: { excelHeader: "자재그룹" }, enableResizing: true, size: 120, }, { accessorKey: "majorItemMaterialCode", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("majorItemMaterialCode")}
, meta: { excelHeader: "자재코드" }, enableResizing: true, minSize: 80, size: 120, }, { accessorKey: "itemName", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("itemName")}
, meta: { excelHeader: "자재명" }, enableResizing: true, size: 140, }, { accessorKey: "prItemsCount", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("prItemsCount")}
, meta: { excelHeader: "PR 건수" }, enableResizing: true, // size: 80, }, { accessorKey: "rfqSendDate", header: ({ column }) => ( ), cell: ({ cell }) => { const value = cell.getValue(); return value ? formatDate(value as Date, "KR") : ""; }, meta: { excelHeader: "RFQ 전송일" }, enableResizing: true, size: 120, }, { accessorKey: "earliestQuotationSubmittedAt", header: ({ column }) => ( ), cell: ({ cell }) => { const value = cell.getValue(); return value ? formatDate(value as Date, "KR") : ""; }, meta: { excelHeader: "첫회신 접수일" }, enableResizing: true, // size: 140, }, { accessorKey: "dueDate", header: ({ column }) => ( ), cell: ({ cell }) => { const value = cell.getValue(); return value ? formatDate(value as Date, "KR") : ""; }, meta: { excelHeader: "RFQ 마감일" }, enableResizing: true, minSize: 80, size: 120, }, { accessorKey: "sentByUserName", header: ({ column }) => ( ), cell: ({ row }) =>
{row.getValue("sentByUserName")}
, meta: { excelHeader: "RFQ 요청자" }, enableResizing: true, size: 120, }, { accessorKey: "updatedAt", header: ({ column }) => ( ), cell: ({ cell }) => formatDateTime(cell.getValue() as Date, "KR"), meta: { excelHeader: "updated At" }, enableResizing: true, size: 140, }, { accessorKey: "remark", header: ({ column }) => ( ), cell: ({ row }) => { const rowId = row.id const value = row.getValue("remark") as string const isEditing = editingCell && editingCell.rowId === rowId const startEditing = () => { setEditingCell({ rowId, value: value || "" }) } const cancelEditing = () => { setEditingCell(null) } const saveChanges = async () => { if (!editingCell) return try { // 컴포넌트에서 전달받은 업데이트 함수 사용 await updateRemark(row.original.id, editingCell.value) row.original.remark = editingCell.value; // 편집 모드 종료 setEditingCell(null) } catch (error) { console.error("비고 업데이트 오류:", error) } } // 키보드 이벤트 처리 const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { saveChanges() } else if (e.key === "Escape") { cancelEditing() } } if (isEditing) { return (
setEditingCell({ ...editingCell, value: e.target.value })} onKeyDown={handleKeyDown} autoFocus className="h-8 w-full" />
) } return (
{value || "-"}
) }, meta: { excelHeader: "비고" }, enableResizing: true, size: 200, } ] }