import { formatCommonCode, type CommonCode } from '@/lib/domain/common-code'; /** * 가맹몰 메뉴 — 백엔드 `TB_COM_VOUCHER_PRODUCT`(`/api/v1/mngr/voc/product`). * 기획(BO-MAL-004)은 「메뉴」, 백엔드는 product라 부른다. 코드는 백엔드를 따르고 화면 문구만 * 「메뉴」다 — 앱 메뉴관리(`system-menu`)와 이름이 겹치지 않게 하려는 뜻이다. */ export type MerchantProduct = { /** 백엔드 `frcsProductSn`. */ id: string; frcsNo: string; name: string; price: number | null; description: string | null; /** 기획 BO-MAL-004 ③ — 선택한 순서대로. */ badges: MerchantProductBadge[]; imageFileId: string | null; /** Repository가 만든 이미지 URL. */ imageUrl: string | null; sortOrder: number | null; isVisible: boolean; }; /** 배지 코드 — 공통코드 `FRCS_BADGE_CD`의 상세코드(예: BEST·MAIN). 기획의 4종은 코드표가 정한다. */ export type MerchantProductBadge = string; /** 기획 BO-MAL-004 ③ [의사결정 필요] 잠정값 — 배지 동시 선택 상한. */ export const MAX_PRODUCT_BADGES = 2; const BADGE_SEPARATOR = ','; /** * 배지 ↔ 백엔드 `frcsBadge`(문자열 하나) — 코드를 쉼표로 잇고 순서를 보존한다. 예) `BEST,MAIN`. * 앱 API도 같은 규칙으로 잘라 `FRCS_BADGE_CD` 이름을 붙인다(백엔드 40f85c4). */ export function parseProductBadges(raw: string | null): MerchantProductBadge[] { if (!raw) { return []; } return raw .split(BADGE_SEPARATOR) .map((token) => token.trim()) .filter((token) => token !== ''); } export function joinProductBadges(badges: readonly MerchantProductBadge[]): string { return badges.join(BADGE_SEPARATOR); } export function formatProductBadgeLabel( codes: readonly CommonCode[], badge: MerchantProductBadge ): string { return formatCommonCode(codes, badge); } export const MERCHANT_PRODUCT_VISIBILITY_OPTIONS = [ { value: 'Y', label: '노출' }, { value: 'N', label: '숨김' }, ] as const; export function formatProductVisibilityLabel(isVisible: boolean): string { return isVisible ? '노출' : '숨김'; } /** 기획 BO-MAL-004 ② — 숫자만 받고 노출 시 세 자리 콤마와 '원'을 붙인다. */ export function formatProductPrice(price: number | null): string { return price === null ? '-' : `${price.toLocaleString('ko-KR')}원`; }