Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

위키-술-검색기능-추가 #58

Merged
merged 8 commits into from
Nov 28, 2023
42 changes: 25 additions & 17 deletions client/src/app/wiki/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
"use client";
import { Paper, Container } from "@mui/material";
import WikiAppbar from "@/components/wiki/WikiAppbar";
import { ReactNode } from "react";
import { ReactNode, useState } from "react";
import WikiPageContext from "@/store/wiki/WikiPageContext";
import WikiSearchDrawer from "@/components/wiki/searchDrawer/WikiSearchDrawer";

const layout = ({ children }: { children: ReactNode }) => {
const [isSearching, setIsSearching] = useState(false);

return (
<Paper>
<WikiAppbar />
<Container sx={{ p: { xs: 0, sm: 4 } }} maxWidth={"lg"}>
<Paper
sx={{
display: "flex",
position: "relative",
flexDirection: "column",
gap: 2,
p: 2,
}}
>
{children}
</Paper>
</Container>
</Paper>
<WikiPageContext.Provider value={{ isSearching, setIsSearching }}>
<Paper>
<WikiAppbar />
<Container sx={{ p: { xs: 0, sm: 4 } }} maxWidth={"lg"}>
<Paper
sx={{
display: "flex",
position: "relative",
flexDirection: "column",
gap: 2,
p: 2,
}}
>
<WikiSearchDrawer />
{children}
</Paper>
</Container>
</Paper>
</WikiPageContext.Provider>
);
};

jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
4 changes: 2 additions & 2 deletions client/src/app/wiki/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AlcoholList from "@/components/wiki/AlcoholList";
import AlcoholPagination from "@/components/wiki/AlcoholPagination";
import WikiAlcoholSelector from "@/components/wiki/WikiAlcoholSelector";
import { Stack } from "@mui/material";
import SectionHeading from "@/components/SectionHeading";
Expand All @@ -14,7 +14,7 @@ const WikiPage = async () => {
subTitle={"투파이아들이 쓴 리뷰를 확인할 수 있어요!"}
/>
<WikiAlcoholSelector />
<AlcoholList />
<AlcoholPagination />

<SectionHeading title={"술 정보"} subTitle={"곧 출시 됩니다!"} />
<Stack alignItems="center">
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
72 changes: 72 additions & 0 deletions client/src/components/SearchHistory.tsx
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;
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 5 additions & 3 deletions client/src/components/newpost/SearchAlcoholInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const SearchAlcoholInput = ({ setAlcoholNo }: SearchAlcoholInputInterface) => {
const [selectedAlcohol, setSelectedAlcohol] =
useState<AlcoholDetailInterface>();


useEffect(() => {
setSearchKeyword(selectedAlcohol?.alcoholName ?? "");
setAlcoholNo(selectedAlcohol?.alcoholNo);
Expand All @@ -48,6 +47,9 @@ const SearchAlcoholInput = ({ setAlcoholNo }: SearchAlcoholInputInterface) => {
name="positionInfo"
size="small"
InputProps={{
sx: {
borderRadius: 12,
},
startAdornment: (
<InputAdornment position="start">
<AlcholeSearchIcon />
Expand Down Expand Up @@ -109,8 +111,8 @@ const SearchAlcoholInput = ({ setAlcoholNo }: SearchAlcoholInputInterface) => {
const WrapperStyle = {
width: "calc(100% - 32px)",
minHeight: "50px",
maxHeight:'142px',
overflowY:'auto',
maxHeight: "142px",
overflowY: "auto",
backgroundColor: "#F5F5F5",
border: "1px solid #E6E6E6",
borderRadius: 1.5,
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/search/SearchArea.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { Box, CircularProgress, Paper, TextField } from "@mui/material";
import React, { useState, useMemo, Suspense } from "react";
import { Paper, TextField } from "@mui/material";
import React, { useState, useMemo } from "react";
import PostCardList from "@/components/post/PostCardList";
import { AugmentedGetPostListResponse } from "@/queries/post/useGetPostListInfiniteQuery";
import useDebounce from "@/hooks/useDebounce";
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
53 changes: 21 additions & 32 deletions client/src/components/wiki/AlcoholList.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
"use client";
import AlcoholNameTag from "@/components/wiki/AlcoholNameTag";
import useGetAlcoholListQuery from "@/queries/alcohol/useGetAlcoholListQuery";
import { Box, Pagination, Skeleton, Stack } from "@mui/material";
import { AlcoholDetailInterface } from "@/types/alcohol/AlcoholInterface";
import { Typography } from "@mui/material";
import { memo } from "react";

const AlcoholList = () => {
const { data: alcohols } = useGetAlcoholListQuery();
const AlcoholList = ({
data: alcohols,
}: {
data: AlcoholDetailInterface[];
}) => {
return (
<Stack alignItems="center" gap={2}>
<Stack gap={1} alignItems="center" width={"100%"} height={"232px"}>
{alcohols ? (
alcohols.list.map((alcohol) => (
<AlcoholNameTag
key={alcohol.alcoholNo}
alcoholName={alcohol.alcoholName}
alcoholType={alcohol.alcoholType}
/>
))
) : (
<AlcoholListSkeleton />
)}
</Stack>
<Pagination count={alcohols?.totalCount} />
</Stack>
<>
{alcohols?.length > 0 ? (
alcohols.map((alcohol) => (
<AlcoholNameTag
key={alcohol.alcoholNo}
alcoholName={alcohol.alcoholName}
alcoholType={alcohol.alcoholType}
/>
))
) : (
<Typography textAlign="center">검색 결과가 없어요</Typography>
)}
</>
);
};
export default memo(AlcoholList);

const AlcoholListSkeleton = memo(() => {
return Array.from(new Array(5)).map(() => (
<Skeleton
variant="rectangular"
width={"100%"}
height={40}
sx={{ borderRadius: 2 }}
/>
));
});

export default AlcoholList;
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 31 additions & 0 deletions client/src/components/wiki/AlcoholListSkeleton.tsx
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;
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
24 changes: 24 additions & 0 deletions client/src/components/wiki/AlcoholPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";
import useGetAlcoholListQuery from "@/queries/alcohol/useGetAlcoholListQuery";
import AlcoholList from "@/components/wiki/AlcoholList";
import { Pagination, Stack } from "@mui/material";
import AlcoholListSkeleton from "@/components/wiki/AlcoholListSkeleton";

const AlcoholPagenation = () => {
const { data: alcohols, isSuccess } = useGetAlcoholListQuery();

return (
<Stack alignItems="center" gap={2}>
<Stack gap={1} alignItems="center" width={"100%"} height={"232px"}>
{isSuccess ? (
<AlcoholList data={alcohols?.list} />
) : (
<AlcoholListSkeleton disableTimer />
)}
</Stack>
<Pagination count={alcohols?.totalCount} />
</Stack>
);
};

export default AlcoholPagenation;
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
28 changes: 15 additions & 13 deletions client/src/components/wiki/WikiAlcoholSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,30 @@ import TraditionalAlcoholIcon from "@/assets/icons/Alcohol/TraditionalAlcoholIco
import SakeIcon from "@/assets/icons/Alcohol/SakeIcon.svg";

const WikiAlcoholSelector = () => {

const btnList =useMemo(()=>[
{ title: "포도주", iconComponent: <WineIcon /> },
{ title: "위스키", iconComponent: <WiskyIcon /> },
{ title: "증류주", iconComponent: <SpiritsIcon /> },
{ title: "우리술", iconComponent: <TraditionalAlcoholIcon /> },
{ title: "사케", iconComponent: <SakeIcon /> },
],[])
const btnList = useMemo(
() => [
{ title: "포도주", iconComponent: <WineIcon /> },
{ title: "위스키", iconComponent: <WiskyIcon /> },
{ title: "증류주", iconComponent: <SpiritsIcon /> },
{ title: "우리술", iconComponent: <TraditionalAlcoholIcon /> },
{ title: "사케", iconComponent: <SakeIcon /> },
],
[]
);

const [selectedAlcohol, setSelectedAlcohol] = useState(btnList[0].title);

const clickHandler = useCallback((title:string)=>{
setSelectedAlcohol(title)
},[])
const clickHandler = useCallback((title: string) => {
setSelectedAlcohol(title);
}, []);

return (
<Stack direction="row" justifyContent='center' gap={2}>
<Stack direction="row" justifyContent="center" gap={2}>
{btnList.map((btnInfo) => (
<WikiAlcoholSelectorBtn
key={btnInfo.title}
isSelected={selectedAlcohol === btnInfo.title}
onClick={()=>clickHandler(btnInfo.title)}
onClick={() => clickHandler(btnInfo.title)}
{...btnInfo}
/>
))}
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
9 changes: 6 additions & 3 deletions client/src/components/wiki/WikiAppbar.tsx
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);
jobkaeHenry marked this conversation as resolved.
Show resolved Hide resolved
Loading