File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
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')}원`;
}