Files
road-monitoring-ui/src/app/(modules)/segment/page.tsx

145 lines
3.9 KiB
TypeScript

'use client';
import { useCallback, useState } from 'react';
import { Milestone, Plus } from 'lucide-react';
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import type { Chainage } from '@/types';
import { SegmentDialog } from './components/SegmentDialog';
import { SegmentTable } from './components/SegmentTable';
import { useSegmentColumns } from './components/SegmentColumns';
import { useSegmentFilters } from './hooks/useSegmentFilters';
import { useSegmentForm } from './hooks/useSegmentForm';
import {
useAllPackageOptionsQuery,
useDeleteSegmentMutation,
useProjectOptionsQuery,
useSegmentsQuery,
} from './hooks/useSegmentQueries';
export default function SegmentPage() {
const [isDialogOpen, setIsDialogOpen] = useState(false);
const { skip, setSkip, limit, setLimit } = useSegmentFilters();
const segmentsQuery = useSegmentsQuery({ skip, limit });
const projectsQuery = useProjectOptionsQuery();
const allPackagesQuery = useAllPackageOptionsQuery();
const deleteSegmentMutation = useDeleteSegmentMutation();
const segmentForm = useSegmentForm({
onSaved: () => setIsDialogOpen(false),
});
const {
register,
onSubmit,
openCreate: prepareCreateSegment,
openEdit: prepareEditSegment,
resetForm,
segmentId,
projectId,
setProjectId,
packageId,
setPackageId,
direction,
setDirection,
errors,
isSubmitted,
canSubmit,
isSaving,
} = segmentForm;
const openCreate = useCallback(() => {
prepareCreateSegment();
setIsDialogOpen(true);
}, [prepareCreateSegment]);
const openEdit = useCallback(
(segment: Chainage) => {
const pkg = allPackagesQuery.data?.items.find(
(item) => item.id === segment.package_id,
);
prepareEditSegment(segment, pkg?.project_id || '');
setIsDialogOpen(true);
},
[allPackagesQuery.data?.items, prepareEditSegment],
);
const handleDialogOpenChange = useCallback(
(open: boolean) => {
setIsDialogOpen(open);
if (!open) {
resetForm();
}
},
[resetForm],
);
const deleteSegment = useCallback(
(segment: Chainage) => {
if (
!confirm(
`Are you sure you want to delete segment "${segment.segment_name}"?`,
)
) {
return;
}
deleteSegmentMutation.mutate(segment);
},
[deleteSegmentMutation],
);
const projects = projectsQuery.data?.items ?? [];
const allPackages = allPackagesQuery.data?.items ?? [];
const segments = segmentsQuery.data?.items ?? [];
const total = segmentsQuery.data?.totalItems ?? 0;
const columns = useSegmentColumns(projects, allPackages);
return (
<>
<main className="relative z-10 space-y-5">
<PageHeader
title="Segment Management"
description="Manage road segments"
icon={Milestone}
actions={
<Button onClick={openCreate} size="sm">
<Plus />
Add Segment
</Button>
}
/>
<SegmentTable
columns={columns}
segments={segments}
isLoading={segmentsQuery.isLoading || deleteSegmentMutation.isPending}
skip={skip}
limit={limit}
total={total}
onPageChange={setSkip}
onLimitChange={setLimit}
onEdit={openEdit}
onDelete={deleteSegment}
/>
</main>
<SegmentDialog
open={isDialogOpen}
onOpenChange={handleDialogOpenChange}
segmentId={segmentId}
projectId={projectId}
onProjectChange={setProjectId}
packageId={packageId}
onPackageChange={setPackageId}
direction={direction}
onDirectionChange={setDirection}
register={register}
errors={errors}
isSubmitted={isSubmitted}
onSubmit={onSubmit}
canSubmit={canSubmit}
isSaving={isSaving}
/>
</>
);
}