145 lines
3.9 KiB
TypeScript
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}
|
|
/>
|
|
</>
|
|
);
|
|
}
|