-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2557610
commit 3859f00
Showing
7 changed files
with
253 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { Button, Stack, StackProps, Typography } from "@mui/material"; | ||
import { useCallback, useState } from "react"; | ||
import XIcon from "@/assets/icons/XIcon.svg"; | ||
|
||
interface SearchHistoryProps extends Omit<StackProps, "onClick"> { | ||
storageKey: string; | ||
onClick: () => void; | ||
} | ||
|
||
const SearchHistory = ({ storageKey, onClick }: SearchHistoryProps) => { | ||
const getItems = useCallback(() => { | ||
return JSON.parse(localStorage.getItem(storageKey) ?? "[]") as string[]; | ||
}, [storageKey]); | ||
|
||
const [searchHistory, setSearchHistory] = useState<string[]>(getItems()); | ||
|
||
const removeAll = useCallback(() => { | ||
localStorage.setItem(storageKey, "[]"); | ||
setSearchHistory(getItems()); | ||
}, [storageKey]); | ||
|
||
const removeByKeyword = useCallback( | ||
(keyword: string) => { | ||
const filteredHistory = searchHistory.filter( | ||
(prevKeyword) => prevKeyword !== keyword | ||
); | ||
localStorage.setItem(storageKey, JSON.stringify(filteredHistory)); | ||
setSearchHistory(getItems()); | ||
}, | ||
[storageKey] | ||
); | ||
|
||
return searchHistory.length > 0 ? ( | ||
<> | ||
<Stack direction="row" justifyContent="space-between"> | ||
<Typography variant="subtitle1" fontWeight="bold"> | ||
최근 검색어 | ||
</Typography> | ||
<Button onClick={removeAll} variant="text" sx={{ fontWeight: "bold" }}> | ||
전체 삭제 | ||
</Button> | ||
</Stack> | ||
<Stack> | ||
{searchHistory.map((keyword) => ( | ||
<Stack | ||
key={keyword} | ||
onClick={onClick} | ||
direction="row" | ||
justifyContent="space-between" | ||
alignItems="center" | ||
> | ||
<Typography variant="subtitle2">{keyword}</Typography> | ||
<Button | ||
onClick={(e) => { | ||
e.stopPropagation(); | ||
removeByKeyword(keyword); | ||
}} | ||
variant="text" | ||
sx={{ justifyContent: "end" }} | ||
> | ||
<XIcon /> | ||
</Button> | ||
</Stack> | ||
))} | ||
</Stack> | ||
</> | ||
) : ( | ||
<></> | ||
); | ||
}; | ||
|
||
export default SearchHistory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { memo } from "react"; | ||
import { Skeleton } from "@mui/material"; | ||
|
||
import useSkeletonTimer from "@/hooks/useSkeletonTimer"; | ||
|
||
interface AlcoholListSkeletonInterface { | ||
size?: number; | ||
disableTimer?: boolean; | ||
} | ||
|
||
const AlcoholListSkeleton = memo( | ||
({ size = 5, disableTimer }: AlcoholListSkeletonInterface) => { | ||
const isOver200ms = !!disableTimer ? true : useSkeletonTimer(); | ||
|
||
return isOver200ms ? ( | ||
Array.from(new Array(size)).map((_e, i) => ( | ||
<Skeleton | ||
key={i} | ||
variant="rectangular" | ||
width={"100%"} | ||
height={40} | ||
sx={{ borderRadius: 2 }} | ||
/> | ||
)) | ||
) : ( | ||
<></> | ||
); | ||
} | ||
); | ||
|
||
export default AlcoholListSkeleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,18 @@ | ||
'use client' | ||
"use client"; | ||
import CustomAppbar from "@/components/CustomAppbar"; | ||
import SearchIcon from "@/assets/icons/SearchIcon.svg"; | ||
import { memo, useContext } from "react"; | ||
import WikiPageContext from "@/store/wiki/WikiPageContext"; | ||
|
||
const WikiAppbar = () => { | ||
const { setIsSearching } = useContext(WikiPageContext); | ||
return ( | ||
<CustomAppbar | ||
title="술백과" | ||
buttonComponent={<SearchIcon />} | ||
onClickButton={() => console.log("눌림")} | ||
onClickButton={() => setIsSearching(true)} | ||
/> | ||
); | ||
}; | ||
|
||
export default WikiAppbar; | ||
export default memo(WikiAppbar); |
47 changes: 47 additions & 0 deletions
47
client/src/components/wiki/searchDrawer/WikiSearchDrawer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { SwipeableDrawer, Stack, styled, Box } from "@mui/material"; | ||
import { useContext } from "react"; | ||
import WikiPageContext from "@/store/wiki/WikiPageContext"; | ||
import WikiSerachArea from "@/components/wiki/searchDrawer/WikiSerachArea"; | ||
|
||
const WikiSearchDrawer = () => { | ||
const { isSearching, setIsSearching } = useContext(WikiPageContext); | ||
|
||
const pullerBleed = 24; | ||
return ( | ||
<SwipeableDrawer | ||
open={isSearching} | ||
onOpen={() => setIsSearching(true)} | ||
onClose={() => setIsSearching(false)} | ||
anchor="bottom" | ||
disableSwipeToOpen | ||
PaperProps={{ | ||
sx: { | ||
p: 2, | ||
borderTopLeftRadius: pullerBleed, | ||
borderTopRightRadius: pullerBleed, | ||
overFlow: "hidden", | ||
}, | ||
}} | ||
ModalProps={{ | ||
keepMounted: false, | ||
}} | ||
> | ||
<Puller /> | ||
<Stack gap={2} pt={`${pullerBleed + 8}px`}> | ||
<WikiSerachArea /> | ||
</Stack> | ||
</SwipeableDrawer> | ||
); | ||
}; | ||
|
||
export default WikiSearchDrawer; | ||
|
||
const Puller = styled(Box)(() => ({ | ||
width: 56, | ||
height: 4, | ||
backgroundColor: "#F6EAFB", | ||
borderRadius: 3, | ||
position: "absolute", | ||
top: 8, | ||
left: "calc(50% - 28px)", | ||
})); |
59 changes: 59 additions & 0 deletions
59
client/src/components/wiki/searchDrawer/WikiSerachArea.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { useEffect, useRef, useState } from "react"; | ||
import useDebounce from "@/hooks/useDebounce"; | ||
import InputSearchIcon from "@/assets/icons/InputSearchIcon.svg"; | ||
import { Stack, TextField } from "@mui/material"; | ||
import useGetAlcoholListQuery from "@/queries/alcohol/useGetAlcoholListQuery"; | ||
import AlcoholList from "@/components/wiki/AlcoholList"; | ||
import AlcoholListSkeleton from "../AlcoholListSkeleton"; | ||
import SearchHistory from "@/components/SearchHistory"; | ||
import { ALCOHOL_SEARCH_HISTORY } from "@/const/localstorageKey"; | ||
|
||
const WikiSerachArea = () => { | ||
const [searchKeyword, setSearchKeyword] = useState(""); | ||
const debouncedValue = useDebounce(searchKeyword, 300); | ||
const { data: alcohols, isSuccess } = useGetAlcoholListQuery(debouncedValue); | ||
const inputRef = useRef<HTMLInputElement>(null); | ||
|
||
useEffect(() => { | ||
inputRef.current?.focus(); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<TextField | ||
label="검색어를 입력해주세요" | ||
autoFocus | ||
autoComplete="off" | ||
value={searchKeyword} | ||
inputRef={inputRef} | ||
onChange={({ target }) => setSearchKeyword(target.value)} | ||
InputProps={{ | ||
endAdornment: <InputSearchIcon />, | ||
sx: { | ||
borderRadius: "12px", | ||
}, | ||
}} | ||
/> | ||
<Stack gap={1} height={"232px"}> | ||
{searchKeyword ? ( | ||
// 입력중인 경우 | ||
<> | ||
{isSuccess ? ( | ||
<AlcoholList data={alcohols.list} /> | ||
) : ( | ||
<AlcoholListSkeleton /> | ||
)} | ||
</> | ||
) : ( | ||
// 입력이 없는경우 검색기록 표출 | ||
<SearchHistory | ||
onClick={() => console.log("눌림")} | ||
storageKey={ALCOHOL_SEARCH_HISTORY} | ||
/> | ||
)} | ||
</Stack> | ||
</> | ||
); | ||
}; | ||
|
||
export default WikiSerachArea; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Dispatch, SetStateAction, createContext } from "react"; | ||
|
||
interface WikiPageContextInterface { | ||
isSearching: boolean; | ||
setIsSearching: Dispatch<SetStateAction<boolean>>; | ||
} | ||
|
||
const WikiPageContext = createContext<WikiPageContextInterface>({ | ||
isSearching: true, | ||
setIsSearching: () => {}, | ||
}); | ||
|
||
export default WikiPageContext; |