251209:1453 Frontend: progress nest = UAT & Bug Fixing
Some checks failed
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled

This commit is contained in:
admin
2025-12-09 14:53:42 +07:00
parent 8aceced902
commit aa96cd90e3
125 changed files with 11052 additions and 785 deletions

View File

@@ -0,0 +1,53 @@
"use client";
import { GenericCrudTable } from "@/components/admin/reference/generic-crud-table";
import { ColumnDef } from "@tanstack/react-table";
import apiClient from "@/lib/api/client";
// Service wrapper
const correspondenceTypeService = {
getAll: async () => (await apiClient.get("/master/correspondence-types")).data,
create: async (data: any) => (await apiClient.post("/master/correspondence-types", data)).data,
update: async (id: number, data: any) => (await apiClient.patch(`/master/correspondence-types/${id}`, data)).data,
delete: async (id: number) => (await apiClient.delete(`/master/correspondence-types/${id}`)).data,
};
export default function CorrespondenceTypesPage() {
const columns: ColumnDef<any>[] = [
{
accessorKey: "type_code",
header: "Code",
cell: ({ row }) => (
<span className="font-mono font-bold">{row.getValue("type_code")}</span>
),
},
{
accessorKey: "type_name_th",
header: "Name (TH)",
},
{
accessorKey: "type_name_en",
header: "Name (EN)",
},
];
return (
<div className="p-6">
<GenericCrudTable
entityName="Correspondence Type"
title="Correspondence Types Management"
queryKey={["correspondence-types"]}
fetchFn={correspondenceTypeService.getAll}
createFn={correspondenceTypeService.create}
updateFn={correspondenceTypeService.update}
deleteFn={correspondenceTypeService.delete}
columns={columns}
fields={[
{ name: "type_code", label: "Code", type: "text", required: true },
{ name: "type_name_th", label: "Name (TH)", type: "text", required: true },
{ name: "type_name_en", label: "Name (EN)", type: "text" },
]}
/>
</div>
);
}

View File

@@ -0,0 +1,62 @@
"use client";
import { GenericCrudTable } from "@/components/admin/reference/generic-crud-table";
import { masterDataService } from "@/lib/services/master-data.service";
import { ColumnDef } from "@tanstack/react-table";
export default function DisciplinesPage() {
const columns: ColumnDef<any>[] = [
{
accessorKey: "discipline_code",
header: "Code",
cell: ({ row }) => (
<span className="font-mono font-bold">{row.getValue("discipline_code")}</span>
),
},
{
accessorKey: "code_name_th",
header: "Name (TH)",
},
{
accessorKey: "code_name_en",
header: "Name (EN)",
},
{
accessorKey: "is_active",
header: "Status",
cell: ({ row }) => (
<span
className={`px-2 py-1 rounded-full text-xs ${
row.getValue("is_active")
? "bg-green-100 text-green-800"
: "bg-red-100 text-red-800"
}`}
>
{row.getValue("is_active") ? "Active" : "Inactive"}
</span>
),
},
];
return (
<div className="p-6">
<GenericCrudTable
entityName="Discipline"
title="Disciplines Management"
description="Manage system disciplines (e.g., ARCH, STR, MEC)"
queryKey={["disciplines"]}
fetchFn={() => masterDataService.getDisciplines()} // Assuming generic fetch supports no args for all
createFn={(data) => masterDataService.createDiscipline({ ...data, contractId: 1 })} // Default contract for now
updateFn={(id, data) => Promise.reject("Not implemented yet")} // Update endpoint might need addition
deleteFn={(id) => masterDataService.deleteDiscipline(id)}
columns={columns}
fields={[
{ name: "discipline_code", label: "Code", type: "text", required: true },
{ name: "code_name_th", label: "Name (TH)", type: "text", required: true },
{ name: "code_name_en", label: "Name (EN)", type: "text" },
{ name: "is_active", label: "Active", type: "checkbox" },
]}
/>
</div>
);
}

View File

@@ -0,0 +1,49 @@
"use client";
import { GenericCrudTable } from "@/components/admin/reference/generic-crud-table";
import { masterDataService } from "@/lib/services/master-data.service";
import { ColumnDef } from "@tanstack/react-table";
export default function DrawingCategoriesPage() {
const columns: ColumnDef<any>[] = [
{
accessorKey: "type_code",
header: "Code",
cell: ({ row }) => (
<span className="font-mono font-bold">{row.getValue("type_code")}</span>
),
},
{
accessorKey: "type_name",
header: "Name",
},
{
accessorKey: "classification",
header: "Classification",
cell: ({ row }) => (
<span className="capitalize">{row.getValue("classification") || "General"}</span>
),
},
];
return (
<div className="p-6">
<GenericCrudTable
entityName="Drawing Category (Sub-Type)"
title="Drawing Categories Management"
description="Manage drawing sub-types and categories"
queryKey={["drawing-categories"]}
fetchFn={() => masterDataService.getSubTypes(1)} // Default contract ID 1
createFn={(data) => masterDataService.createSubType({ ...data, contractId: 1 })}
updateFn={(id, data) => Promise.reject("Not implemented yet")}
deleteFn={(id) => Promise.reject("Not implemented yet")} // Delete might be restricted
columns={columns}
fields={[
{ name: "type_code", label: "Code", type: "text", required: true },
{ name: "type_name", label: "Name", type: "text", required: true },
{ name: "classification", label: "Classification", type: "text" },
]}
/>
</div>
);
}

View File

@@ -0,0 +1,57 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { BookOpen, Tag, Settings, Layers } from "lucide-react";
import Link from "next/link";
const refMenu = [
{
title: "Disciplines",
description: "Manage system-wide disciplines (e.g., ARCH, STR)",
href: "/admin/reference/disciplines",
icon: Layers,
},
{
title: "RFA Types",
description: "Manage RFA types and approve codes",
href: "/admin/reference/rfa-types",
icon: BookOpen,
},
{
title: "Correspondence Types",
description: "Manage generic correspondence types",
href: "/admin/reference/correspondence-types",
icon: Settings,
},
{
title: "Tags",
description: "Manage system tags for documents",
href: "/admin/reference/tags",
icon: Tag,
},
];
export default function ReferenceDataPage() {
return (
<div className="p-6 space-y-6">
<h1 className="text-2xl font-bold">Reference Data Management</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{refMenu.map((item) => (
<Link key={item.href} href={item.href}>
<Card className="hover:shadow-md transition-shadow cursor-pointer h-full">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">
{item.title}
</CardTitle>
<item.icon className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<p className="text-xs text-muted-foreground">
{item.description}
</p>
</CardContent>
</Card>
</Link>
))}
</div>
</div>
);
}

View File

@@ -0,0 +1,54 @@
"use client";
import { GenericCrudTable } from "@/components/admin/reference/generic-crud-table";
import { masterDataService } from "@/lib/services/master-data.service";
import { ColumnDef } from "@tanstack/react-table";
import apiClient from "@/lib/api/client";
// Extending masterDataService locally if needed or using direct API calls for specific RFA types logic
const rfaTypeService = {
getAll: async () => (await apiClient.get("/master/rfa-types")).data,
create: async (data: any) => (await apiClient.post("/master/rfa-types", data)).data, // Endpoint assumption
update: async (id: number, data: any) => (await apiClient.patch(`/master/rfa-types/${id}`, data)).data,
delete: async (id: number) => (await apiClient.delete(`/master/rfa-types/${id}`)).data,
};
export default function RfaTypesPage() {
const columns: ColumnDef<any>[] = [
{
accessorKey: "type_code",
header: "Code",
cell: ({ row }) => (
<span className="font-mono font-bold">{row.getValue("type_code")}</span>
),
},
{
accessorKey: "type_name_th",
header: "Name (TH)",
},
{
accessorKey: "type_name_en",
header: "Name (EN)",
},
];
return (
<div className="p-6">
<GenericCrudTable
entityName="RFA Type"
title="RFA Types Management"
queryKey={["rfa-types"]}
fetchFn={rfaTypeService.getAll}
createFn={rfaTypeService.create}
updateFn={rfaTypeService.update}
deleteFn={rfaTypeService.delete}
columns={columns}
fields={[
{ name: "type_code", label: "Code", type: "text", required: true },
{ name: "type_name_th", label: "Name (TH)", type: "text", required: true },
{ name: "type_name_en", label: "Name (EN)", type: "text" },
]}
/>
</div>
);
}

View File

@@ -0,0 +1,47 @@
"use client";
import { GenericCrudTable } from "@/components/admin/reference/generic-crud-table";
import { masterDataService } from "@/lib/services/master-data.service";
import { CreateTagDto } from "@/types/dto/master/tag.dto";
import { ColumnDef } from "@tanstack/react-table";
export default function TagsPage() {
const columns: ColumnDef<any>[] = [
{
accessorKey: "tag_name",
header: "Tag Name",
},
{
accessorKey: "description",
header: "Description",
},
];
return (
<GenericCrudTable
title="Tags"
description="Manage system tags."
entityName="Tag"
queryKey={["tags"]}
fetchFn={() => masterDataService.getTags()}
createFn={(data: CreateTagDto) => masterDataService.createTag(data)}
updateFn={(id, data) => masterDataService.updateTag(id, data)}
deleteFn={(id) => masterDataService.deleteTag(id)}
columns={columns}
fields={[
{
name: "tag_name",
label: "Tag Name",
type: "text",
required: true,
},
{
name: "description",
label: "Description",
type: "textarea",
required: false,
},
]}
/>
);
}