File name
Commit message
Commit date
File name
Commit message
Commit date
09-03
File name
Commit message
Commit date
export const NAME_MAX_LENGTH = 100;
export const BRAND_MAX_LENGTH = 100;
export const OWNER_MAX_LENGTH = 50;
export const ADDRESS_DETAIL_MAX_LENGTH = 200;
export const MEMO_MAX_LENGTH = 500;
export interface MerchantValues {
id: string;
/** 백엔드에 컬럼이 없어 저장되지 않는다 — 기획 시안 유지를 위해 화면에는 남긴다. */
brandName: string;
memo: string;
name: string;
categoryCode: string;
businessNumber: string;
ownerName: string;
phoneNumber: string;
address: string;
addressDetail: string;
postalCode: string;
latitude: string;
longitude: string;
isVisible: boolean;
}
export type MerchantFormErrors = Partial<
Record<'name' | 'categoryCode' | 'phoneNumber' | 'address' | 'businessNumber', string>
>;
export type MerchantFormState =
| { status: 'idle' }
| { status: 'error'; message?: string; errors?: MerchantFormErrors }
| { status: 'success' };
export const INITIAL_MERCHANT_FORM_STATE: MerchantFormState = { status: 'idle' };
export const REQUIRED_MESSAGE = '필수입력 사항을 입력하세요.';
/** 사업자등록번호는 선택이지만, 넣었다면 형태를 지킨다(기획 예시 `000-00-00000`). */
const BUSINESS_NUMBER_PATTERN = /^\d{3}-?\d{2}-?\d{5}$/;
type ValidationResult =
| { ok: true; values: MerchantValues }
| { ok: false; errors: MerchantFormErrors };
export function validateMerchant(values: MerchantValues): ValidationResult {
const errors: MerchantFormErrors = {};
const name = values.name.trim();
if (!name) {
errors.name = REQUIRED_MESSAGE;
} else if (name.length > NAME_MAX_LENGTH) {
errors.name = `가맹점명은 ${NAME_MAX_LENGTH}자 이내로 입력해 주세요.`;
}
if (!values.categoryCode.trim()) {
errors.categoryCode = REQUIRED_MESSAGE;
}
const phoneNumber = values.phoneNumber.trim();
if (!phoneNumber) {
errors.phoneNumber = REQUIRED_MESSAGE;
} else if (!/^[\d-]+$/.test(phoneNumber)) {
errors.phoneNumber = '전화번호는 숫자와 -만 입력할 수 있습니다.';
}
if (!values.address.trim()) {
errors.address = '주소 검색을 진행해 주세요.';
}
const businessNumber = values.businessNumber.trim();
if (businessNumber && !BUSINESS_NUMBER_PATTERN.test(businessNumber)) {
errors.businessNumber = '사업자등록번호는 000-00-00000 형식으로 입력해 주세요.';
}
if (Object.keys(errors).length > 0) {
return { ok: false, errors };
}
return {
ok: true,
values: {
...values,
name,
brandName: values.brandName.trim().slice(0, BRAND_MAX_LENGTH),
memo: values.memo.trim().slice(0, MEMO_MAX_LENGTH),
ownerName: values.ownerName.trim().slice(0, OWNER_MAX_LENGTH),
phoneNumber,
businessNumber,
address: values.address.trim(),
addressDetail: values.addressDetail.trim().slice(0, ADDRESS_DETAIL_MAX_LENGTH),
},
};
}