File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
/**
* 가맹몰 메뉴 — 백엔드 `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;
};
export const MERCHANT_PRODUCT_BADGE_OPTIONS = [
{ value: 'BEST', label: 'BEST' },
{ value: 'MAIN', label: '대표' },
{ value: 'NEW', label: '신규' },
{ value: 'SALE', label: '할인' },
] as const;
export type MerchantProductBadge =
(typeof MERCHANT_PRODUCT_BADGE_OPTIONS)[number]['value'];
/** 기획 BO-MAL-004 ③ [의사결정 필요] 잠정값 — 배지 동시 선택 상한. */
export const MAX_PRODUCT_BADGES = 2;
const BADGE_SEPARATOR = ',';
/**
* 배지 ↔ 백엔드 `frcsBadge`(문자열 하나). 앱·백엔드에 규약이 없어 여기서 정한다(사용자 확정):
* 코드를 쉼표로 잇고 순서를 보존한다. 예) `BEST,MAIN`
*/
export function parseProductBadges(raw: string | null): MerchantProductBadge[] {
if (!raw) {
return [];
}
return raw
.split(BADGE_SEPARATOR)
.map((token) => token.trim())
.filter((token): token is MerchantProductBadge =>
MERCHANT_PRODUCT_BADGE_OPTIONS.some((option) => option.value === token)
);
}
export function joinProductBadges(badges: readonly MerchantProductBadge[]): string {
return badges.join(BADGE_SEPARATOR);
}
export function formatProductBadgeLabel(badge: MerchantProductBadge): string {
return (
MERCHANT_PRODUCT_BADGE_OPTIONS.find((option) => option.value === badge)?.label ??
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')}원`;
}