Skip to content

[Feat/#76] 주문/계좌이체 페이지 생성#77

Merged
skyblue1232 merged 5 commits intodevelopfrom
feat/#76/random-box-payment
Mar 29, 2026
Merged

[Feat/#76] 주문/계좌이체 페이지 생성#77
skyblue1232 merged 5 commits intodevelopfrom
feat/#76/random-box-payment

Conversation

@skyblue1232
Copy link
Copy Markdown
Contributor

@skyblue1232 skyblue1232 commented Mar 29, 2026

✅ 작업 내용

📝 Description

랜덤박스 구매 흐름 전반(구매 → 결제 안내 → 결제 완료) UI 및 상태 흐름 구현

작업한 내용을 체크해주세요.

  • 구매 페이지 상품 카드/수량 선택 UI 구현
  • 결제 정보 섹션 및 안내 카드 UI 구현
  • 카카오 계좌이체 안내 모달 구현
  • 결제 완료 풀스크린 모달 구현
  • 모달 간 상태 흐름 연결 (안내 → 완료)
  • 완료 후 /main 라우팅 처리
  • 완료 모달 내부 스크롤 대응 (작은 화면 대응)

🚀 설계 의도 및 개선점

  • 구매/결제/완료를 모달 기반 단계 흐름으로 구성하여 페이지 이동 최소화
  • UI 역할별로 컴포넌트 분리 (OrderCard, Info, Notice, Modal 등)
  • 상태를 부모에서 관리하여 모달 간 전환 흐름 명확화
  • 완료 모달은 h-screen + overflow 구조로 반응형 대응

📸 스크린샷 (선택)

  • 구매 페이지 / 결제 안내 모달 / 결제 완료 화면
image image image

📎 기타 참고사항

  • 실제 결제 연동 없이 UI 흐름 기준으로 처리

Fixes #76

Summary by CodeRabbit

출시 노트

  • New Features

    • 메뉴 항목을 클릭하여 구매 페이지로 이동 가능
    • 주문 수량 선택 및 결제 정보 입력 화면 추가
    • 결제 가이드 및 주문 완료 모달 추가
  • Chores

    • 목록 화면의 하단 여백 조정
    • 주문 데이터 업데이트

@skyblue1232 skyblue1232 self-assigned this Mar 29, 2026
@skyblue1232 skyblue1232 added feat 기능 구현 및 생성 style 스타일 관련 적용 labels Mar 29, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
compasser-customer Ready Ready Preview, Comment Mar 29, 2026 7:56pm
compasser-owner Ready Ready Preview, Comment Mar 29, 2026 7:56pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

메뉴 선택부터 결제 완료까지의 구매 흐름을 구현합니다. 스토어 상세 페이지의 메뉴 클릭을 통해 새로운 구매 페이지로 라우팅하며, 구매 수량 선택, 결제 가이드 확인, 완료 모달 표시를 포함한 여러 컴포넌트를 추가합니다.

Changes

Cohort / File(s) Summary
구매 흐름 컴포넌트
apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx, PurchaseOrderCard.tsx, PurchaseGuideModal.tsx, PurchaseCompleteModal.tsx, PurchaseInfoSection.tsx, PurchaseNoticeCard.tsx
구매 과정의 UI 상태 관리 및 모달 표시를 담당하는 새 컴포넌트들. 수량 조절, 가격 계산, 결제 가이드 및 완료 모달의 조건부 렌더링 포함.
구매 페이지
apps/customer/src/app/(tabs)/main/store/[id]/purchase/page.tsx
서버 컴포넌트로서 store ID와 menu ID를 파라미터에서 해석하고, 유효성 검사 후 PurchaseContent를 렌더링하는 새 구매 페이지.
스토어 상세 네비게이션
apps/customer/src/app/(tabs)/main/store/_components/StoreDetailContent.tsx, StoreMenuCard.tsx
메뉴 클릭 핸들러 추가 및 구매 페이지로의 라우팅. StoreMenuCardonClick props 추가하고 button 래핑으로 인터랙티브하게 변경.
모의 데이터 업데이트
apps/customer/src/app/(tabs)/order/_constants/mockOrders.ts
진행 중인 주문에 새 항목(ID 3, 4) 추가 및 완료 주문의 ID 변경(3 → 5).
레이아웃 패딩 조정
apps/customer/src/app/(tabs)/main/_components/MainListView.tsx, apps/customer/src/app/(tabs)/order/page.tsx
메인 리스트 뷰와 주문 페이지의 하단 패딩을 pb-[2rem] 또는 pb-[3.2rem]에서 pb-[9.6rem]으로 증가.

Sequence Diagram

sequenceDiagram
    actor User as 사용자
    participant StoreDetail as 스토어 상세<br/>(StoreDetailContent)
    participant Router as 라우터
    participant Purchase as 구매 페이지<br/>(PurchasePage)
    participant PurchaseContent as 구매 UI<br/>(PurchaseContent)
    participant GuideModal as 결제 가이드<br/>(PurchaseGuideModal)
    participant CompleteModal as 완료 모달<br/>(PurchaseCompleteModal)

    User->>StoreDetail: 메뉴 클릭
    StoreDetail->>Router: navigate to /main/store/{id}/purchase?menuId={id}
    Router->>Purchase: params와 searchParams 전달
    Purchase->>Purchase: store 및 menu 조회 및 검증
    Purchase->>PurchaseContent: store, menu props 전달
    PurchaseContent->>PurchaseContent: count 상태 초기화
    User->>PurchaseContent: 수량 증감
    PurchaseContent->>PurchaseContent: count, totalPrice 업데이트
    User->>PurchaseContent: "결제하기" 버튼 클릭
    PurchaseContent->>GuideModal: isOpen = true
    GuideModal->>User: 결제 가이드 모달 표시
    User->>GuideModal: "결제하기" 확인
    GuideModal->>PurchaseContent: onConfirm 콜백
    PurchaseContent->>GuideModal: isOpen = false
    PurchaseContent->>CompleteModal: isOpen = true
    CompleteModal->>User: 주문 완료 모달 표시
    User->>CompleteModal: "확인" 버튼 클릭
    CompleteModal->>Router: navigate to /main
    Router->>User: 메인 화면으로 이동
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Poem

🐰 메뉴 탭 하나면 구매 페이지로,
수량 조절하고 가이드 확인하고,
완료 모달 떴을 땐 쌩 기분 좋아,
주문 완료! 홉홉홉 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 변경 사항의 핵심을 명확하게 반영하고 있습니다. '주문/계좌이체 페이지 생성'은 실제로 구매 페이지, 결제 안내 모달, 결제 완료 모달 등 결제 관련 UI 및 상태 흐름 구현을 정확하게 설명합니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#76/random-box-payment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
apps/customer/src/app/(tabs)/order/_constants/mockOrders.ts (1)

18-31: 중복 mock 객체는 생성 패턴으로 줄이는 것을 권장합니다.

Line 18-31은 동일 필드 반복이라, 추후 필드 변경 시 누락 위험이 있습니다. 동작 이슈는 아니므로 선택적으로 정리해두면 유지보수가 쉬워집니다.

중복 제거 예시
+const IN_PROGRESS_ORDER_TEMPLATE: Omit<OrderItem, "id"> = {
+  storeName: "별동네 베이커리카페 별내본점",
+  orderSummary: "랜덤박스 Level.1 3개",
+  totalPrice: "15,000원",
+  pickupTime: "2/27 19:00 ~ 20:00",
+};
+
-export const IN_PROGRESS_ORDERS: OrderItem[] = [
-  { id: 1, storeName: "별동네 베이커리카페 별내본점", orderSummary: "랜덤박스 Level.1 3개", totalPrice: "15,000원", pickupTime: "2/27 19:00 ~ 20:00" },
-  { id: 2, storeName: "별동네 베이커리카페 별내본점", orderSummary: "랜덤박스 Level.1 3개", totalPrice: "15,000원", pickupTime: "2/27 19:00 ~ 20:00" },
-  { id: 3, storeName: "별동네 베이커리카페 별내본점", orderSummary: "랜덤박스 Level.1 3개", totalPrice: "15,000원", pickupTime: "2/27 19:00 ~ 20:00" },
-  { id: 4, storeName: "별동네 베이커리카페 별내본점", orderSummary: "랜덤박스 Level.1 3개", totalPrice: "15,000원", pickupTime: "2/27 19:00 ~ 20:00" },
-];
+export const IN_PROGRESS_ORDERS: OrderItem[] = [1, 2, 3, 4].map((id) => ({
+  id,
+  ...IN_PROGRESS_ORDER_TEMPLATE,
+}));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/customer/src/app/`(tabs)/order/_constants/mockOrders.ts around lines 18
- 31, Several mock order objects in MOCK_ORDERS are duplicated; create a small
factory to generate orders and replace repeated literal objects to reduce
duplication and future bugs: add a helper function (e.g., makeMockOrder or
createMockOrder) that accepts an overrides object and returns the common shape
(id, storeName, orderSummary, totalPrice, pickupTime), then use it to produce
the entries in the MOCK_ORDERS array (calling makeMockOrder({ id: 3, ... }) and
makeMockOrder({ id: 4, ... })) so only differing fields need to be specified
while shared fields live in one place.
apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseOrderCard.tsx (1)

57-62: 감소 버튼도 하한선(0)에서 비활성화해 방어적으로 처리하는 게 좋습니다.

증가 버튼은 상한을 막고 있으므로, 감소 버튼도 count <= 0에서 비활성화하면 상태 안정성이 맞춰집니다.

수정 제안
                 <button
                   type="button"
                   onClick={onDecrease}
                   className="flex h-[2.8rem] w-[2.8rem] items-center justify-center"
                   aria-label="수량 감소"
+                  disabled={count <= 0}
                 >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseOrderCard.tsx
around lines 57 - 62, In PurchaseOrderCard, disable the decrease button when
count <= 0 to match the upper-bound guard: update the decrease button element
that uses onDecrease so it sets disabled={count <= 0} (and/or aria-disabled) and
ensure the onDecrease handler short-circuits if count <= 0 to avoid
side-effects; reference the decrease button element, the onDecrease handler and
the count prop/state in PurchaseOrderCard when making the change.
apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseGuideModal.tsx (1)

21-23: 모달에 dialog 접근성 속성을 추가하는 것을 권장합니다.

스크린리더 문맥 인지를 위해 role="dialog", aria-modal, aria-labelledby를 명시하면 더 안전합니다.

수정 제안
-    <div className="fixed inset-0 z-50 flex items-center bg-default/50 px-[1.6rem]">
-      <div className="h-[26.5rem] w-full rounded-[10px] border border-primary bg-inverse px-[1.6rem] py-[1rem]">
+    <div className="fixed inset-0 z-50 flex items-center bg-default/50 px-[1.6rem]">
+      <div
+        role="dialog"
+        aria-modal="true"
+        aria-labelledby="purchase-guide-title"
+        className="h-[26.5rem] w-full rounded-[10px] border border-primary bg-inverse px-[1.6rem] py-[1rem]"
+      >
@@
-            <h3 className="ml-[0.4rem] head3-m text-default">
+            <h3 id="purchase-guide-title" className="ml-[0.4rem] head3-m text-default">
               카카오 계좌이체 안내
             </h3>

Also applies to: 47-49

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseGuideModal.tsx
around lines 21 - 23, The modal markup in PurchaseGuideModal lacks accessibility
attributes; add role="dialog" and aria-modal="true" to the outer modal container
(the div with className starting "fixed inset-0 z-50 ...") and set
aria-labelledby to the id of the modal title element (create a unique id on the
title element inside the inner container with className "h-[26.5rem] w-full
..."); also add aria-describedby pointing to the modal body text if present.
Apply the same changes to the second modal instance referenced around lines
47-49 so both modal containers include role="dialog", aria-modal="true", and
proper aria-labelledby/aria-describedby IDs, and ensure the title/body elements
have matching id attributes.
apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseNoticeCard.tsx (1)

17-19: 리스트 key를 텍스트 단독으로 쓰면 중복 시 충돌합니다.

공지 문구가 중복되면 key 충돌이 발생할 수 있어, 인덱스를 조합한 key로 바꾸는 편이 안전합니다.

수정 제안
-      {noticeList.map((text) => (
-        <div key={text} className="flex items-start">
+      {noticeList.map((text, index) => (
+        <div key={`${text}-${index}`} className="flex items-start">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseNoticeCard.tsx
around lines 17 - 19, The current mapping in PurchaseNoticeCard.tsx uses
noticeList.map((text) => ...) with key={text}, which can collide when identical
notice strings appear; update the map callback to include the index (e.g.,
noticeList.map((text, idx) => ...)) and set the key to a stable combined value
like `${idx}-${text}` (or another unique identifier) on the outer div to avoid
duplicate key collisions while keeping rendering deterministic.
apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx (1)

111-111: accountText 가독성 개선을 고려해 보세요.

현재 은행명과 계좌번호가 공백 없이 연결되어 "나무은행123-4567-891011"로 표시됩니다. 가독성을 위해 구분자를 추가하는 것을 고려해 볼 수 있습니다.

💡 공백 추가 제안
-        accountText={`${ACCOUNT_INFO.bankName}${ACCOUNT_INFO.accountNumber}`}
+        accountText={`${ACCOUNT_INFO.bankName} ${ACCOUNT_INFO.accountNumber}`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx
at line 111, The accountText currently concatenates ACCOUNT_INFO.bankName and
ACCOUNT_INFO.accountNumber with no separator, hurting readability; update the
PurchaseContent prop assignment (accountText) to join ACCOUNT_INFO.bankName and
ACCOUNT_INFO.accountNumber with a clear separator (e.g., a space, " - ", or
other localized delimiter) using a template literal or a small helper (e.g.,
`${ACCOUNT_INFO.bankName} - ${ACCOUNT_INFO.accountNumber}`) so the rendered
string is human-readable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseCompleteModal.tsx:
- Around line 11-27: The onClose prop declared on PurchaseCompleteModal is never
invoked, so parent modal state isn't cleared; update the component's close flow
(e.g., inside handleConfirm or wherever closing happens) to call onClose?.()
before or after navigation. Modify the PurchaseCompleteModal function to accept
onClose from PurchaseCompleteModalProps and invoke onClose?.() in handleConfirm
(and/or in any other close/escape handlers) so the parent can update its state,
then perform router.push("/main") as needed.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx:
- Line 35: The initial count can exceed menu.remainingCount when remainingCount
is 0; change the state initialization for count so it respects
menu.remainingCount (e.g., initialize count via a function that sets count to 1
only if menu.remainingCount > 0, otherwise 0, or use Math.min(1,
menu.remainingCount)). Update the useState initialization for count (and ensure
any increment/decrement handlers that use setCount also clamp against
menu.remainingCount) so UI never shows a quantity greater than
menu.remainingCount.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseInfoSection.tsx:
- Line 35: The total price rendering in PurchaseInfoSection currently displays
only the number (totalPrice.toLocaleString()) without the currency unit; update
the JSX in the PurchaseInfoSection component to append the Korean currency unit
(원) to the displayed value (e.g., render the formatted totalPrice followed by
"원") so it matches other screens and UX expectations.

In `@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/page.tsx:
- Around line 21-27: The current validation treats 0 and NaN the same by using a
falsy check on selectedMenuId; change the checks to explicit numeric validation:
compute storeId and selectedMenuId as Numbers (already done) and replace the
falsy checks with Number.isInteger/store-range or Number.isNaN checks (e.g.,
ensure !Number.isNaN(selectedMenuId) and optionally selectedMenuId >= 0 if 0 is
valid) and similarly validate storeId before looking up
MOCK_MAIN_STORE_DETAIL_MAP; call notFound() only when the numeric validation
fails or the store lookup returns undefined.

---

Nitpick comments:
In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx:
- Line 111: The accountText currently concatenates ACCOUNT_INFO.bankName and
ACCOUNT_INFO.accountNumber with no separator, hurting readability; update the
PurchaseContent prop assignment (accountText) to join ACCOUNT_INFO.bankName and
ACCOUNT_INFO.accountNumber with a clear separator (e.g., a space, " - ", or
other localized delimiter) using a template literal or a small helper (e.g.,
`${ACCOUNT_INFO.bankName} - ${ACCOUNT_INFO.accountNumber}`) so the rendered
string is human-readable.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseGuideModal.tsx:
- Around line 21-23: The modal markup in PurchaseGuideModal lacks accessibility
attributes; add role="dialog" and aria-modal="true" to the outer modal container
(the div with className starting "fixed inset-0 z-50 ...") and set
aria-labelledby to the id of the modal title element (create a unique id on the
title element inside the inner container with className "h-[26.5rem] w-full
..."); also add aria-describedby pointing to the modal body text if present.
Apply the same changes to the second modal instance referenced around lines
47-49 so both modal containers include role="dialog", aria-modal="true", and
proper aria-labelledby/aria-describedby IDs, and ensure the title/body elements
have matching id attributes.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseNoticeCard.tsx:
- Around line 17-19: The current mapping in PurchaseNoticeCard.tsx uses
noticeList.map((text) => ...) with key={text}, which can collide when identical
notice strings appear; update the map callback to include the index (e.g.,
noticeList.map((text, idx) => ...)) and set the key to a stable combined value
like `${idx}-${text}` (or another unique identifier) on the outer div to avoid
duplicate key collisions while keeping rendering deterministic.

In
`@apps/customer/src/app/`(tabs)/main/store/[id]/purchase/_components/PurchaseOrderCard.tsx:
- Around line 57-62: In PurchaseOrderCard, disable the decrease button when
count <= 0 to match the upper-bound guard: update the decrease button element
that uses onDecrease so it sets disabled={count <= 0} (and/or aria-disabled) and
ensure the onDecrease handler short-circuits if count <= 0 to avoid
side-effects; reference the decrease button element, the onDecrease handler and
the count prop/state in PurchaseOrderCard when making the change.

In `@apps/customer/src/app/`(tabs)/order/_constants/mockOrders.ts:
- Around line 18-31: Several mock order objects in MOCK_ORDERS are duplicated;
create a small factory to generate orders and replace repeated literal objects
to reduce duplication and future bugs: add a helper function (e.g.,
makeMockOrder or createMockOrder) that accepts an overrides object and returns
the common shape (id, storeName, orderSummary, totalPrice, pickupTime), then use
it to produce the entries in the MOCK_ORDERS array (calling makeMockOrder({ id:
3, ... }) and makeMockOrder({ id: 4, ... })) so only differing fields need to be
specified while shared fields live in one place.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ba73c60a-c4f4-444b-8b76-cd9082dc0ca2

📥 Commits

Reviewing files that changed from the base of the PR and between 705bdd4 and 643b131.

⛔ Files ignored due to path filters (7)
  • packages/design-system/src/icons/generated/iconNames.ts is excluded by !**/generated/**
  • packages/design-system/src/icons/generated/spriteSymbols.ts is excluded by !**/generated/**
  • packages/design-system/src/icons/source/Check.svg is excluded by !**/*.svg
  • packages/design-system/src/icons/source/GiftOpen.svg is excluded by !**/*.svg
  • packages/design-system/src/icons/source/KakaoPay.svg is excluded by !**/*.svg
  • packages/design-system/src/icons/source/Minus.svg is excluded by !**/*.svg
  • packages/design-system/src/icons/source/Plus.svg is excluded by !**/*.svg
📒 Files selected for processing (13)
  • apps/customer/src/app/(tabs)/main/_components/MainListView.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseCompleteModal.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseContent.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseGuideModal.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseInfoSection.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseItemCard.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseNoticeCard.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/_components/PurchaseOrderCard.tsx
  • apps/customer/src/app/(tabs)/main/store/[id]/purchase/page.tsx
  • apps/customer/src/app/(tabs)/main/store/_components/StoreDetailContent.tsx
  • apps/customer/src/app/(tabs)/main/store/_components/StoreMenuCard.tsx
  • apps/customer/src/app/(tabs)/order/_constants/mockOrders.ts
  • apps/customer/src/app/(tabs)/order/page.tsx

@skyblue1232 skyblue1232 merged commit 07e7188 into develop Mar 29, 2026
6 checks passed
@skyblue1232 skyblue1232 deleted the feat/#76/random-box-payment branch March 31, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능 구현 및 생성 style 스타일 관련 적용

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 매장 랜덤박스별 구매 페이지 생성

1 participant