1- import { useState } from 'react' ;
2- import { useSearchParams } from 'react-router-dom' ;
1+ import { useEffect , useState } from 'react' ;
2+ import { useSearchParams , useNavigate } from 'react-router-dom' ;
3+ import dayjs from 'dayjs' ;
4+
5+ import { useToast } from "@/hooks/useToast.js" ;
6+
7+ import scrapService from "@/services/scrap/scrapService.js" ;
8+
9+ import NoScrapIcon from "@/assets/icon/scrap/no-scrap.svg" ;
310
4- import GroupTab from '@/components/group/GroupTab' ;
511import PublicPostCard from '@/components/group/PublicPostCard' ;
6- import PrivatePostCard from '@/components/group/PrivatePostCard' ;
712import Pagination from "@/components/common/Pagination" ;
813import SearchBar from "@/components/common/SearchBar" ;
914import SearchButton from "@/components/common/SearchButton" ;
1015import Select from '@/components/common/Select' ;
16+ import NeedLoginToGuest from "@/components/modal/NeedLoginToGuest.jsx" ;
1117
1218const GROUP_PARAMS = 'group' ;
1319
14- const publicMemories = [
15- { author : "달봉이아들" , visibility : "공개" , title : '추억 글 제목' , location : '인천 앞바다' , date : '24.01.19' , tags : [ "태그" , "길면" , "두줄" , "낚시" , "인천" ] , likes : 120 , comments : 8 } ,
16- { author : "달봉이아들" , visibility : "공개" , title : '추억 글 제목' , location : '인천 앞바다' , date : '24.02.01' , tags : [ "여행" , "추억" , "가족" , "사진" ] , likes : 98 , comments : 12 } ,
17- ] ;
18-
19- const privateMemories = [
20- { author : "달봉이아들" , visibility : "비공개" , title : '추억 글 제목' , date : '24.01.19' , likes : 120 , comments : 8 } ,
21- { author : "달봉이아들" , visibility : "비공개" , title : '추억 글 제목' , date : '24.02.01' , likes : 98 , comments : 12 } ,
22- ] ;
2320
2421const options = [
2522 { label : "최신순" , value : "latest" } ,
@@ -30,13 +27,57 @@ const options = [
3027
3128
3229export default function Scrap ( ) {
30+ const [ isLogin , setIsLogin ] = useState ( false ) ;
3331 const [ searchTerm , setSearchTerm ] = useState ( '' ) ;
3432 const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
3533 const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
3634 const [ sortBy , setSortBy ] = useState ( searchParams . get ( "sortBy" ) || "mostLiked" ) ;
37-
35+ const [ totalPages , setTotalPages ] = useState ( 10 ) ;
36+ const [ memories , setMemories ] = useState ( [ ] ) ;
3837 const tabName = searchParams . get ( GROUP_PARAMS ) || 'Public' ;
39- const totalPages = 10 ;
38+
39+ const navigate = useNavigate ( ) ;
40+ const addToast = useToast ( ) ;
41+
42+ /** 로그인 유무 판단 **/
43+ useEffect ( ( ) => {
44+ const token = localStorage . getItem ( "accessToken" ) ;
45+
46+ if ( ! token ) {
47+ setIsLogin ( false ) ;
48+ } else {
49+ setIsLogin ( true ) ;
50+ }
51+ } , [ ] ) ;
52+
53+ /** 스크랩한 추억글 목록 불러오기 **/
54+ useEffect ( ( ) => {
55+ const fetchScrapList = async ( ) => {
56+ try {
57+ const response = await scrapService . getScrapList ( {
58+ sortBy,
59+ keyword : searchTerm ,
60+ page : currentPage ,
61+ } ) ;
62+
63+ if ( response . status === "success" ) {
64+ setMemories ( response . data . data || [ ] ) ;
65+ setTotalPages ( response . data . totalPages ) ;
66+ } else {
67+ throw new Error ( "스크랩한 추억글 조회 실패" ) ;
68+ }
69+
70+ } catch {
71+ addToast ( "스크랩한 추억글 조회에 실패했습니다." ) ;
72+ }
73+ }
74+
75+ fetchScrapList ( ) ;
76+ } , [ searchTerm , sortBy , currentPage ] ) ;
77+
78+ useEffect ( ( ) => {
79+ setSortBy ( searchParams . get ( "sortBy" ) || "mostLiked" ) ;
80+ } , [ searchParams ] ) ;
4081
4182 const handleSearch = ( ) => {
4283 console . log ( "검색어:" , searchTerm ) ;
@@ -53,14 +94,21 @@ export default function Scrap () {
5394 }
5495 } ;
5596
97+ const handleLoginModal = ( state ) => {
98+ if ( state === "register" ) {
99+ navigate ( "/login" ) ;
100+ } else {
101+ navigate ( "/" ) ;
102+ }
103+ }
104+
56105 return (
57106 < div className = "max-w-[95%] h-full pt-3 pb-7" >
58107 < div className = "flex items-center mb-2" >
59108 < span className = "text-darkViolet text-2xl font-semibold" > 스크랩</ span >
60109 < span className = "text-black text-2xl font-semibold" > 한 추억 글 목록</ span >
61110 </ div >
62111
63- < GroupTab />
64112 < div
65113 className = "flex mt-4 items-center gap-5"
66114 style = { { flexBasis : '60%' } }
@@ -83,32 +131,45 @@ export default function Scrap () {
83131 </ div >
84132
85133 < div className = "w-full mt-3 py-3" >
86- < div className = "mt-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6" >
87- { tabName === "Public"
88- ? publicMemories . map ( ( memory , index ) =>
89- < PublicPostCard
90- key = { index }
91- id = { index + 1 }
92- groupId = { 1 }
93- { ...memory }
94- /> )
95- : privateMemories . map ( ( memory , index ) =>
96- < PrivatePostCard
97- key = { index }
98- id = { index + 1 }
99- groupId = { 1 }
100- { ...memory }
101- /> ) }
102- </ div >
134+ { memories . length > 0 ? (
135+ < div className = "mt-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6" >
136+ { memories . map ( ( memory ) =>
137+ < PublicPostCard
138+ key = { memory . postId }
139+ id = { memory . postId }
140+ groupId = { memory . post ?. groupId }
141+ title = { memory . post ?. title || "제목 없음" }
142+ tag = { memory . post ?. tag . length ? memory . post ?. tag : [ "태그 없음" ] }
143+ moment = { dayjs ( memory . post ?. moment ) . format ( 'YYYY-MM-DD' ) }
144+ author = { memory . post ?. nickname || "알 수 없음" }
145+ imageUrl = { memory . post ?. imageUrl ? `https://${ memory . post . imageUrl } ` : null }
146+ location = { memory . post ?. location || "장소 정보 없음" }
147+ likeCount = { memory . post ?. likeCount ?? 0 }
148+ commentCount = { memory . post ?. commentCount ?? 0 }
149+ /> ) }
150+ </ div >
151+ ) :(
152+ < div className = "bg-white min-w-[85vw] h-[80vh] max-h-[80vh] w-full rounded-[30px]" >
153+ < div className = "flex flex-col items-center justify-center h-full text-center text-gray-500" >
154+ < img src = { NoScrapIcon } alt = "No Group" className = "w-30 h-30 mb-4" />
155+ < p className = "text-lg font-semibold" > 스크랩된 추억글이 없습니다!</ p >
156+ < p className = "text-sm text-gray-400" > 가입된 그룹에서 마음에 드는 추억글을 스크랩 해보세요!</ p >
157+ < button onClick = { ( ) => navigate ( "/group" ) } className = "mt-4 px-5 py-2 bg-normalViolet hover:bg-normalViolet-hover active:bg-normalViolet-active text-white text-sm font-medium rounded-md" >
158+ 그룹 살펴보기
159+ </ button >
160+ </ div >
161+ </ div >
162+ ) }
103163 </ div >
104164
105- < div className = "p-4" >
165+ { memories . length > 0 && < div className = "p-4" >
106166 < Pagination
107- currentPage = { currentPage }
108- totalPages = { totalPages }
109- onPageChange = { handlePageChange }
167+ currentPage = { currentPage }
168+ totalPages = { totalPages }
169+ onPageChange = { handlePageChange }
110170 />
111- </ div >
171+ </ div > }
172+ { ! isLogin && < NeedLoginToGuest onClick = { handleLoginModal } /> }
112173 </ div >
113174 ) ;
114175}
0 commit comments