Revert "PHP Rebuild"

This reverts commit 2ef3654841.
This commit is contained in:
Stefan Lazic committed 2026-09-05 09:32:05 +01:00
1 parent a59f998f2b
commit 2aa8405006
690 files changed
+12045 -33943

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
import { z } from "zod";
/**
* Single source of truth for the installation wizard's shape — shared
* between the client wizard component and the final Server Action (see
* actions/install.ts). Deliberately one flat schema, not one per wizard
* step: the wizard itself is client-side-only state (see
* install-wizard.tsx's own header for why) and nothing is validated or
* written server-side until the single final submission, so there is only
* ever one real validation boundary to define.
*/
export const installAdministratorSchema = z
.object({
firstName: z.string().trim().min(1, "First name is required"),
lastName: z.string().trim().min(1, "Last name is required"),
email: z.email("Enter a valid email address"),
phone: z.string().trim().optional().or(z.literal("")),
password: z.string().min(8, "Password must be at least 8 characters"),
confirmPassword: z.string(),
})
.refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"],
});
export const installBusinessSchema = z.object({
name: z.string().trim().min(1, "Business name is required"),
shortName: z.string().trim().max(40).optional().or(z.literal("")),
description: z.string().trim().optional().or(z.literal("")),
email: z.email("Enter a valid email address").optional().or(z.literal("")),
phone: z.string().trim().optional().or(z.literal("")),
website: z.string().trim().optional().or(z.literal("")),
});
export const installLocationSchema = z.object({
addressLine1: z.string().trim().min(1, "Address line 1 is required"),
addressLine2: z.string().trim().optional().or(z.literal("")),
city: z.string().trim().min(1, "Town or city is required"),
region: z.string().trim().optional().or(z.literal("")),
postalCode: z.string().trim().min(1, "Postcode is required"),
country: z.string().trim().min(1, "Country is required"),
timezone: z.string().trim().min(1, "Timezone is required"),
currency: z.string().trim().length(3, "Currency should be a 3-letter code, e.g. GBP"),
locale: z.string().trim().min(1, "Locale is required"),
});
const weekdaySchema = z.enum(["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]);
export const installHoursDaySchema = z.object({
dayOfWeek: weekdaySchema,
isClosed: z.boolean(),
opensAtMinutes: z.number().int().min(0).max(1439).optional(),
closesAtMinutes: z.number().int().min(0).max(1439).optional(),
});
export const installBookingRulesSchema = z.object({
allowGuestBooking: z.boolean(),
minNoticeMinutes: z.number().int().min(0),
maxAdvanceDays: z.number().int().min(1),
cancellationWindowHours: z.number().int().min(0),
rescheduleWindowHours: z.number().int().min(0),
slotIntervalMinutes: z.number().int().min(5).max(120),
bufferBeforeMinutes: z.number().int().min(0),
bufferAfterMinutes: z.number().int().min(0),
maxAppointmentsPerDay: z.number().int().min(1).nullable(),
maxAppointmentsPerStaffPerDay: z.number().int().min(1).nullable(),
customerCanChooseStaff: z.boolean(),
requireApproval: z.boolean(),
});
export const installBrandingSchema = z.object({
logoUrl: z.string().trim().optional().or(z.literal("")),
coverImageUrl: z.string().trim().optional().or(z.literal("")),
themeColor: z.string().trim().optional().or(z.literal("")),
backgroundColor: z.string().trim().optional().or(z.literal("")),
});
const decimalPrice = z.string().regex(/^\d+(\.\d{1,2})?$/, "Enter a price like 22.50");
export const installStarterServiceSchema = z.object({
categoryName: z.string().trim().min(1),
name: z.string().trim().min(1),
description: z.string().trim().optional().or(z.literal("")),
price: decimalPrice,
durationMinutes: z.number().int().min(5).max(480),
active: z.boolean(),
allowOnlineBooking: z.boolean(),
});
export const installSchema = z.object({
installationToken: z.string().min(1, "Installation token is required"),
administrator: installAdministratorSchema,
business: installBusinessSchema,
location: installLocationSchema,
hours: z.array(installHoursDaySchema).length(7),
bookingRules: installBookingRulesSchema,
branding: installBrandingSchema,
starterServices: z.array(installStarterServiceSchema).max(20),
});
export type InstallAdministratorInput = z.infer<typeof installAdministratorSchema>;
export type InstallBusinessInput = z.infer<typeof installBusinessSchema>;
export type InstallLocationInput = z.infer<typeof installLocationSchema>;
export type InstallHoursDayInput = z.infer<typeof installHoursDaySchema>;
export type InstallBookingRulesInput = z.infer<typeof installBookingRulesSchema>;
export type InstallBrandingInput = z.infer<typeof installBrandingSchema>;
export type InstallStarterServiceInput = z.infer<typeof installStarterServiceSchema>;
export type InstallInput = z.infer<typeof installSchema>;