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

@@ -66,7 +66,11 @@ export function ProjectDialog({
</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">
@@ -94,14 +98,14 @@ export function ProjectDialog({
<FormField id="project-state" label="State">
<Input
id="project-state"
placeholder="Maharashtra"
placeholder="Enter state"
{...register('state')}
/>
</FormField>
<FormField id="project-corridor" label="Corridor Name">
<Input
id="project-corridor"
placeholder="Mumbai-Goa Highway"
placeholder="Enter corridor name"
{...register('corridor_name')}
/>
</FormField>
@@ -127,7 +131,9 @@ export function ProjectDialog({
id="project-start-lat"
type="number"
step="any"
placeholder="0.0000"
min="-90"
max="90"
placeholder="Enter start latitude"
aria-invalid={!!startLatErrorMessage}
{...register('start_lat')}
/>
@@ -141,7 +147,9 @@ export function ProjectDialog({
id="project-start-lng"
type="number"
step="any"
placeholder="0.0000"
min="-180"
max="180"
placeholder="Enter start longitude"
aria-invalid={!!startLngErrorMessage}
{...register('start_lng')}
/>
@@ -158,7 +166,9 @@ export function ProjectDialog({
id="project-end-lat"
type="number"
step="any"
placeholder="0.0000"
min="-90"
max="90"
placeholder="Enter end latitude"
aria-invalid={!!endLatErrorMessage}
{...register('end_lat')}
/>
@@ -172,7 +182,9 @@ export function ProjectDialog({
id="project-end-lng"
type="number"
step="any"
placeholder="0.0000"
min="-180"
max="180"
placeholder="Enter end longitude"
aria-invalid={!!endLngErrorMessage}
{...register('end_lng')}
/>
@@ -192,7 +204,9 @@ export function ProjectDialog({
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}
{projectId ? 'Update Project' : 'Create Project'}
</Button>
</DialogFooter>

View File

@@ -7,30 +7,24 @@ import { useForm, useWatch } from 'react-hook-form';
import { toast } from 'sonner';
import { z } from 'zod';
import {
optionalLatitude,
optionalLongitude,
} from '@/lib/validation/numberField';
import { projectService } from '@/services/api';
import type { Project, ProjectCreate, ProjectUpdate } from '@/types';
import { projectKeys } from '../queries/projectKeys';
const optionalCoordinate = z.string().refine(
(value) => {
if (!value.trim()) {
return true;
}
return Number.isFinite(Number(value));
},
{ message: 'Enter a valid number' },
);
const projectFormSchema = z.object({
id: z.string().optional(),
name: z.string().trim().min(1, 'Project name is required'),
state: z.string().optional(),
corridor_name: z.string().optional(),
start_lat: optionalCoordinate,
start_lng: optionalCoordinate,
end_lat: optionalCoordinate,
end_lng: optionalCoordinate,
start_lat: optionalLatitude,
start_lng: optionalLongitude,
end_lat: optionalLatitude,
end_lng: optionalLongitude,
});
export type ProjectFormValues = z.infer<typeof projectFormSchema>;