feat: 가맹몰 상세의 기본 정보를 늘 가맹점 값으로 고정하고 [업체 등록]은 비활성으로 둔다
상세가 없는 가맹점도 목록에 서므로 상세 화면은 언제나 행에서 들어온다 — 업체명 선택 상자와 /new 화면, 그 선택지를 만들던 전 페이지 훑기를 지운다. 업체(가맹점)는 BizPlay 미러라 [+ 업체 등록]은 시안 자리만 지키고 비활성이다(사용자 확정). 표의 대표이미지는 인라인 흐름에 두어 셀 가운데에 선다. Co-Authored-By: Claude Opus 5
@b865f0bfded9920a3000452535bf1b5118e3c091
--- app/(protected)/(basic)/system/merchant-details/[frcsNo]/_components/merchant-detail-form.tsx
+++ app/(protected)/(basic)/system/merchant-details/[frcsNo]/_components/merchant-detail-form.tsx
... | ... | @@ -43,32 +43,25 @@ |
| 43 | 43 |
import styles from './merchant-detail-form.module.scss'; |
| 44 | 44 |
|
| 45 | 45 |
interface MerchantDetailFormProps {
|
| 46 |
- /** 상세가 있는 가맹점 — 고친다. */ |
|
| 46 |
+ /** 이 화면의 가맹점 — 업체명·연락처·주소의 출처. 상세 유무와 무관하게 늘 정해져 있다. */ |
|
| 47 |
+ merchant: MerchantDetailSummary; |
|
| 48 |
+ /** 상세가 이미 있으면 그 값. 없으면 이 화면에서 처음 만든다. */ |
|
| 47 | 49 |
detail?: MerchantDetail; |
| 48 |
- /** 상세가 아직 없는데 가맹점은 정해진 경우(행의 [수정]) — 그 가맹점에 처음 만든다. */ |
|
| 49 |
- merchant?: MerchantDetailSummary; |
|
| 50 |
- /** 가맹점도 정해지지 않은 경우([+ 업체 등록]) — 업체명 자리에서 여기서 하나를 고른다. */ |
|
| 51 |
- candidates?: MerchantDetailSummary[]; |
|
| 52 |
- /** 선택지 중 미리 골라 둘 가맹점(`?frcsNo=`). */ |
|
| 53 |
- initialFrcsNo?: string; |
|
| 54 | 50 |
products?: MerchantProduct[]; |
| 55 | 51 |
categories: CommonCode[]; |
| 56 | 52 |
} |
| 57 | 53 |
|
| 58 | 54 |
/** |
| 59 |
- * 가맹몰 상세 — 기획 BO-MAL-002(등록)·003(수정)을 한 화면으로 합쳤다(사용자 확정). `detail`이 |
|
| 60 |
- * 있으면 상세가 이미 있는 가맹점, `merchant`면 상세가 없는 정해진 가맹점, 둘 다 없으면 업체명 |
|
| 61 |
- * 자리에서 가맹점을 고른다. 처음 저장하면 그 가맹점 주소로 옮겨 가되 화면 구성은 그대로라 바로 |
|
| 62 |
- * 메뉴를 붙일 수 있고, 이후 저장은 그 자리에 머문다. |
|
| 55 |
+ * 가맹몰 상세 — 기획 BO-MAL-002(등록)·003(수정)을 한 화면으로 합쳤다(사용자 확정). 목록의 행에서 |
|
| 56 |
+ * 들어오며 `detail`이 있으면 고치고, 없으면 처음 만든다. 첫 저장 뒤에도 화면 구성은 그대로라 |
|
| 57 |
+ * 바로 메뉴를 붙일 수 있고, 저장은 그 자리에 머문다. |
|
| 63 | 58 |
* |
| 64 |
- * 업체명·연락처·우편번호·주소는 가맹점 원본이라 읽기 전용이고, 기획의 [주소 검색]은 가맹점 관리 |
|
| 65 |
- * 화면의 것이라 여기서는 값을 바꾸지 않는다. |
|
| 59 |
+ * 업체명·연락처·우편번호·주소는 가맹점 원본이라 늘 읽기 전용이다(사용자 확정). 기획의 [주소 검색]은 |
|
| 60 |
+ * 가맹점 관리 화면의 것이라 여기서는 값을 바꾸지 않는다. |
|
| 66 | 61 |
*/ |
| 67 | 62 |
export function MerchantDetailForm({
|
| 63 |
+ merchant, |
|
| 68 | 64 |
detail, |
| 69 |
- merchant: fixedMerchant, |
|
| 70 |
- candidates = [], |
|
| 71 |
- initialFrcsNo, |
|
| 72 | 65 |
products = [], |
| 73 | 66 |
categories, |
| 74 | 67 |
}: MerchantDetailFormProps) {
|
... | ... | @@ -82,11 +75,7 @@ |
| 82 | 75 |
const isEdit = detail !== undefined; |
| 83 | 76 |
const errors = state.status === 'error' ? (state.errors ?? {}) : {};
|
| 84 | 77 |
|
| 85 |
- // 가맹점이 정해져 있으면(상세가 있든 없든) 업체명은 읽기 전용이고, 아니면 여기서 고른다. |
|
| 86 |
- const pinned: MerchantDetailSummary | null = detail ?? fixedMerchant ?? null; |
|
| 87 |
- const [frcsNo, setFrcsNo] = useState(pinned?.id ?? initialFrcsNo ?? ''); |
|
| 88 |
- const merchant: MerchantDetailSummary | null = |
|
| 89 |
- pinned ?? candidates.find((row) => row.id === frcsNo) ?? null; |
|
| 78 |
+ const frcsNo = merchant.id; |
|
| 90 | 79 |
const [categoryCode, setCategoryCode] = useState(detail?.categoryCode ?? ''); |
| 91 | 80 |
const [visibility, setVisibility] = useState<string[]>([ |
| 92 | 81 |
detail?.isVisible === false ? 'N' : 'Y', |
... | ... | @@ -170,29 +159,7 @@ |
| 170 | 159 |
<FoxCard size="lg" title="기본 정보" className={styles.section}>
|
| 171 | 160 |
<div className={styles.grid}>
|
| 172 | 161 |
<div className={styles.fieldWide}>
|
| 173 |
- {pinned ? (
|
|
| 174 |
- <FoxInput size="md" label="업체명" requirement="required" value={pinned.name} readOnly state="view" />
|
|
| 175 |
- ) : ( |
|
| 176 |
- <> |
|
| 177 |
- <FoxSelect |
|
| 178 |
- size="md" |
|
| 179 |
- label="업체명" |
|
| 180 |
- requirement="required" |
|
| 181 |
- placeholder="상세를 등록할 가맹점 선택" |
|
| 182 |
- options={candidates.map((row) => ({ value: row.id, label: row.name }))}
|
|
| 183 |
- value={frcsNo}
|
|
| 184 |
- onValueChange={setFrcsNo}
|
|
| 185 |
- error={Boolean(errors.frcsNo)}
|
|
| 186 |
- /> |
|
| 187 |
- {errors.frcsNo && <FoxHelperText type="danger" message={errors.frcsNo} />}
|
|
| 188 |
- {candidates.length === 0 && (
|
|
| 189 |
- <FoxHelperText |
|
| 190 |
- type="information" |
|
| 191 |
- message="상세를 붙일 가맹점이 없습니다. 가맹점 관리에서 먼저 등록해 주세요." |
|
| 192 |
- /> |
|
| 193 |
- )} |
|
| 194 |
- </> |
|
| 195 |
- )} |
|
| 162 |
+ <FoxInput size="md" label="업체명" requirement="required" value={merchant.name} readOnly state="view" />
|
|
| 196 | 163 |
</div> |
| 197 | 164 |
<div className={styles.field}>
|
| 198 | 165 |
<FoxSelect |
... | ... | @@ -213,7 +180,7 @@ |
| 213 | 180 |
size="md" |
| 214 | 181 |
label="업체 연락처" |
| 215 | 182 |
requirement="required" |
| 216 |
- value={formatOptionalValue(formatPhoneNumber(merchant?.phoneNumber ?? null))}
|
|
| 183 |
+ value={formatOptionalValue(formatPhoneNumber(merchant.phoneNumber))}
|
|
| 217 | 184 |
readOnly |
| 218 | 185 |
state="view" |
| 219 | 186 |
/> |
... | ... | @@ -225,10 +192,10 @@ |
| 225 | 192 |
<FoxInput size="md" label="우편번호" requirement="required" value={formatOptionalValue(detail?.postalCode)} readOnly state="view" />
|
| 226 | 193 |
</div> |
| 227 | 194 |
<div className={styles.fieldWide}>
|
| 228 |
- <FoxInput size="md" label="주소" value={formatOptionalValue(merchant?.address)} readOnly state="view" />
|
|
| 195 |
+ <FoxInput size="md" label="주소" value={formatOptionalValue(merchant.address)} readOnly state="view" />
|
|
| 229 | 196 |
</div> |
| 230 | 197 |
<div className={styles.field}>
|
| 231 |
- <FoxInput size="md" label="상세주소" value={formatOptionalValue(merchant?.addressDetail)} readOnly state="view" />
|
|
| 198 |
+ <FoxInput size="md" label="상세주소" value={formatOptionalValue(merchant.addressDetail)} readOnly state="view" />
|
|
| 232 | 199 |
</div> |
| 233 | 200 |
</div> |
| 234 | 201 |
|
--- app/(protected)/(basic)/system/merchant-details/[frcsNo]/page.tsx
+++ app/(protected)/(basic)/system/merchant-details/[frcsNo]/page.tsx
... | ... | @@ -30,8 +30,12 @@ |
| 30 | 30 |
fetchCommonCodes(CODE_GROUP.merchantType), |
| 31 | 31 |
]); |
| 32 | 32 |
|
| 33 |
- if (!detail.hasDetail) {
|
|
| 34 |
- return <MerchantDetailForm merchant={detail} categories={categories} />;
|
|
| 35 |
- } |
|
| 36 |
- return <MerchantDetailForm detail={detail} products={products} categories={categories} />;
|
|
| 33 |
+ return ( |
|
| 34 |
+ <MerchantDetailForm |
|
| 35 |
+ merchant={detail}
|
|
| 36 |
+ detail={detail.hasDetail ? detail : undefined}
|
|
| 37 |
+ products={products}
|
|
| 38 |
+ categories={categories}
|
|
| 39 |
+ /> |
|
| 40 |
+ ); |
|
| 37 | 41 |
} |
--- app/(protected)/(basic)/system/merchant-details/_actions.ts
+++ app/(protected)/(basic)/system/merchant-details/_actions.ts
... | ... | @@ -222,7 +222,7 @@ |
| 222 | 222 |
const frcsNo = readString(formData, 'frcsNo'); |
| 223 | 223 |
const isEdit = readString(formData, 'mode') === 'edit'; |
| 224 | 224 |
if (!frcsNo) {
|
| 225 |
- return { status: 'error', errors: { frcsNo: '업체를 선택해 주세요.' } };
|
|
| 225 |
+ return { status: 'error', message: INVALID_REQUEST_MESSAGE };
|
|
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 | 228 |
let failed: MerchantDetailFormState | null = null; |
--- app/(protected)/(basic)/system/merchant-details/_components/merchant-detail-list.tsx
+++ app/(protected)/(basic)/system/merchant-details/_components/merchant-detail-list.tsx
... | ... | @@ -26,7 +26,6 @@ |
| 26 | 26 |
import {
|
| 27 | 27 |
FILTER_ALL, |
| 28 | 28 |
MERCHANT_DETAILS_PATH, |
| 29 |
- MERCHANT_DETAIL_NEW_PATH, |
|
| 30 | 29 |
MERCHANT_DETAIL_PAGE_SIZE_OPTIONS, |
| 31 | 30 |
buildMerchantDetailHref, |
| 32 | 31 |
clampDateRange, |
... | ... | @@ -56,9 +55,9 @@ |
| 56 | 55 |
/** |
| 57 | 56 |
* 가맹몰 상세 목록 — 기획 BO-MAL-001을 「관리자관리 > 가맹몰 상세 관리」로 옮긴 것. |
| 58 | 57 |
* |
| 59 |
- * 가맹점 전체가 서고 상세가 없는 건은 상태·등록일이 `-`다(사용자 확정). [+ 업체 등록]은 상세 |
|
| 60 |
- * 화면에서 가맹점을 고르게 하고, 행의 [수정]은 그 가맹점의 상세 화면으로 간다 — 상세가 없으면 |
|
| 61 |
- * 거기서 처음 만든다. |
|
| 58 |
+ * 가맹점 전체가 서고 상세가 없는 건은 상태·등록일이 `-`다(사용자 확정). 행의 [수정]은 그 가맹점의 |
|
| 59 |
+ * 상세 화면으로 간다 — 상세가 없으면 거기서 처음 만든다. 업체(가맹점) 자체는 BizPlay 쪽에서 오므로 |
|
| 60 |
+ * [+ 업체 등록]은 시안 자리만 지키고 비활성이다(사용자 확정). |
|
| 62 | 61 |
* |
| 63 | 62 |
* 이슈: 메뉴 건수 열은 목록 응답에 없어 `-`다(보고함). 카테고리·상태도 백엔드가 아직 주지 |
| 64 | 63 |
* 않아 대부분 `-`로 보인다. |
... | ... | @@ -372,7 +371,7 @@ |
| 372 | 371 |
size="md" |
| 373 | 372 |
leadingIcon={<i className="fox-ico fox-ico-Plus" aria-hidden="true" />}
|
| 374 | 373 |
label="업체 등록" |
| 375 |
- onAction={() => router.push(MERCHANT_DETAIL_NEW_PATH)}
|
|
| 374 |
+ disabled |
|
| 376 | 375 |
/> |
| 377 | 376 |
</> |
| 378 | 377 |
} |
--- app/(protected)/(basic)/system/merchant-details/_components/merchant-thumbnail.module.scss
+++ app/(protected)/(basic)/system/merchant-details/_components/merchant-thumbnail.module.scss
... | ... | @@ -3,17 +3,19 @@ |
| 3 | 3 |
// 기획 BO-MAL-001·002의 56×40 썸네일 틀을 1.5배 → 다시 1.2배(약 101×72)로 키웠다(사용자 |
| 4 | 4 |
// 확정 — 시스템에 썸네일 크기 토큰이 없어 와이어프레임 값이 기준이었다). 토큰 스케일 밖이라 |
| 5 | 5 |
// 리터럴로 두고 근거를 남긴다(꾸미기아이템 썸네일과 같은 처리). |
| 6 |
+// 둘 다 인라인 흐름에 둔다 — 표 셀의 text-align: center가 그대로 먹어 가운데 선다. |
|
| 6 | 7 |
.image, |
| 7 | 8 |
.placeholder {
|
| 8 | 9 |
box-sizing: border-box; |
| 9 | 10 |
inline-size: 10.08rem; |
| 10 | 11 |
block-size: 7.2rem; |
| 12 |
+ vertical-align: middle; |
|
| 11 | 13 |
border: fox.border(1) solid fox.color(border-neutral-subtler); |
| 12 | 14 |
border-radius: fox.radius(4); |
| 13 | 15 |
} |
| 14 | 16 |
|
| 15 | 17 |
.image {
|
| 16 |
- display: block; |
|
| 18 |
+ display: inline-block; |
|
| 17 | 19 |
object-fit: cover; |
| 18 | 20 |
} |
| 19 | 21 |
|
--- app/(protected)/(basic)/system/merchant-details/new/page.tsx
... | ... | @@ -1,34 +0,0 @@ |
| 1 | -import type { Metadata } from 'next'; | |
| 2 | -import { verifySession } from '@/lib/auth/dal'; | |
| 3 | -import { fetchCommonCodes } from '@/lib/data/repositories/common-code-repository'; | |
| 4 | -import { fetchMerchantDetailCandidates } from '@/lib/data/repositories/merchant-detail-repository'; | |
| 5 | -import { CODE_GROUP } from '@/lib/domain/common-code'; | |
| 6 | -import { MerchantDetailForm } from '../[frcsNo]/_components/merchant-detail-form'; | |
| 7 | - | |
| 8 | -export const metadata: Metadata = { title: '가맹몰 상세 정보' }; | |
| 9 | -export const dynamic = 'force-dynamic'; | |
| 10 | - | |
| 11 | -interface PageProps { | |
| 12 | - searchParams: Promise<Record<string, string | string[] | undefined>>; | |
| 13 | -} | |
| 14 | - | |
| 15 | -/** 등록 화면 — 상세가 없는 가맹점 중 하나를 골라 상세를 붙인다. `?frcsNo=`로 미리 고를 수 있다. */ | |
| 16 | -export default async function Page({ searchParams }: PageProps) { | |
| 17 | - await verifySession(); | |
| 18 | - | |
| 19 | - const params = await searchParams; | |
| 20 | - const requested = Array.isArray(params.frcsNo) ? params.frcsNo[0] : params.frcsNo; | |
| 21 | - const [candidates, categories] = await Promise.all([ | |
| 22 | - fetchMerchantDetailCandidates(), | |
| 23 | - fetchCommonCodes(CODE_GROUP.merchantType), | |
| 24 | - ]); | |
| 25 | - const initialFrcsNo = candidates.some((row) => row.id === requested) ? requested : undefined; | |
| 26 | - | |
| 27 | - return ( | |
| 28 | - <MerchantDetailForm | |
| 29 | - candidates={candidates} | |
| 30 | - initialFrcsNo={initialFrcsNo} | |
| 31 | - categories={categories} | |
| 32 | - /> | |
| 33 | - ); | |
| 34 | -} |
--- lib/data/repositories/merchant-detail-repository.ts
+++ lib/data/repositories/merchant-detail-repository.ts
... | ... | @@ -147,28 +147,21 @@ |
| 147 | 147 |
}; |
| 148 | 148 |
} |
| 149 | 149 |
|
| 150 |
-type SummaryFilters = Pick< |
|
| 151 |
- MerchantDetailQuery, |
|
| 152 |
- 'keyword' | 'category' | 'visibility' | 'startDate' | 'endDate' |
|
| 153 |
->; |
|
| 154 |
- |
|
| 155 |
-async function fetchSummaryPage( |
|
| 156 |
- filters: Partial<SummaryFilters>, |
|
| 157 |
- pageIndex: number, |
|
| 158 |
- pageSize: number |
|
| 159 |
-): Promise<{ items: MerchantDetailSummary[]; rowCount: number; totalCount: number }> {
|
|
| 150 |
+export async function fetchMerchantDetails( |
|
| 151 |
+ query: MerchantDetailQuery |
|
| 152 |
+): Promise<{ items: MerchantDetailSummary[]; totalCount: number }> {
|
|
| 160 | 153 |
const accessToken = await getSessionAccessToken(); |
| 161 | 154 |
|
| 162 | 155 |
const result = await backendFetch<unknown>(`${DETAIL_PATH}/pagination`, {
|
| 163 | 156 |
method: 'GET', |
| 164 | 157 |
query: {
|
| 165 |
- ...(filters.keyword ? { searchFrcsNm: filters.keyword } : {}),
|
|
| 166 |
- ...(filters.category ? { searchFrcsTypeCd: filters.category } : {}),
|
|
| 167 |
- ...(filters.visibility ? { searchUseYn: filters.visibility } : {}),
|
|
| 168 |
- ...(filters.startDate ? { searchStartDt: filters.startDate } : {}),
|
|
| 169 |
- ...(filters.endDate ? { searchEndDt: filters.endDate } : {}),
|
|
| 170 |
- pageIndex, |
|
| 171 |
- recordCountPerPage: pageSize, |
|
| 158 |
+ ...(query.keyword ? { searchFrcsNm: query.keyword } : {}),
|
|
| 159 |
+ ...(query.category ? { searchFrcsTypeCd: query.category } : {}),
|
|
| 160 |
+ ...(query.visibility ? { searchUseYn: query.visibility } : {}),
|
|
| 161 |
+ ...(query.startDate ? { searchStartDt: query.startDate } : {}),
|
|
| 162 |
+ ...(query.endDate ? { searchEndDt: query.endDate } : {}),
|
|
| 163 |
+ pageIndex: query.page, |
|
| 164 |
+ recordCountPerPage: query.pageSize, |
|
| 172 | 165 |
}, |
| 173 | 166 |
accessToken: accessToken ?? undefined, |
| 174 | 167 |
cache: 'no-store', |
... | ... | @@ -181,7 +174,7 @@ |
| 181 | 174 |
|
| 182 | 175 |
const data = result.data; |
| 183 | 176 |
if (data === null || data === undefined) {
|
| 184 |
- return { items: [], rowCount: 0, totalCount: 0 };
|
|
| 177 |
+ return { items: [], totalCount: 0 };
|
|
| 185 | 178 |
} |
| 186 | 179 |
if (!isRecord(data) || !Array.isArray(data.list)) {
|
| 187 | 180 |
throw new Error('가맹몰 상세 목록 응답의 형식이 올바르지 않습니다.');
|
... | ... | @@ -189,46 +182,9 @@ |
| 189 | 182 |
|
| 190 | 183 |
return {
|
| 191 | 184 |
items: data.list.flatMap(toSummary), |
| 192 |
- // 매핑에서 걸러진 행이 있어도 페이지가 끝났는지는 원본 행 수로 판단한다. |
|
| 193 |
- rowCount: data.list.length, |
|
| 194 | 185 |
totalCount: |
| 195 | 186 |
typeof data.totalCount === 'number' ? data.totalCount : data.list.length, |
| 196 | 187 |
}; |
| 197 |
-} |
|
| 198 |
- |
|
| 199 |
-// 등록 화면의 선택지("상세가 없는 가맹점")를 백엔드가 걸러 주지 않아 전 페이지를 받아 거른다 —
|
|
| 200 |
-// 가맹점은 많아야 수백 건이라 한두 번의 요청이다. 상한을 넘으면 그 뒤는 잘린다. |
|
| 201 |
-// TODO(백엔드): 상세 유무 조건이 생기면 이 훑기를 없애고 페이지 하나만 받는다. |
|
| 202 |
-const SCAN_PAGE_SIZE = 200; |
|
| 203 |
-const MAX_SCAN_PAGES = 25; |
|
| 204 |
- |
|
| 205 |
-async function fetchAllSummaries( |
|
| 206 |
- filters: Partial<SummaryFilters> |
|
| 207 |
-): Promise<MerchantDetailSummary[]> {
|
|
| 208 |
- const items: MerchantDetailSummary[] = []; |
|
| 209 |
- let seen = 0; |
|
| 210 |
- for (let pageIndex = 1; pageIndex <= MAX_SCAN_PAGES; pageIndex += 1) {
|
|
| 211 |
- const page = await fetchSummaryPage(filters, pageIndex, SCAN_PAGE_SIZE); |
|
| 212 |
- items.push(...page.items); |
|
| 213 |
- seen += page.rowCount; |
|
| 214 |
- if (page.rowCount < SCAN_PAGE_SIZE || seen >= page.totalCount) {
|
|
| 215 |
- break; |
|
| 216 |
- } |
|
| 217 |
- } |
|
| 218 |
- return items; |
|
| 219 |
-} |
|
| 220 |
- |
|
| 221 |
-/** 목록 — 가맹점 전체가 오며 상세가 없는 건도 그대로 선다(사용자 확정). */ |
|
| 222 |
-export async function fetchMerchantDetails( |
|
| 223 |
- query: MerchantDetailQuery |
|
| 224 |
-): Promise<{ items: MerchantDetailSummary[]; totalCount: number }> {
|
|
| 225 |
- const { items, totalCount } = await fetchSummaryPage(query, query.page, query.pageSize);
|
|
| 226 |
- return { items, totalCount };
|
|
| 227 |
-} |
|
| 228 |
- |
|
| 229 |
-/** 등록 화면의 업체 선택지 — 아직 상세가 없는 가맹점 전부. */ |
|
| 230 |
-export async function fetchMerchantDetailCandidates(): Promise<MerchantDetailSummary[]> {
|
|
| 231 |
- return (await fetchAllSummaries({})).filter((row) => !row.hasDetail);
|
|
| 232 | 188 |
} |
| 233 | 189 |
|
| 234 | 190 |
export async function fetchMerchantDetail( |
--- lib/domain/merchant-detail-form.ts
+++ lib/domain/merchant-detail-form.ts
... | ... | @@ -29,7 +29,6 @@ |
| 29 | 29 |
|
| 30 | 30 |
export type MerchantDetailFormErrors = Partial< |
| 31 | 31 |
Record< |
| 32 |
- | 'frcsNo' |
|
| 33 | 32 |
| 'categoryCode' |
| 34 | 33 |
| 'description' |
| 35 | 34 |
| 'openTime' |
--- lib/domain/merchant-detail-query.ts
+++ lib/domain/merchant-detail-query.ts
... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 |
import { MERCHANT_DETAIL_VISIBILITY_OPTIONS } from '@/lib/domain/merchant-detail';
|
| 2 | 2 |
|
| 3 | 3 |
export const MERCHANT_DETAILS_PATH = '/system/merchant-details'; |
| 4 |
-export const MERCHANT_DETAIL_NEW_PATH = `${MERCHANT_DETAILS_PATH}/new`;
|
|
| 5 | 4 |
|
| 6 | 5 |
export function merchantDetailPath(frcsNo: string): string {
|
| 7 | 6 |
return `${MERCHANT_DETAILS_PATH}/${encodeURIComponent(frcsNo)}`;
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?