MIF_E31221222/sigap-website/utils/validator.ts

143 lines
3.8 KiB
TypeScript

import { z } from "zod";
export class TValidator {
/**
* Validate an empty value
* @param {string} value - The value to validate
* @param {string} fieldName - The name of the field for error message
* @returns {Object} - Validation result object with success and optional error message
*/
static validateEmptyValue(value: string, fieldName: string) {
const schema = z.string().min(1, `${fieldName} cannot be empty`);
const result = schema.safeParse(value);
if (!result.success) {
return {
success: false,
error: `${fieldName} cannot be empty`,
};
}
return {
success: true,
};
}
/**
* Validate an email address
* @param {string} email - The email address to validate
* @returns {Object} - Validation result object with success and optional error message
*/
static validateEmail(email: string) {
const emptyCheck = this.validateEmptyValue(email, "Email");
if (!emptyCheck.success) return emptyCheck;
const schema = z.string().email("Invalid email address");
const result = schema.safeParse(email);
if (!result.success) {
return {
success: false,
error: "Invalid email address",
};
}
return {
success: true,
};
}
/**
* Validate a phone number for Indonesia
* @param {string} phone - The phone number to validate
* @returns {Object} - Validation result object with success and optional error message
*/
static validatePhone(phone: string) {
const emptyCheck = this.validateEmptyValue(phone, "Phone");
if (!emptyCheck.success) return emptyCheck;
// Regex for Indonesian phone numbers:
// - Allows format starting with +62 or 0
// - For +62 format: +62 followed by 8-12 digits
// - For 0 format: 0 followed by 9-12 digits (usually starts with 08)
// - Handles common mobile prefixes (8xx) and landline prefixes
const schema = z
.string()
.regex(
/^(?:\+62[0-9]{8,12}|0[0-9]{9,12})$/,
"Invalid Indonesian phone number format"
);
const result = schema.safeParse(phone);
if (!result.success) {
return {
success: false,
error:
"Invalid Indonesian phone number format. Use format +62xxxxxxxxxx or 08xxxxxxxxx",
};
}
return {
success: true,
};
}
/**
* Validate the contact form
* @param {Object} formData - The form data to validate
* @returns {Object} - Validation result with success flag and errors object
*/
static validateContactForm(formData: {
name: string;
email: string;
phone: string;
typeMessage: string;
message: string;
}) {
const errors: Record<string, string> = {};
let isValid = true;
// Validate name
const nameResult = this.validateEmptyValue(formData.name, "Name");
if (!nameResult.success) {
errors.name = nameResult.error!;
isValid = false;
}
// Validate email
const emailResult = this.validateEmail(formData.email);
if (!emailResult.success) {
errors.email = emailResult.error!;
isValid = false;
}
// Validate phone
const phoneResult = this.validatePhone(formData.phone);
if (!phoneResult.success) {
errors.phone = phoneResult.error!;
isValid = false;
}
// Validate type message
const typeMessageResult = this.validateEmptyValue(
formData.typeMessage,
"Type message"
);
if (!typeMessageResult.success) {
errors.typeMessage = typeMessageResult.error!;
isValid = false;
}
// Validate message
const messageResult = this.validateEmptyValue(formData.message, "Message");
if (!messageResult.success) {
errors.message = messageResult.error!;
isValid = false;
}
return {
success: isValid,
errors: isValid ? {} : errors,
};
}
}