- {soundOptions.map((option) => (
+
+ {soundOptions.map(option => (
toggleSection('관람 환경')}
>
-
- {environmentOptions.map((option) => (
+
+ {environmentOptions.map(option => (
+
+ {/* 적용 버튼 */}
+
);
diff --git a/src/pages/search/ReviewSearch.tsx b/src/pages/search/ReviewSearch.tsx
index c48b76f..1336a0a 100644
--- a/src/pages/search/ReviewSearch.tsx
+++ b/src/pages/search/ReviewSearch.tsx
@@ -1,59 +1,92 @@
-import { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import {SearchInput, Badge, BottomNavigation} from '@/components'
-const initialKeywords = [
- '뭔가검색했겠지...', '뭐가있지', '아무거나',
- '두줄은', '채워야되니까', '일단써보기'
-];
+import { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { SearchInput, Badge, BottomNavigation } from '@/components';
+import api from '@/api/api';
+
+type Keyword = {
+ content: string;
+};
export default function ReviewSearchPage() {
const [search, setSearch] = useState('');
- const [recentKeywords, setRecentKeywords] = useState(initialKeywords);
- const navigate = useNavigate();
+ const [recentKeywords, setRecentKeywords] = useState
([]);
+ const navigate = useNavigate();
- const handleRemove = (index: number) => {
- setRecentKeywords(prev => prev.filter((_, i) => i !== index));
- };
+ useEffect(() => {
+ const fetchRecentKeywords = async () => {
+ try {
+ const res = await api.get('/search');
+
+ if (res.data?.success && Array.isArray(res.data.data)) {
+ setRecentKeywords(res.data.data);
+ } else {
+ console.warn('유효하지 않은 검색어 응답:', res.data);
+ setRecentKeywords([]);
+ }
+ } catch (error) {
+ console.error('최근 검색어 조회 실패', error);
+ setRecentKeywords([]);
+ }
+ };
- const handleSearch = () => {
+ fetchRecentKeywords();
+ }, []);
+
+ const handleSearch = () => {
if (!search.trim()) {
alert('검색어를 입력해주세요.');
return;
}
- navigate(`/search/result?query=${search}`);
+
+ navigate(`/search/result?query=${encodeURIComponent(search)}`);
+ };
+
+ const handleRemove = async (index: number) => {
+ const keyword = recentKeywords[index].content;
+
+ try {
+ await api.delete('/search', {
+ params: { keyword },
+ });
+ setRecentKeywords((prev) => prev.filter((_, i) => i !== index));
+ } catch (error) {
+ console.error('검색어 삭제 실패', error);
+ }
};
- return (
-
+ return (
+
최근 검색어
- {recentKeywords.map((word, index) => (
-
handleRemove(index)}
- >
- {word}
-
- ))}
+ {recentKeywords.length > 0 ? (
+ recentKeywords.map((wordObj, index) => (
+
handleRemove(index)}
+ >
+ {wordObj.content}
+
+ ))
+ ) : (
+
최근 검색어가 없습니다.
+ )}
-
+
);
}
-
-
diff --git a/src/pages/search/ReviewSearchResult.tsx b/src/pages/search/ReviewSearchResult.tsx
index 5261628..5b6e33d 100644
--- a/src/pages/search/ReviewSearchResult.tsx
+++ b/src/pages/search/ReviewSearchResult.tsx
@@ -1,19 +1,74 @@
-import { useNavigate } from 'react-router-dom';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
+import { useSearchParams, useNavigate } from 'react-router-dom';
import { useFilter } from '@/contexts/FilterContext';
import { SearchInput, ReviewCard } from '@/components';
-import { FilterIcon } from '@/assets';
-import { mockMyReviews } from '@/__mocks/mockReviews';
+import { FilterIcon, ChevronIcon } from '@/assets';
+import api from '@/api/api';
+
+interface Review {
+ reviewId: number;
+ content: string;
+ rating: number;
+ movieTitle: string;
+ thumbnailUrl:string;
+ likeCount: number;
+ likedByUser: boolean;
+ hashTags: string[];
+}
export default function ReviewSearchResultPage() {
- const navigate = useNavigate();
- const [search, setSearch] = useState('');
+ const [searchParams, setSearchParams] = useSearchParams();
+ const [search, setSearch] = useState(searchParams.get('query') ?? '');
const { isFiltered } = useFilter();
+ const [results, setResults] = useState
([]);
+
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const fetchResults = async () => {
+ try {
+ const keyword = searchParams.get('query') || '';
+ const sort = searchParams.get('sort') || 'POPULAR';
+ const auditoriumId = searchParams.get('auditoriumId');
+
+ const res = await api.get('/search/reviews', {
+ params: {
+ keyword,
+ sort,
+ ...(auditoriumId ? { auditoriumId } : {}),
+ },
+ });
+
+ setResults(res.data);
+ } catch (error) {
+ console.error('검색 결과 조회 실패', error);
+ }
+ };
+
+ fetchResults();
+ }, [searchParams]);
+
+ const handleGoBack = () => {
+ navigate(-1);
+ };
return (
-
+
+
+
+
+ setSearchParams({ query: search })}
+ />
+
+
)}
+
- {mockMyReviews.map((result) => (
- {}}
- />
- ))}
+ {results.length > 0 ? (
+ results.map((result) => (
+ {}}
+ />
+ ))
+ ) : (
+ 검색 결과가 없습니다.
+ )}