"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"; interface Project { id: number; 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 [editingId, setEditingId] = useState(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 { if (confirm(`Delete project ${row.original.projectCode}?`)) { deleteProject.mutate(row.original.id); } }} > Delete ), }, ]; const handleEdit = (project: Project) => { setEditingId(project.id); reset({ projectCode: project.projectCode, projectName: project.projectName, isActive: project.isActive, }); setDialogOpen(true); }; const handleCreate = () => { setEditingId(null); reset({ projectCode: "", projectName: "", isActive: true, }); setDialogOpen(true); }; const onSubmit = (data: ProjectFormData) => { if (editingId) { updateProject.mutate( { id: editingId, 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 ? (
Loading projects...
) : ( )} {editingId ? "Edit Project" : "New Project"}
{errors.projectCode && (

{errors.projectCode.message}

)}
{errors.projectName && (

{errors.projectName.message}

)}
setValue("isActive", checked)} />
); }