From d0d2eaa2de58a0c33e9a21604b126961403cd69e Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 14 May 2025 06:12:13 +0000 Subject: (최겸) 기술영업 조선, 해양Top, 해양 Hull 아이템 리스트 개발(CRUD, excel import/export/template) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/items-tech/table/add-items-dialog.tsx | 400 +++++++++++++++++++++ lib/items-tech/table/delete-items-dialog.tsx | 194 ++++++++++ lib/items-tech/table/feature-flags.tsx | 96 +++++ lib/items-tech/table/hull/import-item-handler.tsx | 143 ++++++++ lib/items-tech/table/hull/item-excel-template.tsx | 125 +++++++ .../table/hull/offshore-hull-table-columns.tsx | 282 +++++++++++++++ .../hull/offshore-hull-table-toolbar-actions.tsx | 184 ++++++++++ lib/items-tech/table/hull/offshore-hull-table.tsx | 152 ++++++++ lib/items-tech/table/import-excel-button.tsx | 298 +++++++++++++++ lib/items-tech/table/ship/Items-ship-table.tsx | 146 ++++++++ lib/items-tech/table/ship/import-item-handler.tsx | 145 ++++++++ lib/items-tech/table/ship/item-excel-template.tsx | 122 +++++++ .../table/ship/items-ship-table-columns.tsx | 244 +++++++++++++ .../table/ship/items-table-toolbar-actions.tsx | 178 +++++++++ lib/items-tech/table/top/import-item-handler.tsx | 143 ++++++++ lib/items-tech/table/top/item-excel-template.tsx | 125 +++++++ .../table/top/offshore-top-table-columns.tsx | 282 +++++++++++++++ .../top/offshore-top-table-toolbar-actions.tsx | 184 ++++++++++ lib/items-tech/table/top/offshore-top-table.tsx | 153 ++++++++ lib/items-tech/table/update-items-sheet.tsx | 390 ++++++++++++++++++++ 20 files changed, 3986 insertions(+) create mode 100644 lib/items-tech/table/add-items-dialog.tsx create mode 100644 lib/items-tech/table/delete-items-dialog.tsx create mode 100644 lib/items-tech/table/feature-flags.tsx create mode 100644 lib/items-tech/table/hull/import-item-handler.tsx create mode 100644 lib/items-tech/table/hull/item-excel-template.tsx create mode 100644 lib/items-tech/table/hull/offshore-hull-table-columns.tsx create mode 100644 lib/items-tech/table/hull/offshore-hull-table-toolbar-actions.tsx create mode 100644 lib/items-tech/table/hull/offshore-hull-table.tsx create mode 100644 lib/items-tech/table/import-excel-button.tsx create mode 100644 lib/items-tech/table/ship/Items-ship-table.tsx create mode 100644 lib/items-tech/table/ship/import-item-handler.tsx create mode 100644 lib/items-tech/table/ship/item-excel-template.tsx create mode 100644 lib/items-tech/table/ship/items-ship-table-columns.tsx create mode 100644 lib/items-tech/table/ship/items-table-toolbar-actions.tsx create mode 100644 lib/items-tech/table/top/import-item-handler.tsx create mode 100644 lib/items-tech/table/top/item-excel-template.tsx create mode 100644 lib/items-tech/table/top/offshore-top-table-columns.tsx create mode 100644 lib/items-tech/table/top/offshore-top-table-toolbar-actions.tsx create mode 100644 lib/items-tech/table/top/offshore-top-table.tsx create mode 100644 lib/items-tech/table/update-items-sheet.tsx (limited to 'lib/items-tech/table') diff --git a/lib/items-tech/table/add-items-dialog.tsx b/lib/items-tech/table/add-items-dialog.tsx new file mode 100644 index 00000000..86333189 --- /dev/null +++ b/lib/items-tech/table/add-items-dialog.tsx @@ -0,0 +1,400 @@ +"use client" + +import * as React from "react" +import { useRouter } from "next/navigation" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import { Plus } from "lucide-react" +import * as z from "zod" + +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { Textarea } from "@/components/ui/textarea" +import { toast } from "sonner" + +import { createShipbuildingItem, createOffshoreTopItem, createOffshoreHullItem } from "../service" +import { ItemType } from "./delete-items-dialog" + +// 조선 공종 유형 정의 +const shipbuildingWorkTypes = [ + { label: "기장", value: "기장" }, + { label: "전장", value: "전장" }, + { label: "선실", value: "선실" }, + { label: "배관", value: "배관" }, + { label: "철의", value: "철의" }, +] as const + +// 선종 유형 정의 +const shipTypes = [ + { label: "A-MAX", value: "A-MAX" }, + { label: "S-MAX", value: "S-MAX" }, + { label: "LNGC", value: "LNGC" }, + { label: "VLCC", value: "VLCC" }, + { label: "CONT", value: "CONT" }, +] as const + +// 해양 TOP 공종 유형 정의 +const offshoreTopWorkTypes = [ + { label: "TM", value: "TM" }, + { label: "TS", value: "TS" }, + { label: "TE", value: "TE" }, + { label: "TP", value: "TP" }, +] as const + +// 해양 HULL 공종 유형 정의 +const offshoreHullWorkTypes = [ + { label: "HA", value: "HA" }, + { label: "HE", value: "HE" }, + { label: "HH", value: "HH" }, + { label: "HM", value: "HM" }, + { label: "NC", value: "NC" }, +] as const + +// 기본 아이템 스키마 +const itemFormSchema = z.object({ + itemCode: z.string().min(1, "아이템 코드는 필수입니다"), + itemName: z.string().min(1, "아이템 명은 필수입니다"), + description: z.string().optional(), + workType: z.string().min(1, "공종은 필수입니다"), + // 조선 아이템 전용 필드 + shipTypes: z.string().optional(), + // 해양 아이템 전용 필드 + itemList1: z.string().optional(), + itemList2: z.string().optional(), + itemList3: z.string().optional(), + itemList4: z.string().optional(), +}) + +type ItemFormValues = z.infer + +interface AddItemDialogProps { + itemType: ItemType +} + +export function AddItemDialog({ itemType }: AddItemDialogProps) { + const router = useRouter() + const [open, setOpen] = React.useState(false) + + // 기본값 설정 + const getDefaultValues = () => { + const defaults: ItemFormValues = { + itemCode: "", + itemName: "", + description: "", + workType: getDefaultWorkType(), + } + + if (itemType === 'shipbuilding') { + defaults.shipTypes = "A-MAX" + } else { + defaults.itemList1 = "" + defaults.itemList2 = "" + defaults.itemList3 = "" + defaults.itemList4 = "" + } + + return defaults + } + + const getDefaultWorkType = () => { + switch (itemType) { + case 'shipbuilding': + return "기장" + case 'offshoreTop': + return "TM" + case 'offshoreHull': + return "HA" + default: + return "" + } + } + + const form = useForm({ + resolver: zodResolver(itemFormSchema), + defaultValues: getDefaultValues(), + }) + + const onSubmit = async (data: ItemFormValues) => { + try { + switch (itemType) { + case 'shipbuilding': + if (!data.shipTypes) { + toast.error("선종은 필수입니다") + return + } + + await createShipbuildingItem({ + itemCode: data.itemCode, + itemName: data.itemName, + workType: data.workType, + shipTypes: data.shipTypes, + description: data.description || null + }); + break; + + case 'offshoreTop': + await createOffshoreTopItem({ + itemCode: data.itemCode, + itemName: data.itemName, + workType: data.workType as "TM" | "TS" | "TE" | "TP", + description: data.description || null, + itemList1: data.itemList1 || null, + itemList2: data.itemList2 || null, + itemList3: data.itemList3 || null, + itemList4: data.itemList4 || null + }); + break; + + case 'offshoreHull': + await createOffshoreHullItem({ + itemCode: data.itemCode, + itemName: data.itemName, + workType: data.workType as "HA" | "HE" | "HH" | "HM" | "NC", + description: data.description || null, + itemList1: data.itemList1 || null, + itemList2: data.itemList2 || null, + itemList3: data.itemList3 || null, + itemList4: data.itemList4 || null + }); + break; + + default: + toast.error("지원하지 않는 아이템 타입입니다"); + return; + } + + toast.success("아이템이 성공적으로 추가되었습니다") + setOpen(false) + form.reset(getDefaultValues()) + router.refresh() + } catch (error) { + toast.error("아이템 추가 중 오류가 발생했습니다") + console.error(error) + } + } + + const getItemTypeLabel = () => { + switch (itemType) { + case 'shipbuilding': + return '조선 아이템'; + case 'offshoreTop': + return '해양 TOP 아이템'; + case 'offshoreHull': + return '해양 HULL 아이템'; + default: + return '아이템'; + } + } + + const getWorkTypeOptions = () => { + switch (itemType) { + case 'shipbuilding': + return shipbuildingWorkTypes; + case 'offshoreTop': + return offshoreTopWorkTypes; + case 'offshoreHull': + return offshoreHullWorkTypes; + default: + return []; + } + } + + return ( + + + + + + + + {getItemTypeLabel()} 추가 + + + 새로운 {getItemTypeLabel()}을 추가합니다. + + +
+ + ( + + 아이템 코드 + + + + + + )} + /> + ( + + 아이템 명 + + + + + + )} + /> + ( + + 공종 + + + + )} + /> + {itemType === 'shipbuilding' && ( + ( + + 선종 + + + + )} + /> + )} + {(itemType === 'offshoreTop' || itemType === 'offshoreHull') && ( + <> + ( + + 아이템 리스트 1 + + + + + + )} + /> + ( + + 아이템 리스트 2 + + + + + + )} + /> + ( + + 아이템 리스트 3 + + + + + + )} + /> + ( + + 아이템 리스트 4 + + + + + + )} + /> + + )} + ( + + 설명 + +