1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
"use client";
import * as React from "react";
import { useParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import { DataTable } from "@/components/data-table/data-table";
import { Button } from "@/components/ui/button";
import { Plus, Loader2 } from "lucide-react";
import { useDataTable } from "@/hooks/use-data-table";
import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar";
import type {
DataTableAdvancedFilterField,
DataTableFilterField,
DataTableRowAction,
} from "@/types/table"
import { toast } from "sonner";
import { getColumns } from "./basic-contract-columns";
import { getBasicContracts, getBasicContractsByVendorId } from "../service";
import { BasicContractView } from "@/db/schema";
import { BasicContractTableToolbarActions } from "./basicContract-table-toolbar-actions";
interface BasicTemplateTableProps {
promises: Promise<
[
Awaited<ReturnType<typeof getBasicContractsByVendorId>>,
]
>
}
export function BasicContractsVendorTable({ promises }: BasicTemplateTableProps) {
const params = useParams();
const lng = (params?.lng as string) || "ko";
const { t, ready } = useTranslation(lng, "procurement");
const [rowAction, setRowAction] =
React.useState<DataTableRowAction<BasicContractView> | null>(null)
const [{ data, pageCount }] =
React.use(promises)
// 안전한 번역 함수 (fallback 포함)
const safeT = React.useCallback((key: string, fallback: string) => {
if (!ready) return fallback;
const translated = t(key);
return translated === key ? fallback : translated;
}, [t, ready]);
// 디버깅용 로그 (개발환경에서만)
React.useEffect(() => {
if (process.env.NODE_ENV === 'development') {
console.log('Translation ready:', ready);
console.log('Current language:', lng);
console.log('Template name translation:', t("basicContracts.templateName"));
console.log('Status PENDING translation:', t("basicContracts.statusValues.PENDING"));
}
}, [ready, lng, t]);
// 컬럼 설정 - 번역이 준비된 후에만 생성
const columns = React.useMemo(
() => {
if (!ready) return []; // 번역이 준비되지 않으면 빈 배열 반환
return getColumns({ setRowAction, locale: lng, t });
},
[setRowAction, lng, t, ready]
)
// config 기반으로 필터 필드 설정 - 안전한 번역 함수 사용
const advancedFilterFields: DataTableAdvancedFilterField<BasicContractView>[] = React.useMemo(() => {
return [
{
id: "templateName",
label: safeT("basicContracts.templateName", lng === 'ko' ? "템플릿명" : "Template Name"),
type: "text"
},
{
id: "status",
label: safeT("basicContracts.status", lng === 'ko' ? "상태" : "Status"),
type: "select",
options: [
{
label: safeT("basicContracts.statusValues.PENDING", lng === 'ko' ? "서명대기" : "Pending"),
value: "PENDING"
},
{
label: safeT("basicContracts.statusValues.COMPLETED", lng === 'ko' ? "서명완료" : "Completed"),
value: "COMPLETED"
},
]
},
{
id: "createdAt",
label: safeT("basicContracts.createdAt", lng === 'ko' ? "생성일" : "Created Date"),
type: "date"
},
{
id: "updatedAt",
label: safeT("basicContracts.updatedAt", lng === 'ko' ? "수정일" : "Updated Date"),
type: "date"
},
];
}, [safeT, lng]);
const { table } = useDataTable({
data,
columns,
pageCount,
enablePinning: true,
enableAdvancedFilter: true,
initialState: {
sorting: [{ id: "createdAt", desc: true }],
columnPinning: { right: ["actions"] },
},
getRowId: (originalRow) => String(originalRow.id),
shallow: false,
clearOnDefault: true,
})
return (
<>
<DataTable table={table}>
<DataTableAdvancedToolbar
table={table}
filterFields={advancedFilterFields}
>
<BasicContractTableToolbarActions table={table} />
</DataTableAdvancedToolbar>
</DataTable>
</>
);
}
|