Skip to content
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

[Feat/#144] 카드리스트 수정 및 관련 API 연결 #169

Merged
merged 11 commits into from
Jan 22, 2025
47 changes: 47 additions & 0 deletions src/apis/designList/useFetchDesignDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useQuery } from '@tanstack/react-query';

import { instance } from '@apis/instance';

import { END_POINT, queryKey } from '@constants';

import { ApiResponseType } from '@types';

interface cakeType {
cakeId: number;
isLiked: boolean;
imageUrl: string;
}

interface DesignDetailResponse {
storeId: number;
storeName: string;
station: string;
cake: cakeType[];
}
Comment on lines +9 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types 폴더로 빼면 좋을 것 같습니다!


const fetchDesignDetail = async (
cakeId: number,
dayCategory: string,
themeName: string
): Promise<DesignDetailResponse> => {
try {
const response = await instance.get<ApiResponseType<DesignDetailResponse>>(
END_POINT.FETCH_DESIGN_DETAIL(cakeId, dayCategory, themeName)
);
return response.data.data;
} catch (error) {
console.log(error);
throw error;
}
};

export const useFetchDesignDetail = (
cakeId: number,
dayCategory: string,
themeName: string
) => {
return useQuery({
queryKey: [queryKey.DESIGN_DETAIL],
queryFn: () => fetchDesignDetail(cakeId, dayCategory, themeName),
});
};
45 changes: 45 additions & 0 deletions src/apis/designList/useFetchDesignList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useQuery } from '@tanstack/react-query';

import { instance } from '@apis/instance';

import { END_POINT, queryKey } from '@constants';

import { ApiResponseType, DesignListResponse, ErrorResponse } from '@types';

const fetchDesignList = async (
option: string,
dayCategory: string,
themeName: string
): Promise<DesignListResponse> => {
try {
const response = await instance.get<ApiResponseType<DesignListResponse>>(
END_POINT.FETCH_DESIGN_LIST(option, dayCategory, themeName)
);
return response.data.data;
} catch (error) {
const errorResponse = error as ErrorResponse;
console.log(errorResponse.response.data.code);
if (errorResponse.response.data.code === 40420) {
return {
nextCakeIdCursor: 0,
nextCakeLikesCursor: 0,
isLastData: false,
cakeCount: 0,
cakes: [],
};
}
throw error;
}
};

export const useFetchDesignList = (
option: string,
dayCategory: string,
themeName: string
) => {
return useQuery({
queryKey: [queryKey.DESIGN_LIST, option, dayCategory, themeName],
queryFn: () => fetchDesignList(option, dayCategory, themeName),
staleTime: 0,
});
};
8 changes: 4 additions & 4 deletions src/apis/home/useFetchStoreRank.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { instance } from '@apis/instance';

import { END_POINT, queryKey } from '@constants';

import { ApiResponseType, StoreRankResponse } from '@types';
import { ApiResponseType, StoreRank, StoreRankResponse } from '@types';

const fetchStoreRank = async (): Promise<StoreRankResponse> => {
const fetchStoreRank = async (): Promise<StoreRank[]> => {
try {
const response = await instance.get<ApiResponseType<StoreRankResponse>>(
END_POINT.FETCH_STORE_RANK
);
return response.data.data;
return response.data.data.storeList;
} catch (error) {
console.log(error)
console.log(error);
throw error;
}
};
Expand Down
2 changes: 2 additions & 0 deletions src/apis/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const instance = axios.create({
withCredentials: true,
});



Comment on lines +11 to +12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

export function get<T>(...args: Parameters<typeof instance.get>) {
return instance.get<T>(...args);
}
Expand Down
45 changes: 45 additions & 0 deletions src/apis/myPage/useFetchLikedStoreList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useQuery } from '@tanstack/react-query';

import { instance } from '@apis/instance';

import { END_POINT, queryKey } from '@constants';

import { ApiResponseType, ErrorResponse, LikedStoreListResponse } from '@types';

const fetchLikedStoreList = async (
option: string,
pageParam?: string
): Promise<LikedStoreListResponse> => {
try {
const endpoint = pageParam
? END_POINT.FETCH_LIKED_STORE_LIST(option, pageParam)
: END_POINT.FETCH_LIKED_STORE_LIST(option);

const response =
await instance.get<ApiResponseType<LikedStoreListResponse>>(endpoint);
return response.data.data;
} catch (error) {
const errorResponse = error as ErrorResponse;
console.log(errorResponse.response.data.code);
if (errorResponse.response.data.code === 40420) {
return {
nextStoreIdCursor: -1,
nextLikesCursor: undefined,
storeCount: 0,
stores: [], // 빈 배열 반환
};
}
throw error;
}
};

export const useFetchLikedStoreList = (
option: string,

pageParam?: string
) => {
return useQuery({
queryKey: [queryKey.LIKED_STORE_LIST, option, pageParam],
queryFn: () => fetchLikedStoreList(option, pageParam || ''),
});
};
45 changes: 34 additions & 11 deletions src/components/common/CardList/CardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,79 @@ import FilteringButton from '../FilteringButton/FilteringButton';
import StoreCard from '../StoreCard/StoreCard';

import {
CategoryType,
DesignCardListType,
DesignItemType,
ItemType,
OptionType,
StoreCardListType,
StoreType,
SubCategoryType,
} from '@types';

interface CardListProps {
item: ItemType;
itemData: StoreCardListType | DesignCardListType;
hasModal?: boolean;
itemData?: StoreCardListType | DesignCardListType;
handleOptionSelect: (option: OptionType) => void;
hasModal?: boolean;
selectedCategories?: {
category: CategoryType;
subCategory: SubCategoryType;
};
}

const CardList = ({
item,
itemData,
hasModal = false,
handleOptionSelect,
hasModal,
selectedCategories,
}: CardListProps) => {
// 데이터를 조건에 따라 바로 분기 처리
const isStoreCardListType = (
data: DesignCardListType | StoreCardListType
): data is StoreCardListType => {
return data !== null && 'stores' in data;
return 'stores' in data && 'storeCount' in data;
};

const isDesignCardListType = (
data: DesignCardListType | StoreCardListType
): data is DesignCardListType => {
return 'cakes' in data && 'cakeCount' in data;
};

// itemData가 StoreCardListType인 경우 stores에 접근 가능
const cardListData = itemData
? isStoreCardListType(itemData)
? itemData.stores // Store 데이터
: itemData.cakes // Design 데이터
: isDesignCardListType(itemData)
? itemData.cakes // Design 데이터
: []
: []; // itemData가 null일 경우 빈 배열

// itemData가 StoreCardListType인 경우 storeCount에 접근 가능
const cardListCount = itemData
? isStoreCardListType(itemData)
? itemData.storeCount // Store 데이터 개수
: itemData.cakeCount // Design 데이터 개수
: isDesignCardListType(itemData)
? itemData.cakeCount // Design 데이터 개수
: 0
: 0;

// 카드리스트 텍스트 상황에 따라 다르게
const cardListCountText = {
store: ` 개의 스토어`,
design: ` 개의 디자인`,
likedStore: `찜한 스토어 `,
likedDesign: `찜한 스토어의 디자인 `,
likedDesign: `찜한 디자인 `,
likedStoreDesign: `찜한 스토어의 디자인`,
};

const cardListNullText = {
store: `등록된 스토어가 아직 없어요`,
design: `등록된 케이크가 아직 없어요`,
likedStore: `찜한 스토어가 아직 없어요`,
likedDesign: `찜한 디자인이 아직 없어요`,
likedStoreDesign: `찜한 스토어의 디자인이 아직 없어요`,
};

return (
Expand All @@ -79,7 +99,9 @@ const CardList = ({

<span className={countTextStyle}>{cardListCountText[item]}</span>

{(item === 'likedStore' || item === 'likedDesign') && (
{(item === 'likedStore' ||
item === 'likedDesign' ||
item === 'likedStoreDesign') && (
<span className={countNumberStyle}>{cardListCount}</span>
)}
</div>
Expand All @@ -90,16 +112,17 @@ const CardList = ({
{item === 'store' || item === 'likedStore' ? (
<div className={storeCardListWrapper}>
{(cardListData as StoreType[]).map((store) => (
<StoreCard storeItem={store} />
<StoreCard storeItem={store} key={store.storeId} />
))}
</div>
) : (
<div className={designCardListWrapper}>
{(cardListData as DesignItemType[]).map((cake) => (
<DesignCard
key={cake.cakeId}
designItem={cake}
designId={cake.cakeId}
hasModal={hasModal}
selectedCategories={selectedCategories}
/>
))}
</div>
Expand Down
28 changes: 20 additions & 8 deletions src/components/common/DesignCard/DesignCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,38 @@ import {
infoTitleStyle,
} from './DesignCard.css';

import { DesignItemType } from '@types';
import { CategoryType, DesignItemType, SubCategoryType } from '@types';
interface DesignCardProps extends HTMLAttributes<HTMLDivElement> {
designItem: DesignItemType;
designId: number;
numberLabel?: string;
hasModal?: boolean;
handleCardClick?: () => void;
selectedCategories?: {
category: CategoryType;
subCategory: SubCategoryType;
};
}

const DesignCard = ({
designItem,
designId,
numberLabel,
hasModal = false,
selectedCategories,
}: DesignCardProps) => {
const { storeId, imageUrl, storeName, station, cakeLikesCount, isLiked } =
designItem;
const {
cakeId,
storeId,
imageUrl,
storeName,
station,
cakeLikesCount,
isLiked,
} = designItem;

const { isModalOpen, openModal, closeModal } = useModal();
const { goStorePage } = useEasyNavigate();

const { openModal, isModalOpen, closeModal } = useModal();

const handleCardClick = () => {
if (hasModal) {
openModal(); // 둘러보기 페이지에서는 모달 띄우기
Expand All @@ -52,14 +64,14 @@ const DesignCard = ({
buttonType="like20"
count={cakeLikesCount}
isActive={isLiked}
itemId={designId}
itemId={cakeId}
/>
</div>
</article>

{isModalOpen && (
<Modal variant="bottom" hasBackdrop backdropClick={closeModal}>
<DesignSearchModal storeId={storeId} />
<DesignSearchModal cakeId={cakeId} storeId={storeId} selectedCategories={selectedCategories} />
</Modal>
)}
</>
Expand Down
12 changes: 12 additions & 0 deletions src/constants/apis/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ export const BASE_URL = import.meta.env.VITE_APP_BASE_URL;
export const END_POINT = {
KAKAO_LOGIN: '/api/v1/user/login',
FETCH_STORE_RANK: '/api/v1/store/rank',
FETCH_DESIGN_LIST: (option: string, dayCategory: string, themeName: string) =>
`/api/v1/cake/${option}?dayCategory=${dayCategory}&themeName=${themeName}`,
FETCH_DESIGN_DETAIL: (
cakeId: number,
dayCategory: string,
themeName: string
) =>
`/api/v1/cake/select/${cakeId}?dayCategory=${dayCategory}&themeName=${themeName}`,
FETCH_LIKED_STORE_LIST: (option: string, pageParam?: string) =>
pageParam
? `/api/v1/store/likes/${option}?storeIdCursor=${pageParam}`
: `/api/v1/store/likes/${option}`,
FETCH_STORE_COORDINATE_LIST: (station: string) =>
`/api/v1/store/coordinate-list?station=${station}`,
FETCH_SELECT_STORE_COORDINATE: (storeId: number) =>
Expand Down
6 changes: 5 additions & 1 deletion src/constants/apis/queryKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export const queryKey = {
KAKAO_LOGIN: 'kakaoLogin',
STORE_RANK: 'storeRank',
DESIGN_LIST: 'designList',
DESIGN_DETAIL: 'designDetail',
KAKAO_LOGIN: 'kakaoLogin',
LIKED_STORE_LIST: 'likedStoreList',
STORE_COORDINATE_LIST: 'storeCoordinateList',
STORE_INFO: 'storeInfo',
STORE_DETAIL_DESIGN: 'storeDetailDesign',
STORE_DETAIL_SIZE: 'storeDetailSize',
Expand Down
Loading
Loading