feat: add shared validation for chainage and coordinates

This commit is contained in:
2026-06-23 18:32:38 +05:30
parent 066374bebc
commit b282fdf56d
7 changed files with 219 additions and 95 deletions

View File

@@ -74,7 +74,11 @@ export function PackageDialog({
</DialogDescription>
</DialogHeader>
<form noValidate onSubmit={onSubmit} className="flex min-h-0 flex-1 flex-col">
<form
noValidate
onSubmit={onSubmit}
className="flex min-h-0 flex-1 flex-col"
>
<div className="max-h-[58vh] space-y-6 overflow-y-auto px-6 py-4">
<section className="space-y-4">
<div className="space-y-1">
@@ -120,7 +124,7 @@ export function PackageDialog({
<FormField id="package-region" label="Region">
<Input
id="package-region"
placeholder="North Zone"
placeholder="Enter region"
{...register('region')}
/>
</FormField>
@@ -131,21 +135,22 @@ export function PackageDialog({
<div className="space-y-1">
<h3 className="text-sm font-semibold">Chainage range</h3>
<p className="text-sm text-muted-foreground">
Optional start and end kilometre values.
start and end kilometre values.
</p>
</div>
<div className="grid gap-4 md:grid-cols-2">
<FormField
id="package-start"
label="Start (km)"
label="Start Chainage"
error={startErrorMessage}
>
<Input
id="package-start"
type="number"
step="0.01"
placeholder="0.00"
step="1"
min="0"
placeholder="Enter start chainage"
aria-invalid={!!startErrorMessage}
{...register('chainage_start_km')}
/>
@@ -153,14 +158,15 @@ export function PackageDialog({
<FormField
id="package-end"
label="End (km)"
label="End Chainage"
error={endErrorMessage}
>
<Input
id="package-end"
type="number"
step="0.01"
placeholder="0.00"
step="1"
min="0"
placeholder="Enter end chainage"
aria-invalid={!!endErrorMessage}
{...register('chainage_end_km')}
/>
@@ -179,7 +185,9 @@ export function PackageDialog({
Cancel
</Button>
<Button type="submit" disabled={isSaving || !canSubmit}>
{isSaving ? <Loader2 className="mr-2 size-4 animate-spin" /> : null}
{isSaving ? (
<Loader2 className="mr-2 size-4 animate-spin" />
) : null}
{packageId ? 'Update Package' : 'Create Package'}
</Button>
</DialogFooter>

View File

@@ -7,29 +7,25 @@ import { useForm, useWatch } from 'react-hook-form';
import { toast } from 'sonner';
import { z } from 'zod';
import {
optionalIntegerNumber,
validateChainageRange,
} from '@/lib/validation/numberField';
import { packageService } from '@/services/api';
import type { Package, PackageCreate, PackageUpdate } from '@/types';
import { packageKeys } from '../queries/packageKeys';
const optionalNumber = z.string().refine(
(value) => {
if (!value.trim()) {
return true;
}
return Number.isFinite(Number(value));
},
{ message: 'Enter a valid number' },
);
const packageFormSchema = z.object({
id: z.string().optional(),
project_id: z.string().trim().min(1, 'Project is required'),
name: z.string().trim().min(1, 'Package name is required'),
region: z.string().optional(),
chainage_start_km: optionalNumber,
chainage_end_km: optionalNumber,
});
const packageFormSchema = z
.object({
id: z.string().optional(),
project_id: z.string().trim().min(1, 'Project is required'),
name: z.string().trim().min(1, 'Package name is required'),
region: z.string().optional(),
chainage_start_km: optionalIntegerNumber,
chainage_end_km: optionalIntegerNumber,
})
.superRefine(validateChainageRange);
export type PackageFormValues = z.infer<typeof packageFormSchema>;