Skip to content

Commit 26cf850

Browse files
authored
Merge pull request #105 from YAPP-Github/feature/PRODUCT-215
2 parents 227675e + e516e00 commit 26cf850

File tree

37 files changed

+977
-9
lines changed

37 files changed

+977
-9
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
"@vanilla-extract/css": "^1.17.2",
2828
"@vanilla-extract/dynamic": "^2.1.5",
2929
"@vanilla-extract/recipes": "^0.5.7",
30+
"clsx": "^2.1.1",
3031
"es-toolkit": "^1.39.7",
3132
"framer-motion": "^12.23.9",
3233
"iron-session": "^8.0.4",
3334
"ky": "1.7.5",
3435
"lottie-react": "^2.4.1",
3536
"next": "15.3.2",
37+
"overlay-kit": "^1.8.4",
3638
"react": "^19.0.0",
3739
"react-dom": "^19.0.0",
3840
"react-hook-form": "^7.58.1",

pnpm-lock.yaml

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/(cheer)/_api/cheer.api.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { authHttp } from "@/lib/api";
2+
3+
import {
4+
type CheerRegisterRequest,
5+
type CheerRegisterResponse,
6+
} from "./cheer.types";
7+
8+
/**
9+
* 응원 등록 API
10+
* @param {CheerRegisterRequest} cheerRequest - 응원 등록 요청 데이터
11+
* @param {File | null} imageFile - 업로드할 이미지 파일 (선택사항)
12+
*
13+
* @returns {Promise<CheerRegisterResponse>} 등록된 응원 ID 반환
14+
*/
15+
export const postCheer = async (
16+
cheerRequest: CheerRegisterRequest,
17+
imageFile: File | null
18+
): Promise<CheerRegisterResponse> => {
19+
const formData = new FormData();
20+
21+
formData.append(
22+
"request",
23+
new Blob([JSON.stringify(cheerRequest)], { type: "application/json" })
24+
);
25+
26+
if (imageFile) {
27+
formData.append("image", imageFile);
28+
}
29+
30+
return await authHttp
31+
.post("api/cheer", {
32+
body: formData,
33+
})
34+
.json<CheerRegisterResponse>();
35+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useMutation, useQueryClient } from "@tanstack/react-query";
2+
3+
import { postCheer } from "./cheer.api";
4+
import type { CheerRegisterRequest } from "./cheer.types";
5+
6+
export const cheerQueryKeys = {
7+
all: ["cheer"] as const,
8+
lists: () => [...cheerQueryKeys.all, "list"] as const,
9+
} as const;
10+
11+
export const usePostCheerMutation = () => {
12+
const queryClient = useQueryClient();
13+
14+
return useMutation({
15+
mutationFn: ({
16+
cheerRequest,
17+
imageFile,
18+
}: {
19+
cheerRequest: CheerRegisterRequest;
20+
imageFile: File | null;
21+
}) => {
22+
return postCheer(cheerRequest, imageFile);
23+
},
24+
onSuccess: () => {
25+
queryClient.invalidateQueries({
26+
queryKey: cheerQueryKeys.lists(),
27+
});
28+
},
29+
});
30+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export type CheerRegisterRequest = {
2+
storeKakaoId: string;
3+
storeName: string;
4+
description: string;
5+
};
6+
7+
export type CheerRegisterResponse = {
8+
storeId: number;
9+
cheerId: number;
10+
imageUrl: string;
11+
cheerDescription: string;
12+
};

src/app/(cheer)/_api/index.ts

Whitespace-only changes.

src/app/(store)/stores/[storeId]/_components/StoreCheers/StoreCheers.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,7 @@ const CheerContent = ({ storeId }: { storeId: string }) => {
8282

8383
<Spacer size={shouldShowToggleButton ? 12 : 20} />
8484

85-
{/*
86-
TODO: 가게 응원하기 버튼 클릭 시 가게 응원 페이지로 이동
87-
추후 가게 응원 등록 작업할 때 연결 예정
88-
*/}
89-
<Link href={""}>
85+
<Link href={`/stores/register?storeId=${storeId}`}>
9086
<Button variant='primary' size='large' fullWidth>
9187
가게 응원하기
9288
</Button>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { style } from "@vanilla-extract/css";
2+
3+
import { colors } from "@/styles";
4+
5+
export const progressBar = style({
6+
width: "100%",
7+
height: "0.4rem",
8+
backgroundColor: colors.coolNeutral[98],
9+
position: "relative",
10+
borderRadius: "0.2rem",
11+
overflow: "hidden",
12+
13+
selectors: {
14+
"&::after": {
15+
content: "''",
16+
position: "absolute",
17+
top: 0,
18+
left: 0,
19+
height: "100%",
20+
width: "100%",
21+
backgroundColor: colors.redOrange[50],
22+
borderRadius: "0.2rem",
23+
transformOrigin: "left center",
24+
transition: "transform 0.5s ease",
25+
transform: "scaleX(0)",
26+
},
27+
28+
"&[data-active='true']::after": {
29+
transform: "scaleX(1)",
30+
},
31+
},
32+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { HStack } from "@/components/ui/Stack";
2+
3+
import * as styles from "./ProgressBar.css";
4+
5+
type ProgressBarProps = {
6+
currentStep: number;
7+
totalSteps: number;
8+
};
9+
10+
export const ProgressBar = ({ currentStep, totalSteps }: ProgressBarProps) => {
11+
const isActive = (index: number) => currentStep >= index + 1;
12+
13+
return (
14+
<HStack gap={4}>
15+
{Array.from({ length: totalSteps }).map((_, index) => (
16+
<div
17+
key={index}
18+
className={styles.progressBar}
19+
data-active={isActive(index)}
20+
/>
21+
))}
22+
</HStack>
23+
);
24+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./ProgressBar";

0 commit comments

Comments
 (0)