11"use client" ;
22
3- import { useRouter } from "next/navigation" ;
3+ import { useQuery } from "@tanstack/react-query" ;
4+ import { useParams , useRouter } from "next/navigation" ;
45
56import ExpandableText from "@/components/archive-detail/ExpandableText" ;
67import SizeText from "@/components/archive-detail/SizeText" ;
78import RegionText from "@/components/archive-detail/RegionText" ;
89import ImageSwiper from "@/components/archive-detail/ImageSwiper" ;
910import NicknameCard from "@/components/archive-detail/NicknameCard" ;
11+ import { getArtworkDetail } from "@/services/artworks" ;
12+
13+ function formatDate ( date : string | null ) {
14+ if ( ! date ) return "-" ;
15+ return date . replaceAll ( "-" , "." ) ;
16+ }
1017
1118export default function ArtDetailPage ( ) {
1219 const router = useRouter ( ) ;
20+ const params = useParams < { id : string } > ( ) ;
21+ const artworkId = params . id ;
1322
14- // 임시 이미지 배열
15- const artworkImages = [
16- "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe" ,
17- "https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5" ,
18- "https://images.unsplash.com/photo-1541701494587-cb58502866ab" ,
19- ] ;
23+ const query = useQuery ( {
24+ queryKey : [ "artwork-detail" , artworkId ] ,
25+ queryFn : ( { signal } ) => getArtworkDetail ( artworkId , signal ) ,
26+ enabled : Boolean ( artworkId ) ,
27+ } ) ;
2028
21- // 임시 텍스트
22- const texts =
23- "대법원장과 대법관이 아닌 법관은 대법관회의의 동의를 얻어 대법원장이 임명한다. 재산권의 행사는 공공복리에 적합하도록 하여야 한다. 국가원로자문회의의 의장은 직전대통령이 된다. 다만, 직전대통령이 없을 때에는 대통령이 지명한다. 대한민국은 통일을 지향하며, 자유민주적 기본질서에 입각한 평화적 통일 정책을 수립하고 이를 추진한다. 국가는 농지에 관하여 경자유전의 원칙이 달성될 수 있도록 노력하여야 하며, 농지의 소작제도는 금지된다. 대법원에 대법관을 둔다. 다만, 법률이 정하는 바에 의하여 대법관이 아닌 법관을 둘 수 있다. 국가는 모성의 보호를 위하여 노력하여야 한다. 제안된 헌법개정안은 대통령이 20일 이상의 기간 이를 공고하여야 한다." ;
24- // 임시 지역 데이터
25- const regions = [ "강남구" , "강동구" , "강서구" , "관악구" , "송파구" ] ;
29+ const artwork = query . data ;
30+ const artworkImages = artwork ?. imageUrls ?. filter ( Boolean ) ?? [ ] ;
2631
2732 return (
2833 < div className = "min-h-screen bg-white pb-32" >
29- { /* 헤더 */ }
3034 < header className = "fixed top-0 right-0 left-0 z-50 flex h-15 w-full min-w-[320px] px-4" >
3135 < div className = "flex items-center" >
3236 < button
@@ -39,51 +43,72 @@ export default function ArtDetailPage() {
3943 </ div >
4044 </ header >
4145
42- { /* 이미지 슬라이더 컨테이너 */ }
43- < ImageSwiper images = { artworkImages } />
44- { /* 컨텐츠 영역 */ }
45- < div className = "text-text-primary flex flex-col gap-1.5 px-5 py-6" >
46- < div className = "text-caption bg-object-secondary-light h-6 w-14 rounded-sm px-1.5 py-1 font-medium" >
47- 작품 유형
46+ { query . isLoading ? (
47+ < div className = "flex min-h-screen items-center justify-center px-5 text-sm text-gray-500" >
48+ 불러오는 중...
49+ </ div >
50+ ) : query . isError || ! artwork ? (
51+ < div className = "flex min-h-screen flex-col items-center justify-center gap-4 px-5 text-center" >
52+ < p className = "text-body-2 text-text-secondary" > 작품 정보를 불러오지 못했습니다.</ p >
53+ < button
54+ onClick = { ( ) => query . refetch ( ) }
55+ className = "border-border-primary text-body-2 rounded-lg border px-4 py-2"
56+ >
57+ 다시 시도
58+ </ button >
4859 </ div >
49- < div className = "text-title-3 font-semibold" > 작품 이름</ div >
60+ ) : (
61+ < >
62+ < ImageSwiper images = { artworkImages } altPrefix = "작품 이미지" />
63+ < div className = "text-text-primary flex flex-col gap-1.5 px-5 py-6" >
64+ < div className = "text-caption bg-object-secondary-light h-6 w-fit min-w-14 rounded-sm px-1.5 py-1 font-medium" >
65+ { artwork . artworkType }
66+ </ div >
67+ < div className = "text-title-3 font-semibold" > { artwork . title } </ div >
5068
51- { /* 희망 전시 지역 아코디언 */ }
52- < RegionText regions = { regions } />
69+ < RegionText regions = { artwork . availableRegions } />
5370
54- { /* 크리에이터 닉네임 영역 */ }
55- < NicknameCard nickname = "크리에이터 닉네임" />
56- </ div >
71+ < NicknameCard nickname = { `크리에이터 ${ artwork . ownerId } ` } />
72+ </ div >
5773
58- { /* 구분선 */ }
59- < div className = "bg-bg-primary-darker h-1" />
74+ < div className = "bg-bg-primary-darker h-1" />
6075
61- < div className = "text-text-primary flex flex-col gap-8 px-5 py-6" >
62- { /* 작품 제작일 */ }
63- < div className = "text-text-primary flex flex-col gap-2" >
64- < div className = "text-heading-2 font-medium" > 작품 제작일</ div >
65- < p className = "text-body-2 font-regular" > 2026.01.02</ p >
66- </ div >
76+ < div className = "text-text-primary flex flex-col gap-8 px-5 py-6" >
77+ < div className = "text-text-primary flex flex-col gap-2" >
78+ < div className = "text-heading-2 font-medium" > 작품 제작일</ div >
79+ < p className = "text-body-2 font-regular" > { formatDate ( artwork . createdDate ) } </ p >
80+ </ div >
81+
82+ < SizeText
83+ title = "필요한 전시 공간 사이즈"
84+ width = { artwork . widthCm ?? undefined }
85+ height = { artwork . heightCm ?? undefined }
86+ depth = { artwork . depthCm ?? undefined }
87+ />
88+
89+ < ExpandableText
90+ title = "작품 상세"
91+ content = { artwork . description ?. trim ( ) || "등록된 작품 상세 설명이 없습니다." }
92+ maxLines = { 4 }
93+ />
94+
95+ < ExpandableText
96+ title = "주의사항"
97+ content = { artwork . caution ?. trim ( ) || "등록된 주의사항이 없습니다." }
98+ maxLines = { 4 }
99+ />
100+ </ div >
67101
68- { /* 필요한 전시 공간 사이즈 */ }
69- < SizeText title = "필요한 전시 공간 사이즈" />
70-
71- { /* 작품 상세 */ }
72- < ExpandableText title = "작품 상세" content = { texts } maxLines = { 4 } />
73-
74- { /* 주의사항 */ }
75- < ExpandableText title = "주의사항" content = { texts } maxLines = { 4 } />
76- </ div >
77-
78- { /* 하단 고정 전시 문의하기 버튼 */ }
79- < div className = "border-border-primary bg-bg-primary fixed right-0 bottom-0 left-0 z-50 border-t px-5 pt-3 pb-9" >
80- < button
81- onClick = { ( ) => alert ( "전시 문의 프로세스 시작" ) }
82- className = "bg-object-primary text-body-1 text-text-invert flex h-12.5 w-full items-center justify-center rounded-lg font-medium"
83- >
84- 전시 문의하기
85- </ button >
86- </ div >
102+ < div className = "border-border-primary bg-bg-primary fixed right-0 bottom-0 left-0 z-50 border-t px-5 pt-3 pb-9" >
103+ < button
104+ onClick = { ( ) => alert ( "전시 문의 프로세스 시작" ) }
105+ className = "bg-object-primary text-body-1 text-text-invert flex h-12.5 w-full items-center justify-center rounded-lg font-medium"
106+ >
107+ 전시 문의하기
108+ </ button >
109+ </ div >
110+ </ >
111+ ) }
87112 </ div >
88113 ) ;
89114}
0 commit comments