diff --git a/src/components/SearchBar/index.tsx b/src/components/SearchBar/index.tsx index 28b53e1..256ab75 100644 --- a/src/components/SearchBar/index.tsx +++ b/src/components/SearchBar/index.tsx @@ -5,22 +5,23 @@ import SearchIcon from '@mui/icons-material/Search'; import CategoryChips from '../CategoryChips'; import { Item } from '../../models/item'; -import { getSearchAPICall } from '../../hooks/api/search/search'; -import { Categories, Seasons } from '../../data/enumLists'; +import { Categories, Seasons, Status } from '../../data/enumLists'; interface SearchBarProps { searchKeyWord: string; categorySelected: string[]; seasonSelected: string[]; + filterSelected: string[]; + handleSearch?: (a: string) => void; } export default function SearchBar(props: SearchBarProps) { const navigate = useNavigate(); - const emptyStrArray: string[] = []; - const [searchKeyWord, setSearchKeyWord] = useState(''); - const [categorySelected, setCategorySelected] = useState(emptyStrArray); - const [seasonSelected, setSeasonSelected] = useState(emptyStrArray); - const [filterSelected, setFilterSelected] = useState(emptyStrArray); + // const emptyStrArray: string[] = []; + const [searchKeyWord, setSearchKeyWord] = useState(props.searchKeyWord); + const [categorySelected, setCategorySelected] = useState(props.categorySelected); + const [seasonSelected, setSeasonSelected] = useState(props.seasonSelected); + const [filterSelected, setFilterSelected] = useState(props.filterSelected); const handleChange: React.ChangeEventHandler = (event) => { setSearchKeyWord(event.target.value); @@ -44,7 +45,7 @@ export default function SearchBar(props: SearchBarProps) { const handleSubmit: React.FormEventHandler = (e) => { e.preventDefault(); - const keyWordQueryString = `keyword=${encodeURIComponent(searchKeyWord)}`; + const keyWordQueryString = `text=${encodeURIComponent(searchKeyWord)}`; const categoryQueryString = categorySelected .map((category) => `category=${encodeURIComponent(category)}`) .join('&'); @@ -53,10 +54,9 @@ export default function SearchBar(props: SearchBarProps) { const queryString = [keyWordQueryString, categoryQueryString, seasonQueryString, filterQueryString] .filter((query) => !!query) .join('&'); - const url = `/search/?${queryString}`; - getSearchAPICall(url).then(() => { - navigate(url); - }); + const url = `/search?${queryString}`; + navigate(url); + if (props.handleSearch) props.handleSearch(url); }; const initCategories = Categories.map((value) => { @@ -75,7 +75,14 @@ export default function SearchBar(props: SearchBarProps) { const item: Item = { label: value, isSelected: false }; return item; }); - const initFilter: Item[] = [{ label: '대여 가능', isSelected: false }]; + const initFilter = Status.map((value) => { + if (props.filterSelected.includes(value)) { + const item: Item = { label: value, isSelected: true }; + return item; + } + const item: Item = { label: value, isSelected: false }; + return item; + }); return ( diff --git a/src/data/enumLists.ts b/src/data/enumLists.ts index 238eab4..d8ed2d2 100644 --- a/src/data/enumLists.ts +++ b/src/data/enumLists.ts @@ -2,3 +2,4 @@ import { Season, Category } from '../models/enum'; export const Seasons = Object.values(Season); export const Categories = Object.values(Category); +export const Status = ['대여가능', '대여중', '대여불가능']; diff --git a/src/hooks/api/search/search.ts b/src/hooks/api/search/search.ts index b14a7a2..2e47e6c 100644 --- a/src/hooks/api/search/search.ts +++ b/src/hooks/api/search/search.ts @@ -3,12 +3,30 @@ import axios, { AxiosError } from 'axios'; import { SEARCH_MESSAGE } from '../../../data/messages'; +interface Owner { + id?: number; + nickname?: string; + location?: string; +} +interface SearchClothesRes { + id?: number; + closetId: number; + category?: string; + season?: string; + status: string; + isOpen: boolean; + name: string; + tag?: string; + image?: string; + owner: Owner; + isWished: boolean; +} + export async function getSearchAPICall(url: string) { try { - const response = await axios.get(`${process.env.REACT_APP_API_URL}${url}`); + const response = await axios.get(`${process.env.REACT_APP_API_URL}${url}`); if (response.status === 200) { - const { searchResult } = response.data; - sessionStorage.setItem('searchResult', searchResult); + return response.data; } } catch (err) { if (err instanceof AxiosError) { @@ -17,4 +35,5 @@ export async function getSearchAPICall(url: string) { enqueueSnackbar(SEARCH_MESSAGE.SEARCH_FAIL, { variant: 'error' }); } } + return null; } diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index b1a3ea3..62334b8 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -33,7 +33,7 @@ export function MainPage() { 스타일을 공유하고 다른 사람의 스타일을 빌려보세요 - + {!!applies && applies.length > 0 && ( diff --git a/src/pages/Search/index.tsx b/src/pages/Search/index.tsx new file mode 100644 index 0000000..4bd9f4c --- /dev/null +++ b/src/pages/Search/index.tsx @@ -0,0 +1,93 @@ +import { useSearchParams } from 'react-router-dom'; +import { useState } from 'react'; +import { Box, Typography } from '@mui/material'; + +import { getSearchAPICall } from '../../hooks/api/search/search'; +import SearchBar from '../../components/SearchBar'; +import ClothesPreviewCard from '../../components/ClothesPreviewCard'; + +interface Owner { + id?: number; + nickname?: string; + location?: string; +} +interface SearchClothesRes { + id?: number; + closetId: number; + category?: string; + season?: string; + status: string; + isOpen: boolean; + name: string; + tag?: string; + image?: string; + owner: Owner; + isWished: boolean; +} + +export function SearchPage() { + const [searchParams] = useSearchParams(); + // const location = useLocation(); + // const queryString = location.search; + // const url = `/search${queryString}`; + + const searchKeyWord = searchParams.get('text') || ''; + const categorySelected = searchParams.getAll('category'); + const seasonSelected = searchParams.getAll('season'); + const filterSelected = searchParams.getAll('status'); + + const defaultResult: JSX.Element = ( + + 검색 결과가 없어요 + + ); + + const emptySearchArray: SearchClothesRes[] = []; + const [searchedClothes, setSearchedClothes] = useState(emptySearchArray); + const handleSearch = async (query: string) => { + try { + const result = await getSearchAPICall(query); + if (result) { + setSearchedClothes(result); + } else setSearchedClothes(emptySearchArray); + } catch (error) { + // + } + }; + // handleSearch(url); + + const clothesCards = searchedClothes + ? searchedClothes.map((clothes: SearchClothesRes) => { + const { id, name, status, owner, isWished } = clothes; + return ( + + + + ); + }) + : []; + + return ( + <> + + + + {clothesCards && clothesCards.length > 0 ? clothesCards : defaultResult} + + ); +} diff --git a/src/route/index.tsx b/src/route/index.tsx index a4124e3..eacabbd 100644 --- a/src/route/index.tsx +++ b/src/route/index.tsx @@ -1,5 +1,6 @@ import { Route, Routes } from 'react-router-dom'; +import { SearchPage } from '../pages/Search'; import { RegisterPage } from '../pages/Register'; import { ProfilePage } from '../pages/Profile'; import MyPage from '../pages/Mypage'; @@ -20,6 +21,7 @@ export function RouteComponent() { } /> } /> } /> + } /> ); }