import { z } from "zod"; // Base schemas for validation export const registrationSchema = z.object({ firstName: z .string() .min(1, { message: "Full name is required" }) .min(2, { message: "Full name must be at least 2 characters" }) .max(100, { message: "Full name must be less than 100 characters" }) .regex(/^[a-zA-Z\s]+$/, { message: "Full name can only contain letters and spaces" }), username: z .string() .min(1, { message: "Username is required" }) .min(3, { message: "Username must be at least 3 characters" }) .max(50, { message: "Username must be less than 50 characters" }) .regex(/^[a-zA-Z0-9._-]+$/, { message: "Username can only contain letters, numbers, dots, underscores, and hyphens" }), phoneNumber: z .string() .min(1, { message: "Phone number is required" }) .regex(/^[0-9+\-\s()]+$/, { message: "Please enter a valid phone number" }), email: z .string() .min(1, { message: "Email is required" }) .email({ message: "Please enter a valid email address" }), address: z .string() .min(1, { message: "Address is required" }) .min(10, { message: "Address must be at least 10 characters" }) .max(500, { message: "Address must be less than 500 characters" }), provinsi: z .string() .min(1, { message: "Province is required" }), kota: z .string() .min(1, { message: "City is required" }), kecamatan: z .string() .min(1, { message: "Subdistrict is required" }), password: z .string() .min(1, { message: "Password is required" }) .min(8, { message: "Password must be at least 8 characters" }) .max(100, { message: "Password must be less than 100 characters" }) .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/, { message: "Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character" }), passwordConf: z .string() .min(1, { message: "Password confirmation is required" }), }).refine((data) => data.password === data.passwordConf, { message: "Passwords don't match", path: ["passwordConf"], }); export const journalistRegistrationSchema = z.object({ journalistCertificate: z .string() .min(1, { message: "Journalist certificate number is required" }) .min(5, { message: "Journalist certificate number must be at least 5 characters" }), association: z .string() .min(1, { message: "Association is required" }), email: z .string() .min(1, { message: "Email is required" }) .email({ message: "Please enter a valid email address" }), }); export const personnelRegistrationSchema = z.object({ policeNumber: z .string() .min(1, { message: "Police number is required" }) .min(5, { message: "Police number must be at least 5 characters" }), email: z .string() .min(1, { message: "Email is required" }) .email({ message: "Please enter a valid email address" }), }); export const generalRegistrationSchema = z.object({ email: z .string() .min(1, { message: "Email is required" }) .email({ message: "Please enter a valid email address" }), }); export const instituteSchema = z.object({ name: z .string() .min(1, { message: "Institute name is required" }) .min(2, { message: "Institute name must be at least 2 characters" }), address: z .string() .min(1, { message: "Institute address is required" }) .min(10, { message: "Institute address must be at least 10 characters" }), }); // Inferred types from schemas export type RegistrationFormData = z.infer; export type JournalistRegistrationData = z.infer; export type PersonnelRegistrationData = z.infer; export type GeneralRegistrationData = z.infer; export type InstituteData = z.infer; // API response types export interface RegistrationResponse { data?: { id: string; message: string; }; error?: boolean; message?: string; } export interface OTPRequestResponse { data?: { message: string; }; error?: boolean; message?: string; } export interface OTPVerificationResponse { data?: { message: string; userData?: any; }; error?: boolean; message?: string; } export interface InstituteResponse { data?: { data: InstituteData[]; }; error?: boolean; message?: string; } export interface LocationData { id: number; name: string; provName?: string; cityName?: string; disName?: string; } export interface LocationResponse { data?: { data: LocationData[]; }; error?: boolean; message?: string; } // Registration step types export type RegistrationStep = "identity" | "otp" | "profile"; // User category types export type UserCategory = "6" | "7" | "general"; // 6=Journalist, 7=Personnel, general=Public // Component props types export interface RegistrationLayoutProps { children: React.ReactNode; currentStep: RegistrationStep; totalSteps: number; className?: string; } export interface IdentityFormProps { category: UserCategory; onSuccess: (data: JournalistRegistrationData | PersonnelRegistrationData | GeneralRegistrationData) => void; onError: (error: string) => void; className?: string; } export interface RegistrationOTPFormProps { email: string; category: UserCategory; memberIdentity?: string; onSuccess: (userData: any) => void; onError: (error: string) => void; onResend: () => void; className?: string; } export interface ProfileFormProps { userData: any; category: UserCategory; onSuccess: (data: RegistrationFormData) => void; onError: (error: string) => void; className?: string; } export interface InstituteFormProps { onInstituteChange: (institute: InstituteData | null) => void; className?: string; } export interface LocationSelectorProps { onProvinceChange: (provinceId: string) => void; onCityChange: (cityId: string) => void; onDistrictChange: (districtId: string) => void; selectedProvince?: string; selectedCity?: string; selectedDistrict?: string; className?: string; } // Registration state types export interface RegistrationState { currentStep: RegistrationStep; category: UserCategory; identityData: JournalistRegistrationData | PersonnelRegistrationData | GeneralRegistrationData | null; userData: any; loading: boolean; error: string | null; } export interface RegistrationContextType extends RegistrationState { setStep: (step: RegistrationStep) => void; setIdentityData: (data: JournalistRegistrationData | PersonnelRegistrationData | GeneralRegistrationData) => void; setUserData: (data: any) => void; reset: () => void; } // Association types export interface Association { id: string; name: string; value: string; } // Timer types export interface TimerState { countdown: number; isActive: boolean; isExpired: boolean; } // Password validation types export interface PasswordValidation { isValid: boolean; errors: string[]; strength: 'weak' | 'medium' | 'strong'; }