# TASK-FE-010: Admin Panel & Settings UI
**ID:** TASK-FE-010
**Title:** Admin Panel for User & Master Data Management
**Category:** Administration
**Priority:** P2 (Medium)
**Effort:** 5-7 days
**Dependencies:** TASK-FE-002, TASK-FE-005, TASK-BE-012, TASK-BE-013
**Assigned To:** Frontend Developer
---
## ๐ Overview
Build comprehensive Admin Panel for managing users, roles, master data (organizations, projects, contracts, disciplines, document types), system settings, and viewing audit logs.
---
## ๐ฏ Objectives
1. Create admin layout with separate navigation
2. Build User Management UI (CRUD users, assign roles)
3. Implement Master Data Management screens
4. Create System Settings interface
5. Build Audit Logs viewer
6. Add bulk operations and data import/export
---
## โ
Acceptance Criteria
- [ ] Admin area accessible only to admins
- [ ] User management (create/edit/delete/deactivate)
- [ ] Role assignment with permission preview
- [ ] Master data CRUD (Organizations, Projects, etc.)
- [ ] Audit logs searchable and filterable
- [ ] System settings editable
- [ ] CSV import/export for bulk operations
---
## ๐ง Implementation Steps
### Step 1: Admin Layout
```typescript
// File: src/app/(admin)/layout.tsx
import { AdminSidebar } from '@/components/admin/sidebar';
import { redirect } from 'next/navigation';
import { getServerSession } from 'next-auth';
export default async function AdminLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerSession();
// Check if user has admin role
if (!session?.user?.roles?.some((r) => r.role_name === 'ADMIN')) {
redirect('/');
}
return (
);
}
```
### Step 2: User Management Page
```typescript
// File: src/app/(admin)/admin/users/page.tsx
'use client';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { DataTable } from '@/components/common/data-table';
import { UserDialog } from '@/components/admin/user-dialog';
import { ColumnDef } from '@tanstack/react-table';
import { Badge } from '@/components/ui/badge';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { MoreHorizontal, Plus } from 'lucide-react';
export default function UsersPage() {
const [users, setUsers] = useState([]);
const [dialogOpen, setDialogOpen] = useState(false);
const [selectedUser, setSelectedUser] = useState(null);
const columns: ColumnDef[] = [
{
accessorKey: 'username',
header: 'Username',
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'first_name',
header: 'Name',
cell: ({ row }) => `${row.original.first_name} ${row.original.last_name}`,
},
{
accessorKey: 'is_active',
header: 'Status',
cell: ({ row }) => (
{row.original.is_active ? 'Active' : 'Inactive'}
),
},
{
id: 'roles',
header: 'Roles',
cell: ({ row }) => (
{row.original.roles?.map((role: any) => (
{role.role_name}
))}
),
},
{
id: 'actions',
cell: ({ row }) => (
{
setSelectedUser(row.original);
setDialogOpen(true);
}}
>
Edit
handleDeactivate(row.original.user_id)}
>
{row.original.is_active ? 'Deactivate' : 'Activate'}
Delete
),
},
];
return (
User Management
Manage system users and their roles
);
}
```
### Step 3: User Create/Edit Dialog
```typescript
// File: src/components/admin/user-dialog.tsx
'use client';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
const userSchema = z.object({
username: z.string().min(3),
email: z.string().email(),
first_name: z.string().min(1),
last_name: z.string().min(1),
password: z.string().min(6).optional(),
is_active: z.boolean().default(true),
roles: z.array(z.number()),
});
type UserFormData = z.infer;
interface UserDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
user?: any;
}
export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
const {
register,
handleSubmit,
setValue,
watch,
formState: { errors },
} = useForm({
resolver: zodResolver(userSchema),
defaultValues: user || {},
});
const availableRoles = [
{ role_id: 1, role_name: 'ADMIN', description: 'System Administrator' },
{ role_id: 2, role_name: 'USER', description: 'Regular User' },
{ role_id: 3, role_name: 'APPROVER', description: 'Document Approver' },
];
const selectedRoles = watch('roles') || [];
const onSubmit = async (data: UserFormData) => {
// Call API to create/update user
console.log(data);
onOpenChange(false);
};
return (
);
}
```
### Step 4: Master Data Management (Organizations)
```typescript
// File: src/app/(admin)/admin/organizations/page.tsx
'use client';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { DataTable } from '@/components/common/data-table';
import { Card } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
export default function OrganizationsPage() {
const [organizations, setOrganizations] = useState([]);
const [dialogOpen, setDialogOpen] = useState(false);
const [formData, setFormData] = useState({
org_code: '',
org_name: '',
org_name_th: '',
description: '',
});
const columns = [
{ accessorKey: 'org_code', header: 'Code' },
{ accessorKey: 'org_name', header: 'Name (EN)' },
{ accessorKey: 'org_name_th', header: 'Name (TH)' },
{ accessorKey: 'description', header: 'Description' },
];
const handleSubmit = async () => {
// Call API to create organization
console.log(formData);
setDialogOpen(false);
};
return (
Organizations
Manage project organizations
);
}
```
### Step 5: Audit Logs Viewer
```typescript
// File: src/app/(admin)/admin/audit-logs/page.tsx
'use client';
import { useState } from 'react';
import { Card } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Badge } from '@/components/ui/badge';
import { formatDistanceToNow } from 'date-fns';
export default function AuditLogsPage() {
const [logs, setLogs] = useState([]);
const [filters, setFilters] = useState({
user: '',
action: '',
entity: '',
});
return (
Audit Logs
View system activity and changes
{/* Filters */}
{/* Logs List */}
{logs.map((log: any) => (
{log.user_name}
{log.action}
{log.entity_type}
{log.description}
{formatDistanceToNow(new Date(log.created_at), {
addSuffix: true,
})}
{log.ip_address && (
IP: {log.ip_address}
)}
))}
);
}
```
### Step 6: Admin Sidebar Navigation
```typescript
// File: src/components/admin/sidebar.tsx
'use client';
import Link from 'link';
import { usePathname } from 'next/navigation';
import { cn } from '@/lib/utils';
import { Users, Building2, Settings, FileText, Activity } from 'lucide-react';
const menuItems = [
{ href: '/admin/users', label: 'Users', icon: Users },
{ href: '/admin/organizations', label: 'Organizations', icon: Building2 },
{ href: '/admin/projects', label: 'Projects', icon: FileText },
{ href: '/admin/settings', label: 'Settings', icon: Settings },
{ href: '/admin/audit-logs', label: 'Audit Logs', icon: Activity },
];
export function AdminSidebar() {
const pathname = usePathname();
return (
);
}
```
---
## ๐ฆ Deliverables
- [ ] Admin layout with sidebar navigation
- [ ] User Management (CRUD, roles assignment)
- [ ] Master Data Management screens:
- [ ] Organizations
- [ ] Projects
- [ ] Contracts
- [ ] Disciplines
- [ ] Document Types
- [ ] System Settings interface
- [ ] Audit Logs viewer with filters
- [ ] CSV import/export functionality
---
## ๐งช Testing
### Test Cases
1. **User Management**
- Create new user
- Assign multiple roles
- Deactivate/activate user
- Delete user
2. **Master Data**
- Create organization
- Edit organization details
- Delete organization (check for dependencies)
3. **Audit Logs**
- View all logs
- Filter by user/action/entity
- Search logs
- Export logs
---
## ๐ Related Documents
- [TASK-BE-012: Master Data Management](./TASK-BE-012-master-data-management.md)
- [TASK-BE-013: User Management](./TASK-BE-013-user-management.md)
- [ADR-004: RBAC Implementation](../../05-decisions/ADR-004-rbac-implementation.md)
---
**Created:** 2025-12-01
**Status:** Ready