Skip to content

munyeol-Yoon/Permu

Repository files navigation

🏆 향수 판매 e-커머스

PERMEATE

서비스 링크 : https://www.permeate.store

⚡ 프로젝트 소개

  • ‘향기’ 와 관련한 제품을 파는 곳은 많지만, 판매 사이트들이 분산되어 있어 구매자의 입장에서는 검증된 사이트를 찾기 쉽지 않습니다.
  • 이에 특정 브랜드에 얽매이지 않고, 다양한 브랜드를 모아 하나의 웹사이트에서 편리하게 구매할 수 있는 e-커머스 사이트입니다.

🎲 팀원 소개

리더: 윤문열 팀원: 박원빈 팀원: 이수진 팀원: 이하얀
윤문열 박원빈 이수진 이하얀
@munyeol-Yoon @harry21-kr @leeejin @hayanLee

🌐 개발 환경 및 서비스 아키텍처

  • Front : Next.js, TailwindCSS
  • Database : Supabase
  • 버전 및 이슈관리 : Github,
  • 협업 툴 : Slack, 노션,
  • 서비스 배포 환경 : Vercel
  • 디자인 : 피그마 초안

🍳 사용 기술

NPMESLintTypeScriptNext JSTailwindCSSShadcn/UILodashSupabaseFigma

역할 분담

➡️ 윤문열

  • 카테고리 페이지
  • 검색 페이지
  • 상품 목록 페이지

➡️ 박원빈

  • 장바구니 페이지
  • 주문 페이지

➡️ 이수진

  • 메인 페이지
  • 상품 디테일 페이지
  • 리뷰 페이지

➡️ 이하얀

  • 로그인(로컬,소셜),로그아웃,회원가입
  • 마이페이지
  • UI

개발 기간

  • 전체 개발 기간 2024-07-16~2024-08-21
  • 아이디어 / 기술스택 선정 2024-07-16~2024-07-19
  • 와이어프레임 / URL 구조 / 역할 분배 2024-07-17~2024-07-21
  • DB테이블 생성 및 디자인, 기능 개발 2024-07-18~2024-08-04
  • MVP 완성 2024-08-05
  • UT 후 추가 기능 개발 및 개선 2024-08-05~2024-08-16
  • 최종 마무리 ~2024-08-21

핵심 기술

  • 주문 ( PortOne API )

💡 페이지별 기능

메인페이지

  • 페이지 이동 nav
    • 카테고리, 장바구니, 마이페이지
    • 헤더 탭
    • 메인 캐러셀 아래 배너
  • 캐러셀
    • 메인 화면
    • 추천 상품
  • 제품 불러오기
    • 주문량 / 최신 제품 / 좋아요 순
  • 특정 상품 브랜드 불러오기
    • 캔들, 디퓨저, 딥디크(브랜드)
  • 제품마다 좋아요 기능

상품상세페이지

  • 장바구니 추가
  • 해당 카테고리로 바로가기
  • 바로 구매하기
  • 카카오톡 공유하기
  • 좋아요 기능 (optimisitc)

리뷰페이지

  • 전체 후기 사진 7개만 불러오기
  • 상품별 리뷰 불러오기
  • 리뷰별 필터링
    • 최신순 / 오랜된 순 / 별점 높은순
  • 페이지네이션 ( prefetching )
  • 이미지 전체 보기 클릭 시
    • 뷰 전체 사진 불러오기

상품 주문/결제페이지

  • 비로그인 시 로컬 스토리지만 사용
  • 로그인 시 로컬 스토리지 +DB 사용
  • 상세 페이지에서 상품 추가 기능
  • 구매할 상품의 상태 변경 가능
    • 상품 삭제
    • 상품 옵션 변경
    • 상품 구매 여부 변경
  • 배송지 변경 가능 (마이페이지)
  • 배송 메모 변경 가능
  • 구매할 상품의 정보 확인 가능
  • 사용할 마일리지 변경 가능
  • 사용할 쿠폰 변경 가능
  • 결제 수단 선택 가능
    • 카카오페이, 토스페이
  • 최종 금액 확인 가능

상품 결과 필터링페이지

  • 상품 결과에 대한 편의성을 위해 필터링 제공
    • 가격별

검색페이지

  • 카테고리 불러오기
  • 로컬 스토리지를 활용한 최근 검색어 추가 및 삭제
  • 디바운싱을 활용한 연관 검색어
  • 연관 상품, 카테고리, 키워드 조회

로그인/회원가입

  • 이메일
    • 이메일 인증 (OTP)
  • OAuth (카카오/구글)
  • 회원가입 시, 유저 추가정보 입력 폼 제공

마이페이지

  • 마일리지 / 쿠폰 / 후기 페이지
  • 주문 내역 / 찜 페이지
  • 회원정보 / 배송지 변경 페이지

트러블 슈팅

🧐 문제 정의
🐌 장바구니가 느리다!

프로젝트 내 장바구니 기능에 대해 부정적인 피드백 중 공통된 피드백은 장바구니가 느리다! 라는 의견이였습니다.
다수의 피드백을 받았고, 개발자 본인도 문제를 인식하고 있음에 해당 이슈에 대해 트러블슈팅을 작성하게 되었습니다.

🤔 정확히 어떤 부분이 느릴까?

1. 장바구니에 상품을 추가해도 바로 적용되지 않고 짧은 딜레이 후 장바구니에 상품이 추가된다!
2. 장바구니에서 구매할 상품의 옵션(수량, 사이즈)을 변경하면 바로 적용되지 않고 딜레이 후 상품의 옵션이 변경된다!
3. 장바구니 내의 상품을 삭제할 때, 바로 적용되지 않고 딜레이 후 상품이 삭제된다!

🤔 단순히 반응이 느린것만 문제일까?

UI가 유저의 인터랙션에 따라 반영되는게 느리다! 라는 문제만 존재한다면 그렇게 심각한 이슈는 아니지만,
실제 주문 페이지에서 주문을 하려고 해도 장바구니에 추가한 상품이 적용되지 않는 현상도 발생합니다.

유저의 입장에서는 "어? 나는 장바구니에 분명 상품을 추가했고, 이 상품을 주문하려고 했는데 왜 반영이 안되어있지?" 혹은
상품 내역을 정확히 확인하지 않는 유저의 경우에는 내가 선택한 제품을 구매하지 못하는 최악의 상황을 맞이할수도 있습니다.

**따라서 단순히 UI가 변경되지 않는다! 라는 이슈보다 더 심각한, 하나의 거대한 버그라고 인지하고 해당 버그를 수정하고자합니다.**

❓ 문제 원인
📡  항상 서버와 통신하는 장바구니

이슈를 파악해본 결과 원인은 굉장히 단순하였습니다.
바로 장바구니에 상품을 담거나, 수정, 삭제할 경우 항상 서버와의 통신이 일어나고 있었다는 점이였죠.

항상 서버와의 통신으로 인해 UI에 반영되는 속도가 늦어지고,
서버와의 통신이 일어나고있는 도중 주문을 하려고 했을때,
즉, 서버에 새로운 상품의 정보를 장바구니에 추가하려고 하는 도중 주문을 하려고 주문 페이지로 넘어가게되면
주문 페이지에서는 최신 장바구니를 반영하지 못한 이전의 장바구니 내역을 보여주고, 결제까지 진행하게 되는 것이죠.

🛠️ 고민 내역
1. 서버와의 통신이 완료될때까지 유저의 행동을 제한한다.

서버와 통신하는 시간동안 UI에는 로딩 스피너와 같은 UI를 표시해주고, 서버와의 통신이 완료될때까지 유저가 다른 행동을 하지 못하게
클라이언트에서 행동을 제한할 수도 있을 것 같습니다.

실제로 이런 솔루션을 사용하고있는 이커머스 사이트는 쿠팡이 있습니다.
쿠팡은 장바구니에서 무언가를 수정, 삭제할 때 구매하기 버튼을 `disabled` 시켜 유저로부터 하여금 서버와의 통신이 종료될때까지
주문 페이지에 가지 못하도록 제한하고 있습니다.

2. 매 수정마다 서버와 통신하지 않는다.

서버와 통신하는 시간이 문제라면, 서버와 통신하는 부분을 없애버릴수도 있겠다는 생각이 들었습니다.
물론 아예 유저의 장바구니 정보가 DB에 저장되지 않는것은 아닙니다.

먼저 장바구니에서 일어나는 추가/수정/삭제와 관련한 부분은 로컬 스토리지에 정보들을 저장한 뒤,
저장된 정보들을 장바구니가 언마운트 될 때, 즉 사이트의 이동이나 유저의 액션이 일어났을 때 DB에 저장을 해주는 것입니다.

하지만 위 방법도 결국에는 서버와 통신하는 시간이 필연적으로 발생하게 되고, 로딩 중이라는 UI는 공통적으로 표현해주어야 합니다.

또한 위 방법으로 문제를 해결하였을떄의 발생할 이슈는 사용자가 브라우저를 종료하였을때에는 React가 언마운트를 감지하지 못하여
창을 강제종료하였을때는 저장이 되지 않는다는 점입니다.

❗️ 문제 해결

기존 로직
로그인 상태
`장바구니 페이지 마운트`
→ `해당 유저의 기존 장바구니를 가져와 setState()` 
→ `매 수정이 일어날때마다 DB에 장바구니 정보 저장` 

비로그인 상태
`장바구니 사용 불가능`

변경된 로직
로그인 상태

`유저 로그인 시 해당 유저의 기존 장바구니를 가져와 로컬스토리지에 저장` 
`장바구니 페이지 마운트`
→ `로컬스토리지에 있는 장바구니 정보를 가져와 setState()`
→ `매 수정이 일어날때마다 로컬에 장바구니 정보 저장`
→ `장바구니 페이지 언마운트 시 DB에 해당 유저 장바구니 정보 저장` 

비로그인 상태
`장바구니 정보를 로컬스토리지에 저장` 
만약 유저가 `로그인` 시,
`로컬스토리지에 있는 상품` + `DB에 있던 유저의 기존 장바구니 정보`
로컬스토리지를 적극적으로 활용하면서 

1. 기존 장바구니가 느리다는 피드백을 개선
2. 추가하거나 수정, 삭제한 제품이 주문 시 포함되는 이슈 해결
3. 로그인을 하지않은 유저도 장바구니를 사용할 수 있도록 개선

이 되었습니다.
사용자 인증 상태를 클라이언트 상태로 관리
문제
context를 이용한 전역 상태 관리 방식은 클라이언트 사이드에서 직접 사용자 인증 정보를 가져와 상태로 관리하기 때문에, 컴포넌트가 렌더링될 때마다 사용자 인증 정보가 존재하는지 확인하는 로직이 필요
=> 초기 사용자 데이터(undefined)가 불확실하고, 이로 인해 UI가 깜빡거리거나 추가 로딩 상태 관리가 필요

TanStack Query를 사용하여 서버 상태 관리를 도입
인증 상태와 같은 서버 데이터를 일관되게 관리하는데 적합하다고 판단

데이터가 자동으로 캐싱되고, 서버와 동기화되며 
컴포넌트는 데이터가 준비된 후 렌더링을 진행하여 불필요한 null 확인 로직 제거

useQuery를 통해 로딩 상태와 데이터를 분리하여, 초기 렌더링 시 데이터 불확실성으로 인한 불필요한 로직 제거

사용자 데이터를 가져오는 로직을 useAuthQuery로 분리하여 재사용성을 높이고, 여러 컴포넌트에서 일관된 방식으로 사용자 데이터를 관리

개선 목표

추후 개발

  • 리펙토링
  • 판매자,브랜드, 이벤트 페이지 구현
  • 주문 취소/환불
  • 아이디/비밀번호 찾기
  • 고객센터

기술적인 도전 계획

  • 페이지 성능 최적화
  • 데이터 보안 강화
  • 1:1 문의 챗봇 도입

프로젝트 후기

윤문열

디자이너와 함께 협업하는 경험이 좋은 경험이었습니다. 다만 일정적인 문제와 계속 부딪혔고 이에 급하게 결과를 만들어 낸 부분 때문에 개선해야 할 점이 보여 아쉽습니다.

박원빈

짧은 시간 안에 어느정도 완성도있는 결과물을 만들어 만족하지만, 시간 관계상 깊게 고민한 후 짜야하는 로직도 짧은 시간 내에 만들어야 해 완성도가 떨어지는 점이 아쉽다고 생각합니다!

이수진

짧은 시간내에 기획과 쇼핑몰을 만들고 유저피드백을 받아 로직 개선을 해봤다는 점이 성장기회였고 마찬가지로 로직에 대해서 조금 더 생각을 못한 것이 아쉬웠습니다

이하얀

기획과 개발 이외에도 UT, 디자이너와의 협업 경험을 할 수 있어서 좋았음. 우선순위, 아쉬운 시간관리로 리팩토링을 비롯한 잘 짜여진 코드를 고민하며, 만들 시간이 부족해 아쉬웠음

프로젝트 구조

 📦src
 ┣ 📂api
 ┃ ┣ 📜addresses.ts
 ┃ ┣ 📜auth.ts
 ┃ ┣ 📜brand.ts
 ┃ ┣ 📜cart.ts
 ┃ ┣ 📜categories.ts
 ┃ ┣ 📜coupon.ts
 ┃ ┣ 📜deliveries.ts
 ┃ ┣ 📜myPage.ts
 ┃ ┣ 📜order.ts
 ┃ ┣ 📜orderInfo.ts
 ┃ ┣ 📜payment.ts
 ┃ ┣ 📜product.ts
 ┃ ┣ 📜review.ts
 ┃ ┣ 📜user.ts
 ┃ ┗ 📜wish.ts
 ┣ 📂app
 ┃ ┣ 📂(provider)
 ┃ ┃ ┣ 📂(root)
 ┃ ┃ ┃ ┣ 📂(NavCategories)
 ┃ ┃ ┃ ┃ ┣ 📂brands
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂events
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂support
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┗ 📜layout.tsx
 ┃ ┃ ┃ ┣ 📂auth
 ┃ ┃ ┃ ┃ ┣ 📂log-in
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂sign-up
 ┃ ┃ ┃ ┃ ┃ ┣ 📂account-form
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂agreement
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂complete
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂email-confirm
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┗ 📜layout.tsx
 ┃ ┃ ┃ ┣ 📂cart
 ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┣ 📜CartAccordion.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜CartEmpty.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜CartItem.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜CartList.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜CartSelector.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┣ 📂category
 ┃ ┃ ┃ ┃ ┣ 📂search
 ┃ ┃ ┃ ┃ ┃ ┣ 📂result
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterBenefits.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterButton.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterLabel.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterNavMenu.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterPricePoint.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜FilterPriceType.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜ResultFilter.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜layout.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜RecentSearch.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜SearchInput.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜SearchNotFound.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┣ 📂mypage
 ┃ ┃ ┃ ┃ ┣ 📂address
 ┃ ┃ ┃ ┃ ┃ ┣ 📂edit
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂coupon
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂edit
 ┃ ┃ ┃ ┃ ┃ ┣ 📂info
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂password
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂mileage
 ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂MilieageCard
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜MileageCard.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂orders
 ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂OrderCard
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜OrderCard.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂OrderItem
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜OrderItem.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂ReviewItem
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜ReviewItem.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂review
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂wish
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┣ 📂CouponCard
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CouponCard.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┣ 📂InfoCard
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜InfoCard.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂LinkCard
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜LinkCard.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📂Profile
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜Profile.tsx
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┣ 📂order
 ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┣ 📜OrderCompleted.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜OrderError.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜OrderLoading.tsx
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┣ 📂products
 ┃ ┃ ┃ ┃ ┣ 📂category
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┣ 📂[productId]
 ┃ ┃ ┃ ┃ ┃ ┣ 📂qna
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📂review
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂images
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜layout.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┃ ┗ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┣ 📂Coupon
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Coupon.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┣ 📂DeliveryOptions
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜DeliveryOptions.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┣ 📂DetailButtons
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Paying.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Share.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜Wish.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📂DetailTabs
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Detail.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜DetailTabs.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜QnA.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜Review.tsx
 ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┣ 📂Footer
 ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CallInfo.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜SNSInfo.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜Footer.tsx
 ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┃ ┃ ┗ 📂Header
 ┃ ┃ ┃ ┃ ┃ ┣ 📂_components
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜HeaderNav.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜NavCategories.tsx
 ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜TopBanner.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜Header.tsx
 ┃ ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┃ ┗ 📜Navbar.tsx
 ┃ ┃ ┃ ┣ 📜layout.tsx
 ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┗ 📜layout.tsx
 ┃ ┣ 📂api
 ┃ ┃ ┣ 📂auth
 ┃ ┃ ┃ ┣ 📂callback
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂log-in
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂log-out
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂otp
 ┃ ┃ ┃ ┃ ┣ 📂sign-up
 ┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂provider
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📂user
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂brands
 ┃ ┃ ┃ ┣ 📂brand
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂carts
 ┃ ┃ ┃ ┗ 📂[id]
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂categories
 ┃ ┃ ┃ ┗ 📂category
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂category
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂my
 ┃ ┃ ┃ ┣ 📂address
 ┃ ┃ ┃ ┃ ┣ 📂[id]
 ┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂coupon
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂orders
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📂wishes
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂order
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂orderInfo
 ┃ ┃ ┃ ┗ 📂[id]
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂products
 ┃ ┃ ┃ ┣ 📂brands
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂category
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┣ 📂wishes
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┣ 📂reviews
 ┃ ┃ ┃ ┣ 📂images
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┗ 📂search
 ┃ ┃ ┃ ┣ 📂relation
 ┃ ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┃ ┃ ┗ 📜route.ts
 ┃ ┣ 📜global-error.tsx
 ┃ ┣ 📜globals.css
 ┃ ┣ 📜icon.ico
 ┃ ┗ 📜layout.tsx
 ┣ 📂assets
 ┃ ┣ 📂brands
 ┃ ┃ ┣ 📜brand1.png
 ┃ ┃ ┣ 📜brand2.png
 ┃ ┃ ┗ 📜brand3.png
 ┃ ┣ 📂events
 ┃ ┃ ┣ 📜event1.png
 ┃ ┃ ┣ 📜event2.png
 ┃ ┃ ┣ 📜event3.png
 ┃ ┃ ┗ 📜event4.png
 ┃ ┣ 📜sign-up.png
 ┃ ┗ 📜support.png
 ┣ 📂components
 ┃ ┣ 📂BrandBanner
 ┃ ┃ ┣ 📜BrandBanner.tsx
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂Bread
 ┃ ┃ ┣ 📜Bread.tsx
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂Card
 ┃ ┃ ┣ 📜CategoryCard.tsx
 ┃ ┃ ┣ 📜EventLinkCard.tsx
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜ProductCard.tsx
 ┃ ┃ ┣ 📜ReviewCard.tsx
 ┃ ┃ ┗ 📜SkeletonCard.tsx
 ┃ ┣ 📂CategoryMore
 ┃ ┃ ┣ 📜CategoryMore.tsx
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂Input
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜Input.tsx
 ┃ ┣ 📂Loading
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜Loading.tsx
 ┃ ┣ 📂Navbar
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜Navbar.tsx
 ┃ ┣ 📂Pagination
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜PageButton.tsx
 ┃ ┃ ┗ 📜Pagination.tsx
 ┃ ┣ 📂products
 ┃ ┃ ┗ 📂Cart
 ┃ ┃ ┃ ┗ 📜Cart.tsx
 ┃ ┣ 📂SearchPage
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜MenuItem.tsx
 ┃ ┃ ┗ 📜SearchHeader.tsx
 ┃ ┣ 📂Sliders
 ┃ ┃ ┣ 📜BannerSlide.tsx
 ┃ ┃ ┣ 📜CategoryProducts.tsx
 ┃ ┃ ┣ 📜CategorySection.tsx
 ┃ ┃ ┣ 📜CurrentProducts.tsx
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜MdReviews.tsx
 ┃ ┃ ┣ 📜ProductSlide.tsx
 ┃ ┃ ┗ 📜Sliders.tsx
 ┃ ┣ 📂Tab
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜Tab.tsx
 ┃ ┣ 📂Toggle
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜Toggle.tsx
 ┃ ┗ 📂ui
 ┃ ┃ ┣ 📜accordion.tsx
 ┃ ┃ ┣ 📜breadcrumb.tsx
 ┃ ┃ ┣ 📜button.tsx
 ┃ ┃ ┣ 📜calendar.tsx
 ┃ ┃ ┣ 📜carousel.tsx
 ┃ ┃ ┣ 📜checkbox.tsx
 ┃ ┃ ┣ 📜dialog.tsx
 ┃ ┃ ┣ 📜drawer.tsx
 ┃ ┃ ┣ 📜dropdown-menu.tsx
 ┃ ┃ ┣ 📜input.tsx
 ┃ ┃ ┣ 📜select.tsx
 ┃ ┃ ┣ 📜skeleton.tsx
 ┃ ┃ ┣ 📜tabs.tsx
 ┃ ┃ ┣ 📜toast.tsx
 ┃ ┃ ┣ 📜toaster.tsx
 ┃ ┃ ┗ 📜use-toast.ts
 ┣ 📂constant
 ┃ ┗ 📜pathname.ts
 ┣ 📂contexts
 ┃ ┗ 📂auth.context
 ┃ ┃ ┗ 📜auth.context.tsx
 ┣ 📂hooks
 ┃ ┣ 📂mutation
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜useAddressMutation.ts
 ┃ ┃ ┣ 📜useAuthMutation.ts
 ┃ ┃ ┣ 📜useCartsMutation.ts
 ┃ ┃ ┣ 📜useOrderMutation.ts
 ┃ ┃ ┗ 📜useWishesMutation.ts
 ┃ ┣ 📂query
 ┃ ┃ ┣ 📂mypage
 ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┣ 📜useCouponQuery.ts
 ┃ ┃ ┃ ┣ 📜useOrderListQuery.ts
 ┃ ┃ ┃ ┗ 📜useUserWishesQuery.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜useAddressQuery.ts
 ┃ ┃ ┣ 📜useAuthQuery.ts
 ┃ ┃ ┣ 📜useBrandsQuery.ts
 ┃ ┃ ┣ 📜useCartsQuery.ts
 ┃ ┃ ┣ 📜useCategoryQuery.ts
 ┃ ┃ ┣ 📜useOrderInfoQuery.ts
 ┃ ┃ ┣ 📜useProductsQuery.ts
 ┃ ┃ ┣ 📜useRelatedSearchQuery.ts
 ┃ ┃ ┣ 📜useReviewsQuery.ts
 ┃ ┃ ┣ 📜useReviewsTotalImagesQuery.ts
 ┃ ┃ ┣ 📜useSearchQuery.ts
 ┃ ┃ ┗ 📜useWishesQuery.ts
 ┃ ┣ 📜useAlert.ts
 ┃ ┣ 📜useCart.ts
 ┃ ┣ 📜useLocalCart.ts
 ┃ ┗ 📜useRecentSearchTerms.tsx
 ┣ 📂mockup
 ┃ ┣ 📜banner.json
 ┃ ┣ 📜deliveryInfo.json
 ┃ ┣ 📜keyword.ts
 ┃ ┣ 📜mdPick.json
 ┃ ┗ 📜userReview.json
 ┣ 📂providers
 ┃ ┗ 📜QueryProvider.tsx
 ┣ 📂supabase
 ┃ ┣ 📜client.ts
 ┃ ┣ 📜middleware.ts
 ┃ ┗ 📜server.ts
 ┣ 📂types
 ┃ ┣ 📂myPage
 ┃ ┃ ┗ 📜order.ts
 ┃ ┣ 📜brands.ts
 ┃ ┣ 📜cart.ts
 ┃ ┣ 📜categories.ts
 ┃ ┣ 📜deliveries.ts
 ┃ ┣ 📜order.ts
 ┃ ┣ 📜products.ts
 ┃ ┣ 📜review.ts
 ┃ ┣ 📜search.ts
 ┃ ┣ 📜supabase.ts
 ┃ ┗ 📜types.ts
 ┣ 📂utils
 ┃ ┣ 📜cn.ts
 ┃ ┗ 📜validateCheck.ts
 ┗ 📜middleware.ts 

About

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages