97 lines
3.7 KiB
TypeScript
97 lines
3.7 KiB
TypeScript
/**
|
|
* iFixKart India-specific field validators & input utilities
|
|
* Centralised validation rules for phone, email, pincode, and address fields.
|
|
*/
|
|
|
|
// ─── Regex Patterns ────────────────────────────────────────────────────────────
|
|
/** Exactly 10 digits starting with 6-9 */
|
|
export const PHONE_DIGITS_REGEX = /^[6-9]\d{9}$/;
|
|
/** Accepts formats: 9876543210 | +919876543210 | 09876543210 */
|
|
export const PHONE_FULL_REGEX = /^(?:\+91|0)?[6-9]\d{9}$/;
|
|
/** Standard email address validation */
|
|
export const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
/** Gmail specific validation */
|
|
export const GMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@gmail\.com$/i;
|
|
/** Indian 6-digit pincode starting with 1-9 */
|
|
export const PINCODE_REGEX = /^[1-9]\d{5}$/;
|
|
|
|
// ─── Validators (return error string or null) ──────────────────────────────────
|
|
|
|
export function validatePhone(raw: string, required = false): string | null {
|
|
const stripped = raw.replace(/[\s\-()]/g, '');
|
|
if (!stripped) {
|
|
return required ? 'Phone number is required' : null;
|
|
}
|
|
|
|
// Extract digits
|
|
let digits = stripped;
|
|
if (digits.startsWith('+91')) digits = digits.slice(3);
|
|
else if (digits.startsWith('91') && digits.length === 12) digits = digits.slice(2);
|
|
else if (digits.startsWith('0') && digits.length === 11) digits = digits.slice(1);
|
|
|
|
if (digits.length !== 10) {
|
|
return 'Phone number must be exactly 10 digits';
|
|
}
|
|
if (!/^[6-9]/.test(digits)) {
|
|
return 'Mobile number must start with 6, 7, 8, or 9';
|
|
}
|
|
if (!PHONE_DIGITS_REGEX.test(digits)) {
|
|
return 'Enter a valid 10-digit Indian mobile number';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function validateEmail(raw: string, required = false, gmailOnly = false): string | null {
|
|
const stripped = raw.trim();
|
|
if (!stripped) {
|
|
return required ? 'Email address is required' : null;
|
|
}
|
|
if (gmailOnly && !GMAIL_REGEX.test(stripped)) {
|
|
return 'Please enter a valid Gmail address (e.g. user@gmail.com)';
|
|
}
|
|
if (!EMAIL_REGEX.test(stripped)) {
|
|
return 'Enter a valid email address (e.g. name@example.com)';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function validatePincode(raw: string, required = false): string | null {
|
|
const stripped = raw.trim();
|
|
if (!stripped) {
|
|
return required ? 'PIN code is required' : null;
|
|
}
|
|
if (stripped.length !== 6) {
|
|
return 'PIN code must be exactly 6 digits';
|
|
}
|
|
if (!PINCODE_REGEX.test(stripped)) {
|
|
return 'Enter a valid 6-digit Indian PIN code (cannot start with 0)';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function validateAddress(raw: string, required = false, minLength = 10): string | null {
|
|
const stripped = raw.trim();
|
|
if (!stripped) {
|
|
return required ? 'Address is required' : null;
|
|
}
|
|
if (stripped.length < minLength) {
|
|
return `Address must be at least ${minLength} characters long`;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// ─── Normalizers ──────────────────────────────────────────────────────────────
|
|
|
|
export function normalizePhone(raw: string): string {
|
|
const stripped = raw.replace(/[\s\-().]/g, '');
|
|
if (stripped.startsWith('+91') && stripped.length === 13) return stripped.slice(3);
|
|
if (stripped.startsWith('91') && stripped.length === 12) return stripped.slice(2);
|
|
if (stripped.startsWith('0') && stripped.length === 11) return stripped.slice(1);
|
|
return stripped;
|
|
}
|
|
|
|
export function formatPhoneE164(raw: string): string {
|
|
const digits = normalizePhone(raw);
|
|
if (PHONE_DIGITS_REGEX.test(digits)) return `+91${digits}`;
|
|
return raw;
|
|
}
|