import '../constants/app_constants.dart'; /// 유효성 검사 유틸리티 클래스 class Validators { /// 이메일 유효성 검사 static String? validateEmail(String? value) { if (value == null || value.isEmpty) { return '이메일을 입력해주세요.'; } if (!AppConstants.emailRegex.hasMatch(value)) { return '올바른 이메일 형식이 아닙니다.'; } return null; } /// 비밀번호 유효성 검사 static String? validatePassword(String? value) { if (value == null || value.isEmpty) { return '비밀번호를 입력해주세요.'; } if (value.length < 8) { return '비밀번호는 8자 이상이어야 합니다.'; } if (!value.contains(RegExp(r'[0-9]'))) { return '비밀번호는 숫자를 포함해야 합니다.'; } if (!value.contains(RegExp(r'[a-zA-Z]'))) { return '비밀번호는 영문자를 포함해야 합니다.'; } return null; } /// 필수 입력 검사 static String? validateRequired(String? value, String fieldName) { if (value == null || value.trim().isEmpty) { return '$fieldName을(를) 입력해주세요.'; } return null; } /// 전화번호 유효성 검사 static String? validatePhone(String? value) { if (value == null || value.isEmpty) { return '전화번호를 입력해주세요.'; } final cleanedValue = value.replaceAll('-', ''); if (!AppConstants.phoneRegex.hasMatch(cleanedValue)) { return '올바른 전화번호 형식이 아닙니다.'; } return null; } /// 사업자번호 유효성 검사 static String? validateBusinessNumber(String? value) { if (value == null || value.isEmpty) { return '사업자번호를 입력해주세요.'; } final cleanedValue = value.replaceAll('-', ''); if (!AppConstants.businessNumberRegex.hasMatch(cleanedValue)) { return '올바른 사업자번호 형식이 아닙니다.'; } return null; } /// 숫자 유효성 검사 static String? validateNumber(String? value, { required String fieldName, int? min, int? max, }) { if (value == null || value.isEmpty) { return '$fieldName을(를) 입력해주세요.'; } final number = int.tryParse(value); if (number == null) { return '숫자만 입력 가능합니다.'; } if (min != null && number < min) { return '$fieldName은(는) $min 이상이어야 합니다.'; } if (max != null && number > max) { return '$fieldName은(는) $max 이하여야 합니다.'; } return null; } /// 날짜 범위 유효성 검사 static String? validateDateRange( DateTime? startDate, DateTime? endDate, ) { if (startDate == null || endDate == null) { return null; } if (startDate.isAfter(endDate)) { return '시작일은 종료일보다 이전이어야 합니다.'; } return null; } /// 파일 확장자 유효성 검사 static String? validateFileExtension(String fileName) { final extension = fileName.split('.').last.toLowerCase(); if (!AppConstants.allowedFileExtensions.contains(extension)) { return '허용되지 않는 파일 형식입니다. (${AppConstants.allowedFileExtensions.join(', ')})'; } return null; } /// 파일 크기 유효성 검사 static String? validateFileSize(int sizeInBytes) { if (sizeInBytes > AppConstants.maxFileSize) { final maxSizeMB = AppConstants.maxFileSize / (1024 * 1024); return '파일 크기는 ${maxSizeMB}MB를 초과할 수 없습니다.'; } return null; } /// 시리얼 번호 유효성 검사 static String? validateSerialNumber(String? value) { if (value == null || value.isEmpty) { return null; // 시리얼 번호는 선택사항 } if (value.length < 5) { return '시리얼 번호는 5자 이상이어야 합니다.'; } if (!RegExp(r'^[A-Za-z0-9-]+$').hasMatch(value)) { return '시리얼 번호는 영문, 숫자, 하이픈(-)만 사용 가능합니다.'; } return null; } }