summaryrefslogtreecommitdiff
path: root/lib/gtc-contract/status
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gtc-contract/status')
-rw-r--r--lib/gtc-contract/status/create-gtc-document-dialog.tsx31
-rw-r--r--lib/gtc-contract/status/gtc-documents-table-columns.tsx175
-rw-r--r--lib/gtc-contract/status/update-gtc-document-sheet.tsx34
3 files changed, 126 insertions, 114 deletions
diff --git a/lib/gtc-contract/status/create-gtc-document-dialog.tsx b/lib/gtc-contract/status/create-gtc-document-dialog.tsx
index 98cd249f..003e4d51 100644
--- a/lib/gtc-contract/status/create-gtc-document-dialog.tsx
+++ b/lib/gtc-contract/status/create-gtc-document-dialog.tsx
@@ -10,6 +10,7 @@ import { Textarea } from "@/components/ui/textarea"
import {
Form,
FormControl,
+ FormDescription,
FormField,
FormItem,
FormLabel,
@@ -43,14 +44,17 @@ import { createGtcDocumentSchema, type CreateGtcDocumentSchema } from "@/lib/gtc
import { createGtcDocument, getProjectsForSelect } from "@/lib/gtc-contract/service"
import { type Project } from "@/db/schema/projects"
import { useSession } from "next-auth/react"
+import { Input } from "@/components/ui/input"
+import { useRouter } from "next/navigation";
export function CreateGtcDocumentDialog() {
const [open, setOpen] = React.useState(false)
const [projects, setProjects] = React.useState<Project[]>([])
const [isCreatePending, startCreateTransition] = React.useTransition()
const { data: session } = useSession()
+ const router = useRouter();
- const currentUserId =React.useMemo(() => {
+ const currentUserId = React.useMemo(() => {
return session?.user?.id ? Number(session.user.id) : null;
}, [session]);
@@ -68,6 +72,7 @@ export function CreateGtcDocumentDialog() {
defaultValues: {
type: "standard",
projectId: null,
+ title: "",
revision: 0,
editReason: "",
},
@@ -88,7 +93,7 @@ export function CreateGtcDocumentDialog() {
...data,
createdById: currentUserId
})
-
+
if (result.error) {
toast.error(`에러: ${result.error}`)
return
@@ -96,6 +101,8 @@ export function CreateGtcDocumentDialog() {
form.reset()
setOpen(false)
+ router.refresh();
+
toast.success("GTC 문서가 생성되었습니다.")
} catch (error) {
toast.error("문서 생성 중 오류가 발생했습니다.")
@@ -241,6 +248,26 @@ export function CreateGtcDocumentDialog() {
/>
)}
+ <FormField
+ control={form.control}
+ name="title"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>GTC 제목 (선택사항)</FormLabel>
+ <FormControl>
+ <Input
+ placeholder="GTC 제목를 입력하세요..."
+ {...field}
+ />
+ </FormControl>
+ <FormDescription>
+ 워드의 제목으로 사용됩니다.
+ </FormDescription>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
{/* 편집 사유 */}
<FormField
control={form.control}
diff --git a/lib/gtc-contract/status/gtc-documents-table-columns.tsx b/lib/gtc-contract/status/gtc-documents-table-columns.tsx
index f6eb81d0..cd02a3e5 100644
--- a/lib/gtc-contract/status/gtc-documents-table-columns.tsx
+++ b/lib/gtc-contract/status/gtc-documents-table-columns.tsx
@@ -4,8 +4,9 @@ import * as React from "react"
import { type DataTableRowAction } from "@/types/table"
import { type ColumnDef } from "@tanstack/react-table"
import { Ellipsis, Eye } from "lucide-react"
+import type { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"
-import { formatDate, formatDateTime } from "@/lib/utils"
+import { formatDate } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
@@ -23,16 +24,11 @@ import { type GtcDocumentWithRelations } from "@/db/schema/gtc"
interface GetColumnsProps {
setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<GtcDocumentWithRelations> | null>>
+ router: AppRouterInstance // ← 추가
}
-/**
- * GTC Documents 테이블 컬럼 정의
- */
+/** GTC Documents 테이블 컬럼 정의 (그룹 헤더 제거) */
export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef<GtcDocumentWithRelations>[] {
-
- // ----------------------------------------------------------------
- // 1) select 컬럼 (체크박스)
- // ----------------------------------------------------------------
const selectColumn: ColumnDef<GtcDocumentWithRelations> = {
id: "select",
header: ({ table }) => (
@@ -59,165 +55,145 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef
enableHiding: false,
}
- // ----------------------------------------------------------------
- // 2) 기본 정보 그룹
- // ----------------------------------------------------------------
const basicInfoColumns: ColumnDef<GtcDocumentWithRelations>[] = [
{
accessorKey: "type",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구분" />,
cell: ({ row }) => {
- const type = row.getValue("type") as string;
+ const type = row.getValue("type") as string
return (
<Badge variant={type === "standard" ? "default" : "secondary"}>
{type === "standard" ? "표준" : "프로젝트"}
</Badge>
- );
+ )
},
size: 100,
enableResizing: true,
- meta: {
- excelHeader: "구분",
- },
+ meta: { excelHeader: "구분" },
},
{
accessorKey: "project",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트" />,
cell: ({ row }) => {
- const project = row.original.project;
- if (!project) {
- return <span className="text-muted-foreground">-</span>;
- }
+ const project = row.original.project
+ if (!project) return <span className="text-muted-foreground">-</span>
return (
<div className="flex flex-col min-w-0">
<span className="font-medium truncate">{project.name}</span>
<span className="text-xs text-muted-foreground">{project.code}</span>
</div>
- );
+ )
},
size: 200,
enableResizing: true,
- meta: {
- excelHeader: "프로젝트",
+ meta: { excelHeader: "프로젝트" },
+ },
+ {
+ accessorKey: "title",
+ header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="GTC 제목" />,
+ cell: ({ row }) => {
+ const title = row.original.title
+ if (!title) return <span className="text-muted-foreground">-</span>
+ return (
+ <div className="flex flex-col min-w-0">
+ <span className="font-medium truncate">{title}</span>
+ </div>
+ )
},
+ size: 200,
+ enableResizing: true,
+ meta: { excelHeader: "GTC 제목" },
},
{
accessorKey: "revision",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="Rev." />,
cell: ({ row }) => {
- const revision = row.getValue("revision") as number;
- return <span className="font-mono text-sm">v{revision}</span>;
+ const revision = row.getValue("revision") as number
+ return <span className="font-mono text-sm">v{revision}</span>
},
size: 80,
enableResizing: true,
- meta: {
- excelHeader: "Rev.",
- },
+ meta: { excelHeader: "Rev." },
},
- ];
+ ]
- // ----------------------------------------------------------------
- // 3) 등록/수정 정보 그룹
- // ----------------------------------------------------------------
const auditColumns: ColumnDef<GtcDocumentWithRelations>[] = [
{
accessorKey: "createdAt",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최초등록일" />,
cell: ({ row }) => {
- const date = row.getValue("createdAt") as Date;
- return date ? formatDate(date, "KR") : "-";
+ const date = row.getValue("createdAt") as Date
+ return date ? formatDate(date, "KR") : "-"
},
size: 120,
enableResizing: true,
- meta: {
- excelHeader: "최초등록일",
- },
+ meta: { excelHeader: "최초등록일" },
},
{
accessorKey: "createdBy",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최초등록자" />,
cell: ({ row }) => {
- const createdBy = row.original.createdBy;
- return createdBy ? (
- <span className="text-sm">{createdBy.name}</span>
- ) : (
- <span className="text-muted-foreground">-</span>
- );
+ const createdBy = row.original.createdBy
+ return createdBy ? <span className="text-sm">{createdBy.name}</span> : <span className="text-muted-foreground">-</span>
},
size: 120,
enableResizing: true,
- meta: {
- excelHeader: "최초등록자",
- },
+ meta: { excelHeader: "최초등록자" },
},
{
accessorKey: "updatedAt",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정일" />,
cell: ({ row }) => {
- const date = row.getValue("updatedAt") as Date;
- return date ? formatDate(date, "KR") : "-";
+ const date = row.getValue("updatedAt") as Date
+ return date ? formatDate(date, "KR") : "-"
},
size: 120,
enableResizing: true,
- meta: {
- excelHeader: "최종수정일",
- },
+ meta: { excelHeader: "최종수정일" },
},
{
accessorKey: "updatedBy",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정자" />,
cell: ({ row }) => {
- const updatedBy = row.original.updatedBy;
- return updatedBy ? (
- <span className="text-sm">{updatedBy.name}</span>
- ) : (
- <span className="text-muted-foreground">-</span>
- );
+ const updatedBy = row.original.updatedBy
+ return updatedBy ? <span className="text-sm">{updatedBy.name}</span> : <span className="text-muted-foreground">-</span>
},
size: 120,
enableResizing: true,
- meta: {
- excelHeader: "최종수정자",
- },
+ meta: { excelHeader: "최종수정자" },
},
{
accessorKey: "editReason",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종 편집사유" />,
cell: ({ row }) => {
- const reason = row.getValue("editReason") as string;
+ const reason = row.getValue("editReason") as string
return reason ? (
<span className="text-sm" title={reason}>
{reason.length > 30 ? `${reason.substring(0, 30)}...` : reason}
</span>
) : (
<span className="text-muted-foreground">-</span>
- );
+ )
},
size: 200,
enableResizing: true,
- meta: {
- excelHeader: "최종 편집사유",
- },
+ meta: { excelHeader: "최종 편집사유" },
},
- ];
+ ]
- // ----------------------------------------------------------------
- // 4) actions 컬럼 (Dropdown 메뉴)
- // ----------------------------------------------------------------
const actionsColumn: ColumnDef<GtcDocumentWithRelations> = {
id: "actions",
enableHiding: false,
- cell: function Cell({ row }) {
- const [isUpdatePending, startUpdateTransition] = React.useTransition()
- const gtcDocument = row.original;
+ cell: ({ row }) => {
+ const gtcDocument = row.original
const handleViewDetails = () => {
- router.push(`/evcp/gtc-documents/${gtcDocument.id}`);
- };
+ router.push(`/evcp/basic-contract-template/gtc/${gtcDocument.id}`)
+ }
const handleCreateNewRevision = () => {
- setRowAction({ row, type: "createRevision" });
- };
+ setRowAction({ row, type: "createRevision" })
+ }
return (
<DropdownMenu>
@@ -227,32 +203,28 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef
variant="ghost"
className="flex size-8 p-0 data-[state=open]:bg-muted"
>
- <Ellipsis className="size-4" aria-hidden="true" />
+ <Ellipsis className="size-4" aria-hidden />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48">
<DropdownMenuItem onSelect={handleViewDetails}>
<Eye className="mr-2 h-4 w-4" />
- View Details
+ 상세
</DropdownMenuItem>
-
+
<DropdownMenuSeparator />
-
- <DropdownMenuItem
- onSelect={() => setRowAction({ row, type: "update" })}
- >
- Edit
+
+ <DropdownMenuItem onSelect={() => setRowAction({ row, type: "update" })}>
+ 수정
</DropdownMenuItem>
<DropdownMenuItem onSelect={handleCreateNewRevision}>
- Create New Revision
+ 새 리비전 생성
</DropdownMenuItem>
<DropdownMenuSeparator />
- <DropdownMenuItem
- onSelect={() => setRowAction({ row, type: "delete" })}
- >
- Delete
+ <DropdownMenuItem onSelect={() => setRowAction({ row, type: "delete" })}>
+ 삭제
<DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
@@ -262,28 +234,11 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef
size: 40,
}
- // ----------------------------------------------------------------
- // 5) 중첩 컬럼 그룹 생성
- // ----------------------------------------------------------------
- const nestedColumns: ColumnDef<GtcDocumentWithRelations>[] = [
- {
- id: "기본 정보",
- header: "기본 정보",
- columns: basicInfoColumns,
- },
- {
- id: "등록/수정 정보",
- header: "등록/수정 정보",
- columns: auditColumns,
- },
- ]
-
- // ----------------------------------------------------------------
- // 6) 최종 컬럼 배열
- // ----------------------------------------------------------------
+ // 그룹 없이 평평한 배열 반환
return [
selectColumn,
- ...nestedColumns,
+ ...basicInfoColumns,
+ ...auditColumns,
actionsColumn,
]
-} \ No newline at end of file
+}
diff --git a/lib/gtc-contract/status/update-gtc-document-sheet.tsx b/lib/gtc-contract/status/update-gtc-document-sheet.tsx
index 9d133ecc..6ba02a44 100644
--- a/lib/gtc-contract/status/update-gtc-document-sheet.tsx
+++ b/lib/gtc-contract/status/update-gtc-document-sheet.tsx
@@ -19,16 +19,19 @@ import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
+ FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Textarea } from "@/components/ui/textarea"
+import { useRouter } from "next/navigation";
import { type GtcDocumentWithRelations } from "@/db/schema/gtc"
import { updateGtcDocumentSchema, type UpdateGtcDocumentSchema } from "@/lib/gtc-contract/validations"
import { updateGtcDocument } from "@/lib/gtc-contract/service"
+import { Input } from "@/components/ui/input"
export interface UpdateGtcDocumentSheetProps
extends React.ComponentPropsWithRef<typeof Sheet> {
@@ -37,11 +40,13 @@ export interface UpdateGtcDocumentSheetProps
export function UpdateGtcDocumentSheet({ gtcDocument, ...props }: UpdateGtcDocumentSheetProps) {
const [isUpdatePending, startUpdateTransition] = React.useTransition()
-
+ const router = useRouter();
+
const form = useForm<UpdateGtcDocumentSchema>({
resolver: zodResolver(updateGtcDocumentSchema),
defaultValues: {
editReason: "",
+ title: "",
isActive: gtcDocument?.isActive ?? true,
},
})
@@ -50,7 +55,8 @@ export function UpdateGtcDocumentSheet({ gtcDocument, ...props }: UpdateGtcDocum
React.useEffect(() => {
if (gtcDocument) {
form.reset({
- editReason: "",
+ editReason: gtcDocument.editReason,
+ title:gtcDocument.title,
isActive: gtcDocument.isActive,
})
}
@@ -70,6 +76,8 @@ export function UpdateGtcDocumentSheet({ gtcDocument, ...props }: UpdateGtcDocum
form.reset()
props.onOpenChange?.(false)
+ router.refresh();
+
toast.success("GTC 문서가 업데이트되었습니다!")
} catch (error) {
toast.error("문서 업데이트 중 오류가 발생했습니다.")
@@ -104,6 +112,28 @@ export function UpdateGtcDocumentSheet({ gtcDocument, ...props }: UpdateGtcDocum
</div>
</div>
+
+ <FormField
+ control={form.control}
+ name="title"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>GTC 제목 (선택사항)</FormLabel>
+ <FormControl>
+ <Input
+ placeholder="GTC 제목를 입력하세요..."
+ {...field}
+ />
+ </FormControl>
+ <FormDescription>
+ 워드의 제목으로 사용됩니다.
+ </FormDescription>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+
{/* 편집 사유 */}
<FormField
control={form.control}