Skip to content

Commit 767f80c

Browse files
authored
Merge pull request #152 from YAPP-Github/feature/PRODUCT-270
feat: 마이페이지에 응원 가게, 스토리 연결 (#147)
2 parents e655d50 + 4525379 commit 767f80c

File tree

28 files changed

+486
-104
lines changed

28 files changed

+486
-104
lines changed

src/app/(cheer)/cheer/_components/MyCheerCard/MyCheerCard.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import { useRouter } from "next/navigation";
66
import { type ReactNode, useRef, useState } from "react";
77
import Slider, { type Settings } from "react-slick";
88

9-
import { cheeredMemberQueryOptions } from "@/app/(home)/_api/shop";
10-
import { type CheeredStore } from "@/app/(store)/_api/shop";
9+
import {
10+
cheeredMemberQueryOptions,
11+
type CheeredStore,
12+
} from "@/app/(store)/_api/shop";
1113
import { Avatar } from "@/app/member/_components/Avatar";
1214
import LocationIcon from "@/assets/location.svg";
1315
import MarketIcon from "@/assets/market-fill.svg";
Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { queryOptions } from "@tanstack/react-query";
22

3-
import { getCheeredMember } from "@/app/(store)/_api/shop";
4-
53
import { getStores } from "./shop.api";
64

75
export const storesQueryKeys = {
@@ -21,13 +19,3 @@ export const storesQueryOptions = ({
2119
queryKey: storesQueryKeys.size(size, category),
2220
queryFn: () => getStores({ size, category }),
2321
});
24-
25-
export const cheeredMemberQueryKeys = {
26-
all: ["cheeredMember"] as const,
27-
};
28-
29-
export const cheeredMemberQueryOptions = () =>
30-
queryOptions({
31-
queryKey: cheeredMemberQueryKeys.all,
32-
queryFn: () => getCheeredMember(),
33-
});

src/app/(store)/_api/shop/shop.queries.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { queryOptions } from "@tanstack/react-query";
22

3-
import { getStoreCheers, getStoreDetail, getStoreImages } from "./shop.api";
3+
import {
4+
getCheeredMember,
5+
getStoreCheers,
6+
getStoreDetail,
7+
getStoreImages,
8+
} from "./shop.api";
49

510
export const storeQueryKeys = {
611
all: ["store"] as const,
@@ -28,3 +33,13 @@ export const storeImagesQueryOptions = (storeId: number) =>
2833
queryKey: storeQueryKeys.images(storeId),
2934
queryFn: () => getStoreImages(storeId),
3035
});
36+
37+
export const cheeredMemberQueryKeys = {
38+
all: ["cheeredMember"] as const,
39+
};
40+
41+
export const cheeredMemberQueryOptions = () =>
42+
queryOptions({
43+
queryKey: cheeredMemberQueryKeys.all,
44+
queryFn: () => getCheeredMember(),
45+
});

src/app/member/profile/_components/Banner/Banner.css.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/app/member/profile/_components/Banner/Banner.tsx

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/app/member/profile/_components/Banner/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/app/member/profile/_components/Header/Header.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { useRouter } from "next/navigation";
44

5-
import ChevronLeftIcon from "@/assets/chevron-left.svg";
5+
import SettingIcon from "@/assets/setting.svg";
66
import { GNB } from "@/components/ui/GNB";
77

88
import * as styles from "./Header.css";
@@ -11,21 +11,21 @@ export const Header = () => {
1111
const router = useRouter();
1212

1313
const handleClick = () => {
14-
router.push("/");
14+
router.push("/member/setting");
1515
};
1616

1717
return (
1818
<GNB
1919
align='center'
2020
title='마이페이지'
21-
leftAddon={
21+
rightAddon={
2222
<button
2323
type='button'
2424
onClick={handleClick}
2525
aria-label='홈으로 이동하기'
2626
className={styles.button}
2727
>
28-
<ChevronLeftIcon
28+
<SettingIcon
2929
width={24}
3030
height={24}
3131
onClick={handleClick}

src/app/member/profile/_components/Profile/Profile.css.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { style } from "@vanilla-extract/css";
22

3-
import { colors, radius } from "@/styles";
3+
import { colors, radius, semantic, typography } from "@/styles";
44

55
export const wrapper = style({
66
paddingBottom: "2rem",
@@ -17,3 +17,11 @@ export const imageBackground = style({
1717
borderRadius: radius.circle,
1818
overflow: "hidden",
1919
});
20+
21+
export const myCheerRegisterButton = style({
22+
...typography.body2Sb,
23+
width: "100%",
24+
padding: "0.9rem 2.8rem",
25+
borderRadius: radius[100],
26+
border: `1px solid ${semantic.border.grayLight}`,
27+
});
Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,67 @@
11
"use client";
22

3+
import * as AlertDialog from "@radix-ui/react-alert-dialog";
34
import { useSuspenseQuery } from "@tanstack/react-query";
5+
import Link from "next/link";
46

7+
import { cheeredMemberQueryOptions } from "@/app/(store)/_api/shop";
58
import { memberQueryOptions } from "@/app/member/_api";
9+
import { AlertModal } from "@/components/ui/AlertModal";
10+
import { Button } from "@/components/ui/Button";
11+
import { VStack } from "@/components/ui/Stack";
612
import { Text } from "@/components/ui/Text";
713

14+
import * as styles from "./Profile.css";
815
import { ProfileLayout } from "./ProfileLayout";
916

1017
export const Profile = () => {
1118
const { data: member } = useSuspenseQuery(memberQueryOptions);
19+
const { data } = useSuspenseQuery(cheeredMemberQueryOptions());
20+
const stores = data.stores ?? [];
1221

1322
return (
14-
<ProfileLayout>
15-
<Text typo='title2Sb' color='neutral.10'>
16-
{member.nickname}
17-
</Text>
18-
<Text typo='caption1Md' color='neutral.50'>
19-
{member.email}
20-
</Text>
21-
</ProfileLayout>
23+
<VStack gap={20}>
24+
<ProfileLayout>
25+
<Text typo='title2Sb' color='neutral.10'>
26+
{member.nickname}
27+
</Text>
28+
<Text typo='caption1Md' color='neutral.50'>
29+
{member.email}
30+
</Text>
31+
</ProfileLayout>
32+
33+
{stores.length >= 3 ? (
34+
<AlertModal
35+
title='세 가게 모두 등록 완료!'
36+
content={
37+
<Text typo='body2Rg' color='text.alternative'>
38+
응원하는 가게는 <br /> 최대 3곳까지만 등록할 수 있어요.
39+
</Text>
40+
}
41+
trigger={
42+
<button className={styles.myCheerRegisterButton}>
43+
내 응원 등록
44+
</button>
45+
}
46+
footer={
47+
<AlertDialog.Action asChild>
48+
<Button
49+
variant='primary'
50+
size='large'
51+
fullWidth
52+
style={{ borderRadius: "0 0 1.2rem 1.2rem" }}
53+
>
54+
확인
55+
</Button>
56+
</AlertDialog.Action>
57+
}
58+
/>
59+
) : (
60+
<Link href='/stores/register'>
61+
{/* TODO: Outline 버튼으로 변경 */}
62+
<button className={styles.myCheerRegisterButton}>내 응원 등록</button>
63+
</Link>
64+
)}
65+
</VStack>
2266
);
2367
};
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { style } from "@vanilla-extract/css";
2+
3+
import { radius, semantic } from "@/styles";
4+
5+
export const cheerTabContent = style({
6+
display: "flex",
7+
flexDirection: "column",
8+
gap: "1.2rem",
9+
});
10+
11+
export const emptyWrapper = style({
12+
marginTop: "9rem",
13+
textAlign: "center",
14+
});
15+
16+
export const wrapperBase = style({
17+
padding: "2rem",
18+
borderRadius: "2.4rem",
19+
});
20+
21+
export const wrapperYellow = style([
22+
wrapperBase,
23+
{ backgroundColor: "#FEF8DD" },
24+
]);
25+
export const wrapperPink = style([wrapperBase, { backgroundColor: "#FDE5E3" }]);
26+
export const wrapperBlue = style([wrapperBase, { backgroundColor: "#E0F2FF" }]);
27+
28+
export const WRAPPER_COLORS = [wrapperYellow, wrapperPink, wrapperBlue];
29+
30+
export const locationIcon = style({
31+
color: semantic.icon.gray,
32+
});
33+
34+
export const cheerPeopleCountWrapper = style({
35+
backgroundColor: semantic.background.white,
36+
padding: "0.8rem 1.2rem",
37+
borderRadius: radius[100],
38+
});
39+
40+
export const avatarOverlap = style({
41+
border: "2px solid white",
42+
marginLeft: "-18px",
43+
borderRadius: radius.circle,
44+
width: "2.4rem",
45+
height: "2.4rem",
46+
47+
":first-child": {
48+
marginLeft: "0",
49+
},
50+
});
51+
52+
export const storyGrid = style({
53+
display: "grid",
54+
gridTemplateColumns: "repeat(3, 1fr)",
55+
gap: "0.1rem",
56+
});
57+
58+
export const storyCard = style({
59+
position: "relative",
60+
width: "100%",
61+
aspectRatio: "124 / 210",
62+
});
63+
64+
export const storyImage = style({
65+
objectFit: "cover",
66+
});
67+
68+
export const overlay = style({
69+
position: "absolute",
70+
inset: 0,
71+
background:
72+
"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.7) 100%)",
73+
});
74+
75+
export const storeNameWrapper = style({
76+
position: "absolute",
77+
left: "0.6rem",
78+
bottom: "1.2rem",
79+
80+
display: "flex",
81+
alignItems: "center",
82+
gap: "0.4rem",
83+
});
84+
85+
export const marketIcon = style({
86+
color: semantic.icon.white,
87+
});
88+
89+
export const preLine = style({
90+
whiteSpace: "pre-line",
91+
});

0 commit comments

Comments
 (0)