1- import { useState } from 'react' ;
1+ import { useEffect , useState } from 'react' ;
22import { Link } from 'react-router-dom' ;
33
4+ import type { TNoticeItem } from '@/types/notice/notice' ;
5+
46import EditableInputBox from '@/components/common/EditableInputBox' ;
57import Navigator from '@/components/common/navigator' ;
68
7- const categories = [ '서비스 안내' , '시스템 안내' ] ;
9+ import { fetchNotices } from '@/api/notice/notice' ;
810
9- const dummyNotices = [
10- { category : '서비스 안내' , title : '서비스 점검 안내 (06월 20일 02:00~04:00)' , date : '2025.06.09' } ,
11- { category : '서비스 안내' , title : "신규 기능 '코스 저장하기' 오픈 안내" , date : '2025.06.09' } ,
12- {
13- category : '서비스 안내' ,
14- title : '데이트 추천 정확도 향상을 위한 업데이트 공지' ,
15- date : '2025.06.09' ,
16- content : `안녕하세요, WithTime 팀입니다.
17-
18- 항상 WithTime을 이용해주시는 모든 사용자 여러분께 진심으로 감사드립니다.
19- 보다 더 정확하고 만족스러운 데이트 코스를 추천해드리기 위해,아래와 같은 기능 개선 및 시스템 업데이트를 진행하였음을 알려드립니다.
20-
21- 🔧 주요 업데이트 내용
22- 1. 사용자 취향 기반 알고리즘 개선
23- 기존에는 간단한 지역 및 활동 선호도 중심으로 코스를 구성했다면,
24- 이번 업데이트부터는 시간대, 최근 행동 패턴, 선택 취소된 장소 이력 등
25- 더 정밀한 데이터를 분석하여 추천의 정확도를 높였습니다.
26-
27- 2. 상황별 추천 강화
28- - 비 오는 날에는 실내 데이트 중심으로
29- - 일정 시간이 짧을 경우, 이동 거리를 고려한 코스 구성
30- 이처럼 날씨, 이동 시간, 데이트 시간대를 함께 반영하도록 개선했습니다.
31-
32- 3. 실시간 트렌드 반영
33- 주요 지역별 인기 급상승 장소나 SNS 상에서 언급된 핫플레이스 정보를
34- 추천 코스에 반영하여, 최신 트렌드를 더 빠르게 만나보실 수 있습니다.
35-
36- 🎯 기대 효과
37- - "오늘 뭐하지?" 고민할 시간 없이 상황 맞춤형 코스를 자동 추천
38- - MBTI P 유형 사용자도 만족할 만큼 빠르고 간단한 코스 구성
39- - 더 이상 ‘나랑 안 맞는 장소 추천’으로 불편하지 않도록 개선
40-
41- 📅 적용 일시
42- - 2025년 6월 21일(금) 00:00부터 순차 적용 예정입니다.
43-
44- 이번 업데이트는 사용자 여러분의 피드백을 바탕으로 진행되었습니다.
45- 앞으로도 더 나은 서비스 제공을 위해 지속적으로 개선해나가겠습니다.
46- 사용 중 불편한 점이나 건의 사항이 있다면, 언제든지 고객센터 또는 [문의하기]를 통해 알려주세요.
47- 감사합니다.
48-
49- WithTime 팀 드림` ,
50- } ,
51- { category : '서비스 안내' , title : '비회원 기능 이용 제한 관련 안내' , date : '2025.06.09' } ,
52- { category : '서비스 안내' , title : '지도 기반 추천 기능 일시 중단 안내' , date : '2025.06.09' } ,
53- { category : '서비스 안내' , title : '지도 기반 추천 기능 일시 중단 안내' , date : '2025.06.09' } ,
54- { category : '서비스 안내' , title : '지도 기반 추천 기능 일시 중단 안내' , date : '2025.06.09' } ,
55- { category : '시스템 안내' , title : '일부 브라우저에서 발생하는 오류 관련 안내' , date : '2025.06.09' } ,
56- { category : '시스템 안내' , title : '추천 코스 반영 기준 변경 안내' , date : '2025.06.09' } ,
57- { category : '시스템 안내' , title : '회원가입 약관 일부 변경 안내' , date : '2025.06.09' } ,
58- ] ;
11+ const categories = [ '서비스 안내' , '시스템 안내' ] ;
5912
6013export default function Notice ( ) {
61- const [ searchValue , setSearchValue ] = useState ( '' ) ;
62- const [ activeCategory , setActiveCategory ] = useState ( categories [ 0 ] ) ;
14+ const [ searchValue , setSearchValue ] = useState ( '' ) ; //검색어 상태
15+ const [ activeCategory , setActiveCategory ] = useState ( categories [ 0 ] ) ; //선택된 카테고리
6316 const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
17+
18+ const [ noticeList , setNoticeList ] = useState < TNoticeItem [ ] > ( [ ] ) ; // 공지사항 리스트
19+ const [ totalPages , setTotalPages ] = useState ( 1 ) ;
20+ const [ loading , setLoading ] = useState ( false ) ;
21+ const [ error , setError ] = useState ( '' ) ;
22+
6423 const itemsPerPage = 10 ;
6524
66- // 필터링 + 페이징
67- const filteredNotices = dummyNotices . filter (
68- ( notice ) => notice . category === activeCategory && notice . title . toLowerCase ( ) . includes ( searchValue . toLowerCase ( ) ) ,
69- ) ;
70- const totalPages = Math . ceil ( filteredNotices . length / itemsPerPage ) ;
71- const paginatedNotices = filteredNotices . slice ( ( currentPage - 1 ) * itemsPerPage , currentPage * itemsPerPage ) ;
25+ // 백엔드에 넘길 카테고리 키 - 영어 변환
26+ const categoryKey = activeCategory === '서비스 안내' ? 'SERVICE' : 'SYSTEM' ;
27+
28+ // 컴포넌트 마운트 시, 카테고리/페이지 변경 시 -> API 호출
29+ useEffect ( ( ) => {
30+ const getNotices = async ( ) => {
31+ setLoading ( true ) ;
32+ try {
33+ // 공지사항 목록 요청
34+ const response = await fetchNotices ( {
35+ category : categoryKey ,
36+ page : currentPage - 1 ,
37+ size : itemsPerPage ,
38+ } ) ;
39+
40+ console . log ( 'API 응답:' , response ) ;
41+
42+ // 공지 목록과 페이지 수 설정 (빈 배열도 허용)
43+ setNoticeList ( response . result . noticeList ?? [ ] ) ;
44+ setTotalPages ( response . result . totalPages ?? 1 ) ;
45+ } catch ( err ) {
46+ // 오류 처리
47+ setError ( '공지사항을 불러오는 데 실패했습니다.' ) ;
48+ console . log ( err ) ;
49+ } finally {
50+ setLoading ( false ) ;
51+ }
52+ } ;
53+
54+ getNotices ( ) ; // 함수 실행
55+ } , [ activeCategory , currentPage ] ) ; // 의존성 배열 - 카테고리/페이지 변경 시마다 재호출
56+
57+ // 검색어 필터링 적용된 공지사항
58+ const filteredNotices = noticeList . filter ( ( notice ) => notice . title . toLowerCase ( ) . includes ( searchValue . toLowerCase ( ) ) ) ;
7259
7360 return (
7461 < div className = "max-w-[1000px] mx-auto px-4 py-10" >
@@ -102,15 +89,16 @@ export default function Notice() {
10289 ) ) }
10390 </ div >
10491
92+ { /* 공지 없을 때 메시지 */ }
93+ { ! loading && ! error && filteredNotices . length === 0 && < p className = "text-center text-default-gray-500" > 공지사항이 없습니다.</ p > }
94+
10595 { /* 공지 리스트 */ }
10696 < ul className = "divide-y divide-default-gray-400 mb-10" >
107- { paginatedNotices . map ( ( notice , index ) => (
108- < li key = { index } className = "py-4" >
109- < Link to = { `/notice/${ index } ` } state = { notice } className = "flex items-center justify-between" >
110- < div className = "flex items-center gap-4" >
111- < span className = "font-body2 text-default-gray-800" > { notice . title } </ span >
112- </ div >
113- < span className = "text-sm text-default-gray-500" > { notice . date } </ span >
97+ { filteredNotices . map ( ( notice ) => (
98+ < li key = { notice . noticeId } className = "py-4" >
99+ < Link to = { `/notice/${ notice . noticeId } ` } className = "flex items-center justify-between" >
100+ < span className = "font-body2 text-default-gray-800" > { notice . title } </ span >
101+ < span className = "text-sm text-default-gray-500" > { new Date ( notice . createdAt ) . toLocaleDateString ( ) } </ span >
114102 </ Link >
115103 </ li >
116104 ) ) }
@@ -122,7 +110,7 @@ export default function Notice() {
122110 current = { currentPage }
123111 end = { totalPages }
124112 onClick = { ( page ) => {
125- setCurrentPage ( page ) ;
113+ setCurrentPage ( page ) ; //페이지 변경
126114 } }
127115 />
128116 ) }
0 commit comments