'use client'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { DataTable } from '@/components/common/data-table'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; import { useProjects, useCreateProject, useUpdateProject, useDeleteProject } from '@/hooks/use-projects'; import { ColumnDef } from '@tanstack/react-table'; import { Pencil, Trash, Plus, Folder, Search as SearchIcon } from 'lucide-react'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Badge } from '@/components/ui/badge'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Skeleton } from '@/components/ui/skeleton'; interface Project { id: string; // ADR-019: uuid exposed as 'id' projectCode: string; projectName: string; isActive: boolean; createdAt: string; updatedAt: string; } const projectSchema = z.object({ projectCode: z.string().min(1, 'Project Code is required'), projectName: z.string().min(1, 'Project Name is required'), isActive: z.boolean().optional(), }); type ProjectFormData = z.infer; export default function ProjectsPage() { const [search, setSearch] = useState(''); const { data: projects, isLoading } = useProjects({ search: search || undefined }); const createProject = useCreateProject(); const updateProject = useUpdateProject(); const deleteProject = useDeleteProject(); const [dialogOpen, setDialogOpen] = useState(false); const [editingUuid, setEditingUuid] = useState(null); // Stats for Delete Dialog const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [projectToDelete, setProjectToDelete] = useState(null); const handleDeleteClick = (project: Project) => { setProjectToDelete(project); setDeleteDialogOpen(true); }; const confirmDelete = () => { if (projectToDelete) { deleteProject.mutate(projectToDelete.id, { onSuccess: () => { setDeleteDialogOpen(false); setProjectToDelete(null); }, }); } }; const { register, handleSubmit, reset, setValue, watch, formState: { errors }, } = useForm({ resolver: zodResolver(projectSchema), defaultValues: { projectCode: '', projectName: '', isActive: true, }, }); const columns: ColumnDef[] = [ { accessorKey: 'projectCode', header: 'Code', cell: ({ row }) => (
{row.original.projectCode}
), }, { accessorKey: 'projectName', header: 'Project Name' }, { accessorKey: 'isActive', header: 'Status', cell: ({ row }) => ( {row.original.isActive ? 'Active' : 'Inactive'} ), }, { id: 'actions', header: 'Actions', cell: ({ row }) => ( handleEdit(row.original)}> Edit handleDeleteClick(row.original)} > Delete ), }, ]; const handleEdit = (project: Project) => { setEditingUuid(project.id); reset({ projectCode: project.projectCode, projectName: project.projectName, isActive: project.isActive, }); setDialogOpen(true); }; const handleCreate = () => { setEditingUuid(null); reset({ projectCode: '', projectName: '', isActive: true, }); setDialogOpen(true); }; const onSubmit = (data: ProjectFormData) => { if (editingUuid) { updateProject.mutate( { uuid: editingUuid, data }, { onSuccess: () => setDialogOpen(false), } ); } else { createProject.mutate(data, { onSuccess: () => setDialogOpen(false), }); } }; return (

Projects

Manage construction projects and configurations

setSearch(e.target.value)} className="pl-8 bg-background" />
{isLoading ? (
{[1, 2, 3, 4, 5].map((i) => (
))}
) : ( )} {editingUuid ? 'Edit Project' : 'New Project'}
{errors.projectCode &&

{errors.projectCode.message}

}
{errors.projectName &&

{errors.projectName.message}

}
setValue('isActive', checked)} />
Are you absolutely sure? This action cannot be undone. This will permanently delete the project {projectToDelete?.projectCode} and remove it from the system. Cancel {deleteProject.isPending ? 'Deleting...' : 'Delete Project'}
); }