Skip to content

Commit bb06fb3

Browse files
authored
Merge pull request #155 from YAPP-Github/feat/main-layout
2 parents 226ef12 + 0c3432f commit bb06fb3

15 files changed

Lines changed: 160 additions & 182 deletions

File tree

src/app/(home)/_api/cheer/cheer.types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import { type ImageResponse } from "@/types";
2+
13
export type Cheer = {
24
storeId: number;
3-
imageUrl: string;
5+
images: ImageResponse[];
46
storeName: string;
57
storeDistrict: string;
68
storeNeighborhood: string;
79
storeCategory: string;
810
cheerId: number;
911
cheerDescription: string;
12+
tags: string[];
1013
};
1114

1215
export type CheersResponse = {

src/app/(home)/_api/shop/shop.api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,24 @@ import { type StoresResponse } from "./shop.types";
1010
export const getStores = async ({
1111
size,
1212
category,
13+
tag,
14+
location,
1315
}: {
1416
size: number;
1517
category?: string;
18+
tag?: string[];
19+
location?: string[];
1620
}): Promise<StoresResponse> => {
21+
const toCSV = (v?: string | string[]) =>
22+
Array.isArray(v) ? v.filter(Boolean).join(",") : v || undefined;
23+
1724
return await http
1825
.get("api/shops", {
1926
searchParams: {
2027
size,
2128
...(category ? { category } : {}),
29+
...(toCSV(tag) ? { tag: toCSV(tag) } : {}),
30+
...(toCSV(location) ? { location: toCSV(location) } : {}),
2231
},
2332
})
2433
.json<StoresResponse>();

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,26 @@ import { getStores } from "./shop.api";
44

55
export const storesQueryKeys = {
66
all: ["stores"] as const,
7-
size: (size: number, category?: string) =>
8-
[...storesQueryKeys.all, size, category] as const,
7+
size: (
8+
size: number,
9+
category?: string,
10+
tag?: string[],
11+
location?: string[]
12+
) => [...storesQueryKeys.all, size, category, tag, location] as const,
913
};
1014

1115
export const storesQueryOptions = ({
1216
size,
1317
category,
18+
tag,
19+
location,
1420
}: {
1521
size: number;
1622
category?: string;
23+
tag?: string[];
24+
location?: string[];
1725
}) =>
1826
queryOptions({
19-
queryKey: storesQueryKeys.size(size, category),
20-
queryFn: () => getStores({ size, category }),
27+
queryKey: storesQueryKeys.size(size, category, tag, location),
28+
queryFn: () => getStores({ size, category, tag, location }),
2129
});

src/app/(home)/_components/RecentCheers/RecentCheers.css.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ export const recentSupportCard = style({
66
borderRadius: "2.8rem",
77
padding: "2rem",
88
border: "2px solid #fff",
9-
height: "13.6rem",
9+
minHeight: "13.6rem",
10+
maxHeight: "17.4rem",
11+
overflow: "hidden",
1012
});
1113

1214
export const cheersContent = style({
@@ -58,6 +60,7 @@ export const storeImage = style({
5860
width: "4rem",
5961
height: "4rem",
6062
borderRadius: radius[100],
63+
objectFit: "cover",
6164
});
6265

6366
export const storeImageFallback = style([

src/app/(home)/_components/RecentCheers/RecentCheers.tsx

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

33
import { Suspense } from "@suspensive/react";
44
import { useSuspenseQuery } from "@tanstack/react-query";
5-
import { chunk } from "es-toolkit";
5+
import { at, chunk, compact } from "es-toolkit";
6+
import { isEmpty } from "es-toolkit/compat";
67
import Image from "next/image";
78
import Link from "next/link";
89
import { type HTMLAttributes, useState } from "react";
@@ -13,8 +14,10 @@ import ResetIcon from "@/assets/reset-20.svg";
1314
import { Button } from "@/components/ui/Button";
1415
import { Skeleton } from "@/components/ui/Skeleton";
1516
import { HStack, VStack } from "@/components/ui/Stack";
17+
import { Tag } from "@/components/ui/Tag";
1618
import { Text } from "@/components/ui/Text";
1719
import { TextButton } from "@/components/ui/TextButton";
20+
import { ALL_TAGS } from "@/constants/tag.constants";
1821
import { colors } from "@/styles";
1922

2023
import { cheerQueryOptions } from "../../_api/cheer";
@@ -66,23 +69,24 @@ const RecentSupportCardContent = () => {
6669
}}
6770
store={{
6871
name: cheer.storeName,
69-
imageUrl: cheer.imageUrl,
72+
imageUrl: cheer.images[0]?.url ?? "",
7073
location: `${cheer.storeDistrict} ${cheer.storeNeighborhood}`,
7174
category: cheer.storeCategory,
7275
}}
7376
content={cheer.cheerDescription}
77+
tags={cheer.tags}
7478
/>
7579
</Link>
7680
))}
7781
</VStack>
78-
<Link href='/stores'>
82+
<Link href='/cheer'>
7983
<Button
8084
variant='custom'
8185
size='large'
8286
className={styles.showAllButton}
8387
fullWidth
8488
>
85-
가게 전체보기
89+
응원 전체보기
8690
</Button>
8791
</Link>
8892
</VStack>
@@ -98,13 +102,19 @@ type RecentSupportCardProps = {
98102
category: string;
99103
};
100104
content: string;
105+
tags: string[];
101106
} & HTMLAttributes<HTMLDivElement>;
102107

103108
const RecentSupportCard = ({
104109
store,
105110
content,
111+
tags,
106112
...restProps
107113
}: RecentSupportCardProps) => {
114+
const selectedTags = ALL_TAGS.filter(tag => tags?.includes(tag.name));
115+
116+
const visibleTags = compact(at(selectedTags, [0, 1]));
117+
108118
return (
109119
<VStack gap={8} className={styles.recentSupportCard} {...restProps}>
110120
<HStack gap={12}>
@@ -114,7 +124,6 @@ const RecentSupportCard = ({
114124
height={40}
115125
alt={`${store.name} 가게 이미지`}
116126
className={styles.storeImage}
117-
objectFit='cover'
118127
src={store.imageUrl}
119128
// TODO: 추후 제거
120129
unoptimized
@@ -152,6 +161,18 @@ const RecentSupportCard = ({
152161
>
153162
{content}
154163
</Text>
164+
165+
{isEmpty(selectedTags) ? null : (
166+
<HStack gap={8}>
167+
{visibleTags.map(tag => (
168+
<Tag key={tag.name}>
169+
<Image src={tag.iconUrl} alt={tag.label} width={14} height={14} />
170+
{tag.label}
171+
</Tag>
172+
))}
173+
{selectedTags.length > 2 && <Tag>+{selectedTags.length - 2}</Tag>}
174+
</HStack>
175+
)}
155176
</VStack>
156177
);
157178
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Suspense } from "react";
2+
3+
import { ChipFilter } from "@/app/_shared/ChipFilter";
4+
import { StoreList as StoreListComponent } from "@/app/(store)/stores/(list)/_components";
5+
import { Bleed } from "@/components/ui/Bleed";
6+
import { FoodCategories } from "@/components/ui/FoodCategory";
7+
import { Spacer } from "@/components/ui/Spacer";
8+
import { VStack } from "@/components/ui/Stack";
9+
import { useFoodCategory } from "@/hooks/useFoodCategory";
10+
11+
export const StoreList = () => {
12+
const { categories, handleSelectCategory, selectedCategory } =
13+
useFoodCategory("/");
14+
15+
return (
16+
<VStack>
17+
<Bleed inline={20}>
18+
<FoodCategories
19+
categories={categories}
20+
selectedCategory={selectedCategory}
21+
onSelectCategory={handleSelectCategory}
22+
/>
23+
</Bleed>
24+
25+
<Spacer size={12} />
26+
27+
<ChipFilter />
28+
29+
<Suspense>
30+
<StoreListComponent category={selectedCategory.name} />
31+
</Suspense>
32+
</VStack>
33+
);
34+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./StoreList";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { RecentCheers } from "./RecentCheers";
22
export { RecentlySupportedStores } from "./RecentlySupportStories";
33
export { RegisterPopup } from "./RegisterPopup";
4+
export { StoreList } from "./StoreList";
45
export { StoreStory } from "./StoreStory";
56
export { Story } from "./Story";

src/app/(home)/page.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import { Bleed } from "@/components/ui/Bleed";
44
import { Spacer } from "@/components/ui/Spacer";
55
import { VStack } from "@/components/ui/Stack";
6+
import { colors } from "@/styles";
67

7-
import { RecentCheers, RegisterPopup, Story } from "./_components";
8+
import { RecentCheers, RegisterPopup, StoreList, Story } from "./_components";
89
import { ServiceIntroBottomSheet } from "./_components/ServiceIntroBottomSheet";
910
import { RegisterFloatingButton } from "./_shared/RegisterFloatingButton";
1011

@@ -15,10 +16,18 @@ export default function HomePage() {
1516
<Spacer size={12} />
1617
<Story />
1718
</Bleed>
18-
<Spacer size={12} />
1919
<Spacer size={32} />
20-
<VStack gap={40}>
20+
<VStack gap={32}>
2121
<RecentCheers />
22+
23+
<Bleed inline={20}>
24+
<Spacer
25+
size={12}
26+
style={{ backgroundColor: colors.coolNeutral[98] }}
27+
/>
28+
</Bleed>
29+
30+
<StoreList />
2231
</VStack>
2332
<RegisterFloatingButton />
2433
<ServiceIntroBottomSheet />

src/app/(store)/constants/storeCategory.constants.ts

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

0 commit comments

Comments
 (0)