Skip to content

Commit ee91731

Browse files
committed
add agency booking form validation
1 parent be4a77f commit ee91731

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

src/app/_components/agencycomponents/agency-interactive-area.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { env } from "@/env";
1111
import { notify } from "@/lib/notifications";
1212
import { api } from "@/trpc/react";
1313
import { ViewMode } from "@/types/types";
14+
import { validateStringLength, validateTimeRange } from "@/types/validation";
1415
import TableView from "../agencypage/table-view";
1516
import CalendarView from "../calendar-view";
1617
import styles from "./agency-interactive-area.module.scss";
@@ -66,15 +67,24 @@ export const BookingInteractiveArea = ({ initialViewMode = ViewMode.CALENDAR }:
6667
},
6768

6869
validate: {
69-
title: (value) => (value.trim().length > 0 ? null : "Title is required"),
70-
residentName: (value) => (value.trim().length > 0 ? null : "Resident name is required"),
71-
contactInfo: (value) => (value.trim().length > 0 ? null : "Contact info is required"),
70+
title: (value) => validateStringLength(value, 1, 150, "Booking name"),
71+
residentName: (value) => validateStringLength(value, 1, 100, "Resident name"),
72+
contactInfo: (value) => validateStringLength(value, 1, 150, "Contact information"),
73+
additionalInfo: (value) => {
74+
// Optional field, only validate max length if provided
75+
if (value.trim().length === 0) return null;
76+
return validateStringLength(value, 0, 500, "Additional information");
77+
},
7278
startTime: (value) => (value.trim().length > 0 ? null : "Date and time is required"),
73-
endTime: (value) => (value.trim().length > 0 ? null : "Date and time is required"),
74-
purpose: (value) => (value.trim().length > 0 ? null : "Purpose is required"),
75-
pickupAddress: (value) => (value.trim().length > 0 ? null : "Pickup address is required"),
76-
destinationAddress: (value) =>
77-
value.trim().length > 0 ? null : "Destination address is required",
79+
endTime: (value, values) => {
80+
// First check if required
81+
if (value.trim().length === 0) return "Date and time is required";
82+
// Then validate time range
83+
return validateTimeRange(values.startTime, value);
84+
},
85+
purpose: (value) => validateStringLength(value, 1, 500, "Purpose of transport"),
86+
pickupAddress: (value) => validateStringLength(value, 1, 300, "Pickup address"),
87+
destinationAddress: (value) => validateStringLength(value, 1, 300, "Destination address"),
7888
},
7989
});
8090

src/types/validation.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,52 @@ export const passwordSchema = z
88
.regex(/[0-9]/, "Password must contain at least one number");
99

1010
export const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
11+
12+
/**
13+
* Validates a string's length with both minimum and maximum constraints.
14+
* @param value - The string value to validate
15+
* @param minLength - Minimum required length (default: 1)
16+
* @param maxLength - Maximum allowed length
17+
* @param fieldName - Human-readable field name for error messages
18+
* @returns Error message string or null if valid
19+
*/
20+
export const validateStringLength = (
21+
value: string,
22+
minLength: number,
23+
maxLength: number,
24+
fieldName: string,
25+
): string | null => {
26+
const trimmedValue = value.trim();
27+
28+
if (trimmedValue.length < minLength) {
29+
return `${fieldName} is required`;
30+
}
31+
32+
if (trimmedValue.length > maxLength) {
33+
return `${fieldName} cannot exceed ${maxLength} characters`;
34+
}
35+
36+
return null;
37+
};
38+
39+
/**
40+
* Validates that an end time is after a start time.
41+
* @param startTime - ISO date string for start time
42+
* @param endTime - ISO date string for end time
43+
* @returns Error message string or null if valid
44+
*/
45+
export const validateTimeRange = (startTime: string, endTime: string): string | null => {
46+
// Don't validate if either field is empty (let required validation handle that)
47+
if (!startTime || !endTime) {
48+
return null;
49+
}
50+
51+
const start = new Date(startTime);
52+
const end = new Date(endTime);
53+
54+
if (end <= start) {
55+
return "End time must be after start time";
56+
}
57+
58+
return null;
59+
};

0 commit comments

Comments
 (0)