diff --git a/src/apis/templeInfo/axios.ts b/src/apis/templeInfo/axios.ts index 95fc2025..aac9a4b2 100644 --- a/src/apis/templeInfo/axios.ts +++ b/src/apis/templeInfo/axios.ts @@ -1,16 +1,12 @@ import instance from '@apis/instance'; -export const getTempleDetails = async (templestayId: string, userId?: string) => { - const res = await instance.get('/templestay', { - params: { templestayId, userId }, - }); +export const getTempleDetails = async (id: number) => { + const res = await instance.get(`/v2/api/templestay/details/${id}`); return res.data; }; -export const getTempleImages = async (templestayId: string) => { - const res = await instance.get('/public/templestay/img', { - params: { templestayId }, - }); +export const getTempleImages = async (id: number) => { + const res = await instance.get(`/v2/api/templestay/images/${id}`); return res.data; }; diff --git a/src/apis/templeInfo/index.ts b/src/apis/templeInfo/index.ts index c08b6200..6000d68b 100644 --- a/src/apis/templeInfo/index.ts +++ b/src/apis/templeInfo/index.ts @@ -1,21 +1,24 @@ +import { ApiResponse } from '@apis/response'; import { useQuery } from '@tanstack/react-query'; import { getTempleReviews, getTempleImages, getTempleDetails } from './axios'; import { ReviewsResponse, TemplestayImgsResponse, TempleDetail } from './type'; -export const useGetTempleDetails = (templestayId: string, userId?: string) => { - const { data, isLoading, isError } = useQuery({ - queryKey: ['detailPage', templestayId, userId], - queryFn: () => getTempleDetails(templestayId, userId), +export const useGetTempleDetails = (id: number) => { + const { data, isLoading, isError } = useQuery({ + queryKey: ['detailPage', id], + queryFn: () => getTempleDetails(id), + select: (res: ApiResponse) => res.data, }); return { data, isLoading, isError }; }; -export const useGetTempleImages = (templestayId: string) => { - const { data, isLoading, isError } = useQuery({ - queryKey: ['images', templestayId], - queryFn: () => getTempleImages(templestayId), +export const useGetTempleImages = (id: number) => { + const { data, isLoading, isError } = useQuery({ + queryKey: ['images', id], + queryFn: () => getTempleImages(id), + select: (res: ApiResponse) => res.data, }); return { data, isLoading, isError }; diff --git a/src/apis/templeInfo/prefetch.ts b/src/apis/templeInfo/prefetch.ts index 99a634e7..41f6f8f3 100644 --- a/src/apis/templeInfo/prefetch.ts +++ b/src/apis/templeInfo/prefetch.ts @@ -3,16 +3,16 @@ import { queryOptions } from '@tanstack/react-query'; import { getTempleImages, getTempleReviews, getTempleDetails } from './axios'; import { TemplestayImgsResponse, ReviewsResponse, TempleDetail } from './type'; -export const templeDetailQueryOptions = (templestayId: string, userId?: string) => +export const templeDetailQueryOptions = (id: number) => queryOptions({ - queryKey: ['detailPage', templestayId, userId], - queryFn: () => getTempleDetails(templestayId, userId), + queryKey: ['detailPage', id], + queryFn: () => getTempleDetails(id), }); -export const templeImagesQueryOptions = (templestayId: string) => +export const templeImagesQueryOptions = (id: number) => queryOptions({ - queryKey: ['images', templestayId], - queryFn: () => getTempleImages(templestayId), + queryKey: ['images', id], + queryFn: () => getTempleImages(id), }); export const templeReviewsQueryOptions = (templestayId: string, page: number) => diff --git a/src/apis/templeInfo/type.ts b/src/apis/templeInfo/type.ts index 7a4b2d78..fb9b6e55 100644 --- a/src/apis/templeInfo/type.ts +++ b/src/apis/templeInfo/type.ts @@ -1,29 +1,25 @@ export interface TempleDetail { - templestayId: string; - templeName: string; + id: number; templestayName: string; - phoneNumber: string; + templeName: string; address: string; - tag?: string; - templestayPrice?: string; - introduction?: string; - detailAddress: string; - youtube?: string; - schedule?: string; - latitude: number; - longitude: number; - liked: boolean; + phone: string; + schedule: string; + price: number; + introduction: string; url: string; + lat: number; + lon: number; + wish: boolean; } export interface TemplestayImg { - imageUrlId: number; - imgUrl: string; + imgurl: string; } export interface TemplestayImgsResponse { - total: number; - templestayImgs: TemplestayImg[]; + id: number; + imgUrls: TemplestayImg[]; } export interface Review { diff --git a/src/app/detail/[templestayId]/TempleDetailClient.tsx b/src/app/detail/[templestayId]/TempleDetailClient.tsx index f2591aab..e8f605c4 100644 --- a/src/app/detail/[templestayId]/TempleDetailClient.tsx +++ b/src/app/detail/[templestayId]/TempleDetailClient.tsx @@ -29,18 +29,17 @@ const SmallMap = dynamic(() => import('@components/templeDetail/naverMap/smallMa }); interface TempleDetailClientProps { - templestayId: string; + id: number; } -const TempleDetailClient = ({ templestayId }: TempleDetailClientProps) => { +const TempleDetailClient = ({ id }: TempleDetailClientProps) => { const [userId, setUserId] = useState(undefined); useEffect(() => { - const id = getCookie('userId') as string; - setUserId(id); + const user = getCookie('userId') as string; + setUserId(user); }, []); - - const { data, isLoading, isError } = useGetTempleDetails(templestayId, userId || undefined); + const { data, isLoading, isError } = useGetTempleDetails(id); const queryClient = useQueryClient(); const addWishlistMutation = useAddWishlist(); const removeWishlistMutation = useRemoveWishlist(); @@ -51,7 +50,7 @@ const TempleDetailClient = ({ templestayId }: TempleDetailClientProps) => { useEffect(() => { if (data) { - setLiked(data.liked); + setLiked(data.wish); } }, [data]); @@ -66,7 +65,7 @@ const TempleDetailClient = ({ templestayId }: TempleDetailClientProps) => { const mutation = liked ? removeWishlistMutation : addWishlistMutation; mutation.mutate( - { userId: Number(userId), templestayId: Number(templestayId) }, + { userId: Number(userId), templestayId: Number(id) }, { onSuccess: () => { setLiked(!liked); @@ -126,17 +125,13 @@ const TempleDetailClient = ({ templestayId }: TempleDetailClientProps) => { )}
- +
- - + +
@@ -145,15 +140,11 @@ const TempleDetailClient = ({ templestayId }: TempleDetailClientProps) => {
- +
- + }) => { const { templestayId } = await params; - const cookieStore = await cookies(); - const userId = cookieStore.get('userId')?.value; + const id = Number(templestayId); + if (!Number.isInteger(id) || id <= 0) { + throw new Error(`Invalid templestay ID: ${templestayId}`); + } + const stringId = templestayId; const queryClient = new QueryClient(); await Promise.all([ - queryClient.prefetchQuery(templeDetailQueryOptions(templestayId, userId || undefined)), - queryClient.prefetchQuery(templeImagesQueryOptions(templestayId)), - queryClient.prefetchQuery(templeReviewsQueryOptions(templestayId, 1)), + queryClient.prefetchQuery(templeDetailQueryOptions(id)), + queryClient.prefetchQuery(templeImagesQueryOptions(id)), + queryClient.prefetchQuery(templeReviewsQueryOptions(stringId, 1)), ]); return ( - + ); }; diff --git a/src/app/detail/[templestayId]/photo/TempleImagesClient.tsx b/src/app/detail/[templestayId]/photo/TempleImagesClient.tsx new file mode 100644 index 00000000..5bbe50a5 --- /dev/null +++ b/src/app/detail/[templestayId]/photo/TempleImagesClient.tsx @@ -0,0 +1,49 @@ +'use client'; +import { useGetTempleImages } from '@apis/templeInfo'; +import PageName from '@components/common/pageName/PageName'; +import ExceptLayout from '@components/except/exceptLayout/ExceptLayout'; +import Image from 'next/image'; + +import * as styles from './style.css'; + +interface TemplePhotoPageProps { + templestayId: number; +} + +const TempleImageClient = ({ templestayId }: TemplePhotoPageProps) => { + const { data, isLoading, isError } = useGetTempleImages(templestayId); + + if (isLoading) { + return ; + } + + if (isError) { + return ; + } + + if (!data || !data.imgUrls.length) { + return

No temple images available

; + } + + return ( +
+
+ +
+
+ {data.imgUrls.map((photo) => ( + 템플스테이 사진 + ))} +
+
+ ); +}; + +export default TempleImageClient; diff --git a/src/app/detail/[templestayId]/photo/page.tsx b/src/app/detail/[templestayId]/photo/page.tsx index 662c8ba6..5f839ecc 100644 --- a/src/app/detail/[templestayId]/photo/page.tsx +++ b/src/app/detail/[templestayId]/photo/page.tsx @@ -1,45 +1,10 @@ -import { templeImagesQueryOptions } from '@apis/templeInfo/prefetch'; -import { TemplestayImg, TemplestayImgsResponse } from '@apis/templeInfo/type'; -import PageName from '@components/common/pageName/PageName'; -import { QueryClient } from '@tanstack/react-query'; -import Image from 'next/image'; - -import * as styles from './style.css'; +import TempleImageClient from './TempleImagesClient'; const TemplePhotoPage = async ({ params }: { params: Promise<{ templestayId: string }> }) => { const { templestayId } = await params; - const queryClient = new QueryClient(); - const cachedData = queryClient.getQueryData(['images', templestayId]); - if (!cachedData) { - await queryClient.prefetchQuery(templeImagesQueryOptions(templestayId)); - } - const data = - queryClient.getQueryData(['images', templestayId]) || - (await queryClient.fetchQuery(templeImagesQueryOptions(templestayId))); - - if (!data) { - return

No temple images available

; - } + const templestayIdNumber = Number(templestayId); - return ( -
-
- -
-
- {data.templestayImgs.map((photo: TemplestayImg) => ( - {`Temple - ))} -
-
- ); + return ; }; export default TemplePhotoPage; diff --git a/src/components/carousel/detailCarousel/DetailCarousel.tsx b/src/components/carousel/detailCarousel/DetailCarousel.tsx index 28af53fe..701b4958 100644 --- a/src/components/carousel/detailCarousel/DetailCarousel.tsx +++ b/src/components/carousel/detailCarousel/DetailCarousel.tsx @@ -11,10 +11,10 @@ const largeEmptyImage = '@assets/images/img_gray_light_leaf_large.png'; const DetailCarousel = () => { const { templestayId } = useParams(); - const { data, isLoading, isError } = useGetTempleImages(String(templestayId)); + const { data, isLoading, isError } = useGetTempleImages(Number(templestayId)); const { carouselRef, transformStyle, handleDragChange, handleDragEnd } = useCarousel({ - itemCount: data?.total || 0, + itemCount: data?.imgUrls.length || 0, moveDistance: 355, }); @@ -43,13 +43,13 @@ const DetailCarousel = () => { onDragChange: handleDragChange, onDragEnd: handleDragEnd, })}> - {data.templestayImgs.map((image, index) => ( + {data.imgUrls.map((image, index) => ( ))}
diff --git a/src/components/templeDetail/templeInfo/templeInfo.tsx b/src/components/templeDetail/templeInfo/templeInfo.tsx index e964ee98..6941d74f 100644 --- a/src/components/templeDetail/templeInfo/templeInfo.tsx +++ b/src/components/templeDetail/templeInfo/templeInfo.tsx @@ -8,36 +8,26 @@ import * as styles from './templeInfo.css'; interface TempleInfoProps { introduction?: string; } -interface StringKeyValue { - [key: string]: string; -} const TempleInfo = ({ introduction }: TempleInfoProps) => { const contentRef = useRef(null); const { isAppeared, isExpanded, handleToggleExpand } = useExpandHook(contentRef); - let parsedIntroduction: StringKeyValue | null = null; - if (introduction) { - parsedIntroduction = JSON.parse(introduction); - } - return (
- {parsedIntroduction ? ( + {introduction ? (
{(() => { - const key = Object.keys(parsedIntroduction)[0]; - const value = parsedIntroduction[key]; return ( <> -

{key}

+ {/*

{key}

*/}

- {value} + {introduction}

); diff --git a/src/components/templeDetail/templePrice/TemplePrice.tsx b/src/components/templeDetail/templePrice/TemplePrice.tsx index cac8d174..9c856f1b 100644 --- a/src/components/templeDetail/templePrice/TemplePrice.tsx +++ b/src/components/templeDetail/templePrice/TemplePrice.tsx @@ -2,17 +2,18 @@ import DetailTitle from '@components/detailTitle/DetailTitle'; import * as styles from './templePrice.css'; interface TemplePriceProps { - templestayPrice?: string; + templestayPrice?: number; } const TemplePrice = ({ templestayPrice }: TemplePriceProps) => { + const hasPrice = templestayPrice !== null && templestayPrice !== undefined; return (
- {templestayPrice ? ( + {hasPrice ? (

성인(1인)

-

{templestayPrice}

+

{templestayPrice.toLocaleString()}원

) : (
diff --git a/src/components/templeDetail/templeTitle/TempleTitle.tsx b/src/components/templeDetail/templeTitle/TempleTitle.tsx index 04a725bb..2ac6ab1e 100644 --- a/src/components/templeDetail/templeTitle/TempleTitle.tsx +++ b/src/components/templeDetail/templeTitle/TempleTitle.tsx @@ -1,25 +1,18 @@ import * as styles from './templeTitle.css'; interface TempleTitleProps { - tag?: string; templeName: string; templestayName: string; } -const TempleTitle = ({ tag, templeName, templestayName }: TempleTitleProps) => { +const TempleTitle = ({ templeName, templestayName }: TempleTitleProps) => { return (
- {tag?.split(',').map((tagItem, index) => ( - - #{tagItem.trim()} - - ))} + {templeName}
-

- {templeName} {templestayName} -

+

{templestayName}

); diff --git a/src/components/templeDetail/templeTopbar/TempleTopbar.tsx b/src/components/templeDetail/templeTopbar/TempleTopbar.tsx index 8bff0b60..b6a1015d 100644 --- a/src/components/templeDetail/templeTopbar/TempleTopbar.tsx +++ b/src/components/templeDetail/templeTopbar/TempleTopbar.tsx @@ -1,14 +1,13 @@ import PageName from '@components/common/pageName/PageName'; interface TempleTopbarProps { - templeName: string; templestayName: string; } -const TempleTopbar = ({ templeName, templestayName }: TempleTopbarProps) => { +const TempleTopbar = ({ templestayName }: TempleTopbarProps) => { return (
- +
); };