# 📋 แผนการพัฒนา Frontend (NestJS) - LCBP3-DMS v1.4.0
# 📋 แผนการพัฒนา Frontend (Next.js) - LCBP3-DMS v1.4.0
## 🎯 ภาพรวมโครงการ
พัฒนา Frontend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่ทันสมัย responsive และใช้งานง่าย รองรับการจัดการเอกสารที่ซับซ้อน มี Dashboard แบบ Real-time และระบบ Workflow Visualization
---
## 📐 สถาปัตยกรรมระบบ
### Technology Stack
- **Framework:** Next.js 14+ (App Router, React 18+, TypeScript, ESM)
- **Styling:** Tailwind CSS + PostCSS
- **Component Library:** shadcn/ui (Radix UI)
- **State Management:**
- **Server State:** TanStack Query (React Query)
- **Global Client State:** Zustand
- **Form State:** React Hook Form + Zod
- **Data Fetching:** Axios + TanStack Query
- **Authentication:** NextAuth.js (JWT Strategy)
- **File Upload:** React Dropzone
- **Tables:** TanStack Table
- **Charts:** Recharts
- **Date Picker:** date-fns + shadcn/ui Calendar
- **Icons:** Lucide React
- **Testing:**
- **Unit/Integration:** Vitest + React Testing Library
- **E2E:** Playwright
- **API Mocking:** Mock Service Worker (MSW)
### โครงสร้างโปรเจกต์
```
app/
├── (public)/ # Public routes (Landing, Login)
│ ├── page.tsx # Landing Page
│ └── login/ # Login Page
├── (protected)/ # Protected routes
│ ├── layout.tsx # App Shell (Navbar + Sidebar)
│ ├── dashboard/ # Dashboard
│ ├── correspondences/ # Correspondence Management
│ ├── rfas/ # RFA Management
│ ├── drawings/ # Drawing Management
│ ├── circulations/ # Circulation Management
│ ├── transmittals/ # Transmittal Management
│ ├── search/ # Advanced Search
│ ├── reports/ # Reports
│ ├── admin/ # Admin Panel
│ └── profile/ # User Profile
├── api/ # API Routes (if needed)
components/
├── ui/ # shadcn/ui components
├── features/ # Feature-specific components
│ ├── auth/
│ ├── correspondence/
│ ├── rfa/
│ ├── drawing/
│ ├── circulation/
│ └── common/
└── layouts/ # Layout components
lib/
├── api/ # API client & hooks
├── stores/ # Zustand stores
├── utils/ # Utility functions
├── hooks/ # Custom hooks
└── types/ # TypeScript types
public/
├── images/
└── fonts/
```
---
## 🗓️ แผนการพัฒนาแบบ Phase-Based
## **Phase 0: Setup & Infrastructure (สัปดาห์ที่ 1)**
### Milestone: สร้างโครงสร้างพื้นฐานและ Development Environment
#### Tasks:
**T0.1 Initialize Next.js Project**
- สร้างโปรเจกต์ด้วย `create-next-app`:
```bash
npx create-next-app@latest lcbp3-frontend --typescript --tailwind --app --src-dir=false
```
- เลือก Options:
- ✅ TypeScript
- ✅ ESLint
- ✅ Tailwind CSS
- ✅ App Router
- ✅ Import alias (@/\*)
- Setup .gitignore, README.md
- Deliverable: ✅ โปรเจกต์เริ่มต้นพร้อม
**T0.2 Install Core Dependencies**
```bash
# State Management & Data Fetching
npm install @tanstack/react-query zustand
npm install axios
npm install react-hook-form @hookform/resolvers zod
# UI Components & Styling
npm install clsx tailwind-merge
npm install lucide-react
npm install date-fns
# File Upload
npm install react-dropzone
# Authentication
npm install next-auth
# Development Tools
npm install -D @types/node
```
- Deliverable: ✅ Dependencies ติดตั้งสมบูรณ์
**T0.3 Setup shadcn/ui**
```bash
npx shadcn-ui@latest init
```
- เลือก Style: Default
- เลือก Base Color: Slate
- ติดตั้ง Components เบื้องต้น:
```bash
npx shadcn-ui@latest add button input label card table dropdown-menu
npx shadcn-ui@latest add dialog sheet toast alert
npx shadcn-ui@latest add form select textarea checkbox
npx shadcn-ui@latest add calendar popover
```
- Deliverable: ✅ shadcn/ui พร้อมใช้งาน
**T0.4 Configure Tailwind CSS**
- แก้ไข `tailwind.config.ts`:
- เพิ่ม Custom Colors (ตาม Brand)
- เพิ่ม Custom Fonts (ภาษาไทย: Noto Sans Thai)
- Configure Container, Spacing
- สร้าง `app/globals.css` พร้อม Custom Styles
- Deliverable: ✅ Tailwind พร้อมใช้
**T0.5 Setup Development Environment**
- สร้าง `.env.local`:
```
NEXT_PUBLIC_API_URL=http://backend.np-dms.work/api
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=...
```
- Setup ESLint Rules (ไทย Comments OK)
- Setup Prettier
- Setup VS Code Settings
- Deliverable: ✅ Dev Environment พร้อม
**T0.6 Setup Git & Docker**
- Push โปรเจกต์ไปยัง Gitea (git.np-dms.work)
- สร้าง Dockerfile สำหรับ Next.js:
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
```
- สร้าง docker-compose.yml (เชื่อม Network `lcbp3`)
- Deliverable: ✅ Project อยู่ใน Git + Docker พร้อม
---
## **Phase 1: Authentication & App Shell (สัปดาห์ที่ 2-3)**
### Milestone: ระบบ Login และ Layout หลัก
#### Tasks:
**T1.1 Setup API Client**
- สร้าง `lib/api/client.ts`:
```typescript
import axios from "axios";
export const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
"Content-Type": "application/json",
},
});
// Request Interceptor (Add JWT Token)
apiClient.interceptors.request.use((config) => {
const token = localStorage.getItem("access_token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response Interceptor (Handle Errors)
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Redirect to login
window.location.href = "/login";
}
return Promise.reject(error);
}
);
```
- Deliverable: ✅ API Client พร้อมใช้
**T1.2 Setup TanStack Query**
- สร้าง `app/providers.tsx`:
```typescript
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState } from "react";
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
refetchOnWindowFocus: false,
},
},
})
);
return (
{children}
);
}
```
- Wrap ใน `app/layout.tsx`
- Deliverable: ✅ React Query พร้อม
**T1.3 Create Auth Store (Zustand)**
- สร้าง `lib/stores/auth-store.ts`:
```typescript
import { create } from "zustand";
import { persist } from "zustand/middleware";
interface User {
user_id: number;
username: string;
email: string;
first_name: string;
last_name: string;
primary_organization_id: number;
permissions: string[];
}
interface AuthStore {
user: User | null;
token: string | null;
setAuth: (user: User, token: string) => void;
clearAuth: () => void;
hasPermission: (permission: string) => boolean;
}
export const useAuthStore = create()(
persist(
(set, get) => ({
user: null,
token: null,
setAuth: (user, token) => {
set({ user, token });
localStorage.setItem("access_token", token);
},
clearAuth: () => {
set({ user: null, token: null });
localStorage.removeItem("access_token");
},
hasPermission: (permission) => {
const user = get().user;
return user?.permissions.includes(permission) || false;
},
}),
{
name: "auth-storage",
}
)
);
```
- Deliverable: ✅ Auth Store พร้อม
**T1.4 Create Login Page**
- สร้าง `app/(public)/login/page.tsx`:
```typescript
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useRouter } from "next/navigation";
import { useAuthStore } from "@/lib/stores/auth-store";
import { apiClient } from "@/lib/api/client";
const loginSchema = z.object({
username: z.string().min(1, "กรุณากรอกชื่อผู้ใช้"),
password: z.string().min(1, "กรุณากรอกรหัสผ่าน"),
});
export default function LoginPage() {
const router = useRouter();
const setAuth = useAuthStore((state) => state.setAuth);
const form = useForm({
resolver: zodResolver(loginSchema),
});
const handleLogin = async (data: z.infer) => {
try {
const response = await apiClient.post("/auth/login", data);
const { access_token, user } = response.data;
setAuth(user, access_token);
router.push("/dashboard");
} catch (error) {
console.error("Login failed:", error);
// แสดง Toast Error
}
};
return (
);
}
```
- Deliverable: ✅ หน้า Login พร้อม
**T1.5 Create Landing Page**
- สร้าง `app/(public)/page.tsx`:
- Hero Section พร้อมข้อมูลโครงการ
- Feature Highlights
- CTA Button → Login
- ใช้ Tailwind + Animations
- Deliverable: ✅ Landing Page สวยงาม
**T1.6 Create Protected Layout (App Shell)**
- สร้าง `app/(protected)/layout.tsx`:
```typescript
"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuthStore } from "@/lib/stores/auth-store";
import Navbar from "@/components/layouts/navbar";
import Sidebar from "@/components/layouts/sidebar";
export default function ProtectedLayout({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter();
const user = useAuthStore((state) => state.user);
useEffect(() => {
if (!user) {
router.push("/login");
}
}, [user, router]);
if (!user) return null;
return (
);
}
```
- Deliverable: ✅ App Shell พร้อม
**T1.7 Create Navbar Component**
- สร้าง `components/layouts/navbar.tsx`:
- แสดงชื่อระบบ
- แสดงชื่อผู้ใช้ + Avatar
- Dropdown Menu:
- Profile
- Settings
- Logout
- Responsive (Mobile Hamburger Menu)
- Deliverable: ✅ Navbar พร้อม
**T1.8 Create Sidebar Component**
- สร้าง `components/layouts/sidebar.tsx`:
- เมนูหลัก:
- Dashboard
- Correspondences
- RFAs
- Drawings (Shop & Contract)
- Circulations
- Transmittals
- Search
- Reports
- เมนู Admin (แสดงตามสิทธิ์):
- Users
- Roles & Permissions
- Master Data
- Document Numbering
- Collapsible Sidebar
- Active State Highlighting
- Deliverable: ✅ Sidebar พร้อม
---
## **Phase 2: Dashboard & Common Components (สัปดาห์ที่ 4)**
### Milestone: Dashboard และ Reusable Components
#### Tasks:
**T2.1 Create Reusable Components**
- `components/features/common/data-table.tsx`:
- ใช้ TanStack Table
- รองรับ Pagination, Sorting, Filtering
- Responsive
- `components/features/common/file-upload.tsx`:
- ใช้ React Dropzone
- รองรับ Multi-file Upload
- Drag & Drop
- Progress Bar
- `components/features/common/status-badge.tsx`:
- แสดง Status แบบสีสัน (Draft, Submitted, Approved)
- `components/features/common/permission-guard.tsx`:
- ซ่อน/แสดง Component ตามสิทธิ์
- Deliverable: ✅ Reusable Components พร้อม
**T2.2 Create Dashboard Page**
- สร้าง `app/(protected)/dashboard/page.tsx`:
- **KPI Cards Section**:
- จำนวนเอกสารทั้งหมด
- งานที่รอดำเนินการ
- เอกสารที่เกินกำหนด
- RFA ที่รออนุมัติ
- **My Tasks Table**:
- ดึงข้อมูลจาก `/api/circulations/my-tasks` (ใช้ `v_user_tasks`)
- แสดงรายการงานที่ต้องทำ (Pending, In Progress)
- Columns: Document Number, Title, Type, Status, Deadline, Actions
- คลิกแถวแล้วไปยังหน้า Detail
- **Recent Activity Feed**:
- ดึงข้อมูลจาก `/api/audit-logs/user/:userId`
- แสดง 10 รายการล่าสุด
- Deliverable: ✅ Dashboard ครบถ้วน
**T2.3 Create API Hooks**
- สร้าง `lib/api/hooks/use-my-tasks.ts`:
```typescript
import { useQuery } from "@tanstack/react-query";
import { apiClient } from "../client";
export function useMyTasks() {
return useQuery({
queryKey: ["my-tasks"],
queryFn: async () => {
const response = await apiClient.get("/circulations/my-tasks");
return response.data;
},
});
}
```
- สร้าง Hooks เพิ่มเติม:
- `use-dashboard-stats.ts`
- `use-recent-activity.ts`
- Deliverable: ✅ API Hooks พร้อม
---
## **Phase 3: Correspondence Management (สัปดาห์ที่ 5-6)**
### Milestone: ระบบจัดการเอกสารโต้ตอบ
#### Tasks:
**T3.1 Create Correspondence List Page**
- สร้าง `app/(protected)/correspondences/page.tsx`:
- Data Table แสดงรายการเอกสาร
- Columns:
- Document Number (คลิกไปยัง Detail)
- Title
- Type
- Status (Badge)
- Originator
- Date
- Actions (View, Edit, Delete)
- Filters:
- ประเภทเอกสาร (Dropdown)
- สถานะ (Dropdown)
- วันที่ (Date Range Picker)
- องค์กร (Dropdown)
- Pagination (Server-side)
- Search Box
- Create Button (ตรวจสิทธิ์)
- Deliverable: ✅ หน้ารายการเอกสาร
**T3.2 Create Correspondence Detail Page**
- สร้าง `app/(protected)/correspondences/[id]/page.tsx`:
- **Header Section**:
- Document Number (ใหญ่)
- Status Badge
- Action Buttons: Edit, Delete, Export PDF
- **Metadata Section**:
- Title, Description
- Document Date, Issued Date, Received Date
- Originator, Recipients (TO/CC)
- Due Date (ถ้ามี)
- **Revision History**:
- แสดง Revisions ทั้งหมดเป็น Timeline
- แต่ละ Revision แสดง: Revision Number, Date, Changes, User
- **Attachments**:
- แสดงไฟล์แนบทั้งหมด
- กำหนดไฟล์หลัก (Main Document) ด้วยไอคอน
- ปุ่ม Download
- **References**:
- แสดงเอกสารที่อ้างถึง (Links)
- **Tags**:
- แสดง Tags แบบ Chips
- **Activity Log**:
- แสดง Audit Log ของเอกสารนี้
- Deliverable: ✅ หน้า Detail ครบถ้วน
**T3.3 Create Correspondence Form (Create/Edit)**
- สร้าง `app/(protected)/correspondences/create/page.tsx`:
- สร้าง `app/(protected)/correspondences/[id]/edit/page.tsx`:
- Form Fields:
- **Basic Info**:
- Correspondence Type (Dropdown)
- Title (Text)
- Description (Textarea)
- Document Date (Date Picker)
- **Recipients**:
- TO: Multi-select Organizations
- CC: Multi-select Organizations
- **References**:
- Search & Select เอกสารอื่นๆ
- **Tags**:
- Autocomplete Tag Input
- **Attachments**:
- File Upload (Multi-file)
- กำหนด Main Document (Radio)
- **Deadline**:
- Due Date (Date Picker)
- Validation ด้วย Zod
- Submit → API → Redirect to Detail
- Deliverable: ✅ ฟอร์มสร้าง/แก้ไข
**T3.4 Create Status Management**
- ใน Detail Page เพิ่มปุ่ม Status Actions:
- **Draft → Submit** (Document Control)
- **Submit → Close** (Admin)
- **Submit → Cancel** (Admin + Dialog ให้กรอกเหตุผล)
- แสดง Confirmation Dialog ก่อนเปลี่ยนสถานะ
- Deliverable: ✅ เปลี่ยนสถานะได้
---
## **Phase 4: RFA & Workflow Visualization (สัปดาห์ที่ 7-8)**
### Milestone: ระบบ RFA และ Workflow
#### Tasks:
**T4.1 Create RFA List Page**
- สร้าง `app/(protected)/rfas/page.tsx`:
- คล้าย Correspondence List
- Columns เพิ่มเติม:
- RFA Type (DWG, DOC, MAT)
- Approval Status (Badge)
- Approval Code (1A, 3R, etc.)
- Filters:
- RFA Type
- Status
- Approval Code
- Deliverable: ✅ หน้ารายการ RFA
**T4.2 Create RFA Detail Page**
- สร้าง `app/(protected)/rfas/[id]/page.tsx`:
- คล้าย Correspondence Detail
- เพิ่ม Section:
- **Shop Drawings** (สำหรับ RFA_DWG):
- แสดงรายการ Shop Drawings ที่เชื่อมโยง
- แสดง Revision ของแต่ละแบบ
- Link ไปยัง Shop Drawing Detail
- **Workflow Visualization** (ดูรายละเอียดใน T4.3)
- Deliverable: ✅ หน้า Detail RFA
**T4.3 Create Workflow Visualization Component**
- สร้าง `components/features/rfa/workflow-visualizer.tsx`:
- **Layout**: Steps แนวนอน (Timeline)
- **Step States**:
- ✅ **Completed**: สีเขียว, ไอคอน Check
- ⏳ **Active**: สีฟ้า, ปุ่ม Action เปิดใช้งาน
- ⏸️ **Pending**: สีเทา, ปุ่ม disabled
- ❌ **Rejected**: สีแดง
- **Step Info Card** (เมื่อคลิก):
- Organization
- Assigned User
- Action Type (Review, Approve)
- Status
- Comments
- Completed Date
- **Actions** (สำหรับ Active Step):
- ปุ่ม "อนุมัติ" (Approve)
- ปุ่ม "ปฏิเสธ" (Reject)
- Dialog ให้กรอก Comments
- **Admin Override**:
- ปุ่ม "ไปยังขั้นตอนต่อไป" (Skip Step)
- ปุ่ม "ย้อนกลับ" (Previous Step)
- Deliverable: ✅ Workflow Component พร้อม
**T4.4 Create RFA Form (Create/Edit)**
- สร้าง `app/(protected)/rfas/create/page.tsx`:
- Form Fields:
- RFA Type (Dropdown)
- Title, Description
- Document Date
- **Shop Drawings Section** (สำหรับ RFA_DWG):
- Search & Select Shop Drawings
- แสดง Revisions ที่มี (Dropdown)
- เพิ่มได้หลายแบบ
- Attachments
- Workflow Template (Dropdown)
- Submit → สร้าง RFA + Start Workflow
- Deliverable: ✅ ฟอร์ม RFA พร้อม
**T4.5 Implement Workflow Actions API**
- สร้าง `lib/api/hooks/use-rfa-workflow.ts`:
```typescript
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiClient } from "../client";
export function useCompleteWorkflowStep() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ rfaId, stepNumber, action, comments }) => {
const response = await apiClient.post(
`/rfas/${rfaId}/workflow/steps/${stepNumber}/complete`,
{ action, comments }
);
return response.data;
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries(["rfa", variables.rfaId]);
queryClient.invalidateQueries(["my-tasks"]);
},
});
}
```
- Hooks เพิ่มเติม:
- `use-reject-workflow-step.ts`
- `use-start-workflow.ts`
- Deliverable: ✅ Workflow Actions ทำงานได้
---
## **Phase 5: Drawing Management (สัปดาห์ที่ 9)**
### Milestone: ระบบจัดการแบบ
#### Tasks:
**T5.1 Create Shop Drawing List Page**
- สร้าง `app/(protected)/drawings/shop/page.tsx`:
- Data Table:
- Drawing Number
- Title
- Main Category
- Sub Category
- Current Revision
- Actions
- Filters:
- Category (Dropdown)
- Sub Category (Dropdown)
- Create Button
- Deliverable: ✅ หน้ารายการ Shop Drawings
**T5.2 Create Shop Drawing Detail Page**
- สร้าง `app/(protected)/drawings/shop/[id]/page.tsx`:
- **Header**: Drawing Number, Title
- **Current Revision Info**:
- Revision Number, Date
- Description
- Attachments (PDF, DWG)
- **Contract Drawing References**:
- แสดง Contract Drawings ที่อ้างถึง
- Links ไปยัง Contract Drawing Detail
- **Revision History**:
- แสดง Revisions ทั้งหมดเป็น Timeline
- **Related RFAs**:
- แสดง RFAs ที่เชื่อมโยงกับแบบนี้
- Deliverable: ✅ หน้า Detail Shop Drawing
**T5.3 Create Shop Drawing Form**
- สร้าง `app/(protected)/drawings/shop/create/page.tsx`:
- Form Fields:
- Drawing Number (Auto-generate หรือ Manual)
- Title
- Main Category (Dropdown)
- Sub Category (Dropdown, dependent on Main)
- **Contract Drawing References**:
- Search & Select Contract Drawings (Multi-select)
- **Revision Info**:
- Revision Number (Auto)
- Revision Label (A, B, C)
- Description
- **Attachments**:
- Upload PDF (Main)
- Upload DWG (Optional)
- Upload Other Files
- Deliverable: ✅ ฟอร์ม Shop Drawing
**T5.4 Create Contract Drawing List & Detail**
- สร้าง `app/(protected)/drawings/contract/page.tsx`:
- Data Table:
- Drawing Number
- Title
- Volume
- Category
- Sub Category
- Filters:
- Volume (Dropdown)
- Category (Dropdown)
- สร้าง `app/(protected)/drawings/contract/[id]/page.tsx`:
- แสดง Metadata
- Attachments
- **Referenced By**:
- แสดง Shop Drawings ที่อ้างถึงแบบนี้
- Deliverable: ✅ Contract Drawing Pages
---
## **Phase 6: Circulation & Transmittal (สัปดาห์ที่ 10)**
### Milestone: ระบบใบเวียนและเอกสารนำส่ง
#### Tasks:
**T6.1 Create Circulation List Page**
- สร้าง `app/(protected)/circulations/page.tsx`:
- Data Table:
- Circulation Number
- Subject
- Status (Badge)
- Created By
- Created Date
- Filters:
- Status
- Date Range
- Deliverable: ✅ หน้ารายการใบเวียน
**T6.2 Create Circulation Detail & Workflow**
- สร้าง `app/(protected)/circulations/[id]/page.tsx`:
- **Header**: Circulation Number, Subject, Status
- **Linked Correspondence**:
- Link ไปยังเอกสารต้นทาง
- **Workflow Visualization**:
- คล้าย RFA Workflow
- แสดง Steps:
- Organization
- Assigned Users (Main, Action, Information)
- Status
- Comments
- Deadline
- **Actions** (สำหรับ Assigned User):
- ปุ่ม "ดำเนินการเสร็จสิ้น" (Complete)
- Dialog ให้กรอก Comments
- **Close Circulation** (Document Control):
- ปุ่ม "ปิดใบเวียน" (เมื่อตอบกลับองค์กรผู้ส่งแล้ว)
- Deliverable: ✅ หน้า Detail ใบเวียน