-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 마이페이지 UI 구현 (#43) #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
344f4f7
feat(#43): 아이콘 및 사진 세팅
wkdtnqls0506 3f537f1
feat(#43): /member/profile 페이지 및 레이아웃 생성
wkdtnqls0506 f647718
feat(#43): Profile 컴포넌트 생성
wkdtnqls0506 b74b401
feat(#43): Banner 컴포넌트 생성
wkdtnqls0506 8501ac8
feat(#43): MenuList 컴포넌트 생성 및 메뉴 리스트 상수화
wkdtnqls0506 b564961
chore(#43): 불필요한 async 키워드 제거
wkdtnqls0506 34deddc
chore(#43): 피그마 아이콘 네이밍에 맞게 아이콘 파일명 변경 및 적용
wkdtnqls0506 248e9af
refactor(#43): MENU_LIST를 Union 타입으로 변경하여 link/action 메뉴 분리
wkdtnqls0506 deaed52
refactor(#43): Suspense 기반 로딩 처리로 변경 및 ProfileSkeleton 적
wkdtnqls0506 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { style } from "@vanilla-extract/css"; | ||
|
|
||
| import { colors, semantic } from "@/styles"; | ||
|
|
||
| export const wrapper = style({ | ||
| backgroundColor: colors.redOrange[90], | ||
| padding: "1.4rem 2.4rem", | ||
| }); | ||
|
|
||
| export const linkWrapper = style({ | ||
| display: "flex", | ||
| alignItems: "center", | ||
| gap: "0.4rem", | ||
| }); | ||
|
|
||
| export const icon = style({ | ||
| color: semantic.icon.black, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| "use client"; | ||
|
|
||
| import Image from "next/image"; | ||
| import Link from "next/link"; | ||
|
|
||
| import ChevronRightIcon from "@/assets/chevron-right.svg"; | ||
| import { Bleed } from "@/components/ui/Bleed"; | ||
| import { HStack, VStack } from "@/components/ui/Stack"; | ||
| import { Text } from "@/components/ui/Text"; | ||
|
|
||
| import * as styles from "./Banner.css"; | ||
|
|
||
| export const Banner = () => { | ||
| return ( | ||
| <Bleed inline={20} className={styles.wrapper}> | ||
| <HStack align='center' gap={8}> | ||
| <Image | ||
| src='/images/store.png' | ||
| alt='가게 이미지' | ||
| width={55} | ||
| height={55} | ||
| /> | ||
| <VStack gap={4} justify='center'> | ||
| <Text typo='body1Sb' color='neutral.10'> | ||
| 당신의 소중한 가게를 소개해주세요 | ||
| </Text> | ||
| {/* TODO: [가게 등록하기] url로 변경 */} | ||
| <Link href='/' className={styles.linkWrapper}> | ||
| <Text typo='label2' color='neutral.10'> | ||
| 가게 등록하기 | ||
| </Text> | ||
| <ChevronRightIcon width={16} height={16} className={styles.icon} /> | ||
| </Link> | ||
| </VStack> | ||
| </HStack> | ||
| </Bleed> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { Banner } from "./Banner"; |
16 changes: 16 additions & 0 deletions
16
src/app/member/profile/_components/MenuList/MenuList.css.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { style } from "@vanilla-extract/css"; | ||
|
|
||
| import { semantic, typography } from "@/styles"; | ||
|
|
||
| export const wrapper = style({ | ||
| padding: "1.6rem 0", | ||
| }); | ||
|
|
||
| export const list = style({ | ||
| padding: "1.4rem 0", | ||
| }); | ||
|
|
||
| export const menuItem = style({ | ||
| ...typography.body1Sb, | ||
| color: semantic.text.normal, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| "use client"; | ||
|
|
||
| import Link from "next/link"; | ||
|
|
||
| import { VStack } from "@/components/ui/Stack"; | ||
|
|
||
| import { MENU_LIST } from "../../_constants"; | ||
| import * as styles from "./MenuList.css"; | ||
|
|
||
| export const MenuList = () => { | ||
| return ( | ||
| <> | ||
| <VStack as='ul' gap={8} className={styles.wrapper}> | ||
| {MENU_LIST.map(menu => ( | ||
| <li key={menu.id} className={styles.list}> | ||
| {menu.type === "link" ? ( | ||
| <Link href={menu.link} className={styles.menuItem}> | ||
| {menu.label} | ||
| </Link> | ||
| ) : ( | ||
| <button type='button' className={styles.menuItem}> | ||
| {menu.label} | ||
| </button> | ||
| )} | ||
| </li> | ||
| ))} | ||
| </VStack> | ||
| {/* TODO: 로그아웃시 나타날 모달 연결 */} | ||
| </> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { MenuList } from "./MenuList"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { style } from "@vanilla-extract/css"; | ||
|
|
||
| import { colors, radius } from "@/styles"; | ||
|
|
||
| export const wrapper = style({ | ||
| paddingBottom: "2rem", | ||
| }); | ||
|
|
||
| export const imageBackground = style({ | ||
| display: "flex", | ||
| justifyContent: "center", | ||
| width: "7rem", | ||
| height: "7rem", | ||
| paddingTop: "1.6rem", | ||
| backgroundColor: colors.redOrange[80], | ||
| border: `1px solid ${colors.redOrange[70]}`, | ||
| borderRadius: radius.circle, | ||
| overflow: "hidden", | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| "use client"; | ||
|
|
||
| import { useSuspenseQuery } from "@tanstack/react-query"; | ||
|
|
||
| import { memberQueryOptions } from "@/app/member/_api"; | ||
| import { Text } from "@/components/ui/Text"; | ||
|
|
||
| import { ProfileLayout } from "./ProfileLayout"; | ||
|
|
||
| export const Profile = () => { | ||
| const { data: member } = useSuspenseQuery(memberQueryOptions); | ||
|
|
||
| return ( | ||
| <ProfileLayout> | ||
| <Text typo='title2Sb' color='neutral.10'> | ||
| {member.nickname} | ||
| </Text> | ||
| <Text typo='caption1Md' color='neutral.50'> | ||
| {member.email} | ||
| </Text> | ||
| </ProfileLayout> | ||
| ); | ||
| }; |
25 changes: 25 additions & 0 deletions
25
src/app/member/profile/_components/Profile/ProfileLayout.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| "use client"; | ||
|
|
||
| import { type ReactNode } from "react"; | ||
|
|
||
| import Bapurit from "@/assets/logo/front-bapurit.svg"; | ||
| import { HStack, VStack } from "@/components/ui/Stack"; | ||
|
|
||
| import * as styles from "./Profile.css"; | ||
|
|
||
| export type ProfileLayoutProps = { | ||
| children: ReactNode; | ||
| }; | ||
|
|
||
| export const ProfileLayout = ({ children }: ProfileLayoutProps) => { | ||
| return ( | ||
| <HStack gap={16} className={styles.wrapper}> | ||
| <div className={styles.imageBackground}> | ||
| <Bapurit width={61} height={61} /> | ||
| </div> | ||
| <VStack justify='center' gap={8}> | ||
| {children} | ||
| </VStack> | ||
| </HStack> | ||
| ); | ||
| }; |
13 changes: 13 additions & 0 deletions
13
src/app/member/profile/_components/Profile/ProfileSkeleton.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { Skeleton } from "@/components/ui/Skeleton"; | ||
| import { radius } from "@/styles"; | ||
|
|
||
| import { ProfileLayout } from "./ProfileLayout"; | ||
|
|
||
| export const ProfileSkeleton = () => { | ||
| return ( | ||
| <ProfileLayout> | ||
| <Skeleton width={80} height={20} radius={radius[40]} /> | ||
| <Skeleton width={160} height={20} radius={radius[40]} /> | ||
| </ProfileLayout> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { Profile } from "./Profile"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from "./menuList.constants"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { type MenuListItem } from "../types"; | ||
|
|
||
| // TODO: 노션, 인스타 링크 전달받으면 수정 | ||
| export const MENU_LIST: readonly MenuListItem[] = [ | ||
| { type: "link", id: "notice", label: "공지사항", link: "/" }, | ||
| { type: "link", id: "customer_service", label: "고객센터", link: "/" }, | ||
| { type: "link", id: "guide", label: "잇다 이용가이드", link: "/" }, | ||
| { type: "action", id: "logout", label: "로그아웃" }, | ||
| ] as const; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { style } from "@vanilla-extract/css"; | ||
|
|
||
| import { semantic } from "@/styles"; | ||
|
|
||
| export const wrapper = style({ | ||
| height: "100dvh", | ||
| display: "flex", | ||
| flexDirection: "column", | ||
| }); | ||
|
|
||
| export const button = style({ | ||
| width: "2.4rem", | ||
| height: "2.4rem", | ||
| display: "flex", | ||
| justifyContent: "center", | ||
| alignItems: "center", | ||
| }); | ||
|
|
||
| export const icon = style({ | ||
| color: semantic.icon.black, | ||
| }); | ||
|
|
||
| export const mainWrapper = style({ | ||
| display: "flex", | ||
| flex: 1, | ||
| flexDirection: "column", | ||
| padding: "2rem", | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| "use client"; | ||
|
|
||
| import { useRouter } from "next/navigation"; | ||
| import { type ReactNode } from "react"; | ||
|
|
||
| import ChevronLeftIcon from "@/assets/chevron-left.svg"; | ||
| import { GNB } from "@/components/ui/GNB"; | ||
|
|
||
| import * as styles from "./layout.css"; | ||
|
|
||
| type MemberProfileLayoutProps = { | ||
| children: ReactNode; | ||
| }; | ||
|
|
||
| export default function MemberProfileLayout({ | ||
| children, | ||
| }: MemberProfileLayoutProps) { | ||
| const router = useRouter(); | ||
| const handleClick = () => { | ||
| router.push("/"); | ||
| }; | ||
|
|
||
| return ( | ||
| <div className={styles.wrapper}> | ||
| <GNB | ||
| align='center' | ||
| title='마이페이지' | ||
| leftAddon={ | ||
| <button | ||
| type='button' | ||
| onClick={handleClick} | ||
| aria-label='홈으로 이동하기' | ||
| className={styles.button} | ||
| > | ||
| <ChevronLeftIcon | ||
| width={24} | ||
| height={24} | ||
| onClick={handleClick} | ||
| className={styles.icon} | ||
| /> | ||
| </button> | ||
| } | ||
| /> | ||
| <main className={styles.mainWrapper}>{children}</main> | ||
| </div> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { Suspense } from "react"; | ||
|
|
||
| import { VStack } from "@/components/ui/Stack"; | ||
|
|
||
| import { Banner } from "./_components/Banner"; | ||
| import { MenuList } from "./_components/MenuList"; | ||
| import { Profile } from "./_components/Profile"; | ||
| import { ProfileSkeleton } from "./_components/Profile/ProfileSkeleton"; | ||
|
|
||
| export default function ProfilePage() { | ||
| return ( | ||
| <VStack> | ||
| <Suspense fallback={<ProfileSkeleton />}> | ||
| <Profile /> | ||
| </Suspense> | ||
| <Banner /> | ||
| <MenuList /> | ||
| </VStack> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from "./menuList.types"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| type LinkMenu = { | ||
| type: "link"; | ||
| id: string; | ||
| label: string; | ||
| link: string; | ||
| }; | ||
|
|
||
| type ActionMenu = { | ||
| type: "action"; | ||
| id: string; | ||
| label: string; | ||
| }; | ||
|
|
||
| export type MenuListItem = LinkMenu | ActionMenu; |
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: useSuspenseQuery, suspense, error boundary로 loading, error 처리의 관심을 분리해보는 건 어떨까요?!
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deaed52
오.. 그렇게 분리하면 컴포넌트에서는 성공한 상태만 관리하면 되니 좋군요..!! 수정했습니다 ~ . ~👍🏻👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
한가지 궁금한 점이 있습니다 ~ . ~
닉네임과 전화번호만 필요한 데이터라 해당 부분만 스켈레톤 처리가 필요해서
ProfileLayout을 상위에 따로 생성하고 컴포넌트와 Skeleton을 따로 선언해서 사용했는데요!!일부 데이터만 로딩 처리가 필요한 경우엔 보통 어떤 방식으로 처리하시나용?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수빈님 하신 것처럼 처리하기도 합니다!
최대한 먼저 보여줄 수 있는 부분은 보여주는 것이 경험에 더 좋아서, 적절히 영역을 나눠서 처리하면 좋아요~! ex) a 데이터 가져온 후 b 데이터 가져와서 a+b를 보여줄 때, a 데이터를 먼저 보여줘도 괜찮으면 그거 먼저 보여주고 b 로딩되면 b도 보여주고,,
이 질문이 맞으실까요?,,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 정확히 맞습니다~!~!
Profile전체를 처리할지, 아니면 필요한 부분만 레아이웃으로 분리해서 관리하는지 궁금해서 여쭤봤습니다 ㅎㅎ감사해요!!🙇🏻♀️👍🏻