Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 69 additions & 20 deletions apps/web/src/app/maintenance/components/create-edit-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ const maintenanceSchema = z.discriminatedUnion("strategy", [
baseMaintenanceSchema.extend({
strategy: z.literal("single"),
timezone: z.string().optional(),
startDateTime: z.string().optional(),
endDateTime: z.string().optional(),
startDateTime: z.string().min(1, "Start date is required"),
endDateTime: z.string().min(1, "End date is required"),
}),

// Cron expression
Expand All @@ -81,43 +81,92 @@ const maintenanceSchema = z.discriminatedUnion("strategy", [
cron: z.string().optional(),
duration: z.number().optional(),
timezone: z.string().optional(),
startDateTime: z.string().optional(),
endDateTime: z.string().optional(),
startDateTime: z.string().min(1, "Start date is required"),
endDateTime: z.string().min(1, "End date is required"),
}),

// Recurring interval
baseMaintenanceSchema.extend({
strategy: z.literal("recurring-interval"),
intervalDay: z.number().min(1).max(3650).optional(),
startTime: z.string().optional(),
endTime: z.string().optional(),
intervalDay: z.number().min(1).max(3650, "Interval day must be between 1 and 3650"),
startTime: z.string().min(1, "Start time is required"),
endTime: z.string().min(1, "End time is required"),
timezone: z.string().optional(),
startDateTime: z.string().optional(),
endDateTime: z.string().optional(),
startDateTime: z.string().min(1, "Start date is required"),
endDateTime: z.string().min(1, "End date is required"),
}),

// Recurring weekday
baseMaintenanceSchema.extend({
strategy: z.literal("recurring-weekday"),
weekdays: z.array(z.number()).optional(),
startTime: z.string().optional(),
endTime: z.string().optional(),
weekdays: z.array(z.number()).min(1, "At least one weekday must be selected"),
startTime: z.string().min(1, "Start time is required"),
endTime: z.string().min(1, "End time is required"),
timezone: z.string().optional(),
startDateTime: z.string().optional(),
endDateTime: z.string().optional(),
startDateTime: z.string().min(1, "Start date is required"),
endDateTime: z.string().min(1, "End date is required"),
}),

// Recurring day of month
baseMaintenanceSchema.extend({
strategy: z.literal("recurring-day-of-month"),
daysOfMonth: z.array(z.union([z.number(), z.string()])).optional(),
startTime: z.string().optional(),
endTime: z.string().optional(),
daysOfMonth: z.array(z.union([z.number(), z.string()])).min(1, "At least one day must be selected"),
startTime: z.string().min(1, "Start time is required"),
endTime: z.string().min(1, "End time is required"),
timezone: z.string().optional(),
startDateTime: z.string().optional(),
endDateTime: z.string().optional(),
startDateTime: z.string().min(1, "Start date is required"),
endDateTime: z.string().min(1, "End date is required"),
}),
]);
]).superRefine((data, ctx) => {
if (data.strategy === "single" || data.strategy === "cron") {
if (data.startDateTime && data.endDateTime) {
const startDate = new Date(data.startDateTime);
const endDate = new Date(data.endDateTime);
if (startDate >= endDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Start date must be before end date",
path: ["startDateTime"],
});
}
}
}

if (data.strategy === "recurring-interval" ||
data.strategy === "recurring-weekday" ||
data.strategy === "recurring-day-of-month") {

if (data.startTime && data.endTime) {
const [startHour, startMin] = data.startTime.split(':').map(Number);
const [endHour, endMin] = data.endTime.split(':').map(Number);

if (!isNaN(startHour) && !isNaN(startMin) && !isNaN(endHour) && !isNaN(endMin)) {
const startMinutes = startHour * 60 + startMin;
const endMinutes = endHour * 60 + endMin;

if (startMinutes >= endMinutes) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Start time must be before end time",
path: ["startTime"],
});
}
}
}

if (data.startDateTime && data.endDateTime) {
const startDate = new Date(data.startDateTime);
const endDate = new Date(data.endDateTime);
if (startDate >= endDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Start date must be before end date",
path: ["startDateTime"],
});
}
}
}
});

export type MaintenanceFormValues = z.infer<typeof maintenanceSchema>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const StartEndDateTime = () => {
const form = useFormContext();

return (
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-2 gap-4 items-start">
<FormField
control={form.control}
name="startDateTime"
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/maintenance/components/start-end-time.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const StartEndTime = () => {
return (
<div className="space-y-4">
<FormLabel>Maintenance Time Window of a Day</FormLabel>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-2 gap-4 items-start">
<FormField
control={form.control}
name="startTime"
Expand Down
Loading