From de1bd6a963058d96a750af1abd51ded8af0fe2c6 Mon Sep 17 00:00:00 2001 From: ldh3907 Date: Mon, 25 Apr 2022 22:19:07 +0900 Subject: [PATCH] 2022-04-25 --- components/common/PageTemplate.tsx | 2 +- components/header/style.ts | 2 +- components/main/Main.tsx | 2 + .../main/mainCardList/mainCard/MainCard.tsx | 30 ++++++++++-- .../main/mainCardList/mainCard/style.ts | 15 ++++++ .../MainFavoriteCardList.tsx | 12 +++++ components/main/mainFavoriteCardList/style.ts | 9 ++++ components/main/style.ts | 3 +- constants/localStorage.contants.ts | 1 + constants/product.constants.ts | 2 +- hooks/main/useFavorites.ts | 47 +++++++++++++++++++ store/main/main.store.ts | 11 +++++ 12 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 components/main/mainFavoriteCardList/MainFavoriteCardList.tsx create mode 100644 components/main/mainFavoriteCardList/style.ts create mode 100644 constants/localStorage.contants.ts create mode 100644 hooks/main/useFavorites.ts create mode 100644 store/main/main.store.ts diff --git a/components/common/PageTemplate.tsx b/components/common/PageTemplate.tsx index f1e02fd..36ac0fc 100644 --- a/components/common/PageTemplate.tsx +++ b/components/common/PageTemplate.tsx @@ -21,7 +21,7 @@ const TemplateContainer = styled.div` `; const TemplateChildrenWrap = styled.div` - width: 1130px; + width: 1052px; min-height: calc(100vh - 74px); height: auto; display: flex; diff --git a/components/header/style.ts b/components/header/style.ts index be1ceb8..4f81b66 100644 --- a/components/header/style.ts +++ b/components/header/style.ts @@ -9,7 +9,7 @@ export const HeaderContainer = styled.div` `; export const HeaderWrap = styled.div` - width: 1130px; + width: 1052px; height: 100%; display: flex; align-items: center; diff --git a/components/main/Main.tsx b/components/main/Main.tsx index 3742590..bf7a826 100644 --- a/components/main/Main.tsx +++ b/components/main/Main.tsx @@ -1,5 +1,6 @@ import { Coin } from "../../types/common/common.type"; import MainCardList from "./mainCardList/MainCardList"; +import MainFavoriteCardList from "./mainFavoriteCardList/MainFavoriteCardList"; import { MainContainer } from "./style"; type Props = { @@ -10,6 +11,7 @@ const Main = ({ data }: Props) => { return ( + ); }; diff --git a/components/main/mainCardList/mainCard/MainCard.tsx b/components/main/mainCardList/mainCard/MainCard.tsx index 421bb68..d4f4772 100644 --- a/components/main/mainCardList/mainCard/MainCard.tsx +++ b/components/main/mainCardList/mainCard/MainCard.tsx @@ -2,21 +2,45 @@ import { Coin } from "../../../../types/common/common.type"; import { MainCardContainer, MainCardDetailButton, + MainCardFavIcon, MainCardTitle, + MainCardTitleWrap, } from "./style"; import { FiArrowRight } from "@react-icons/all-files/fi/FiArrowRight"; +import { FaRegStar } from "@react-icons/all-files/fa/FaRegStar"; +import { FaStar } from "@react-icons/all-files/fa/FaStar"; import Link from "next/link"; +import useFavorites from "../../../../hooks/main/useFavorites"; +import { useRecoilValue } from "recoil"; +import { mainFavoriteAtom } from "../../../../store/main/main.store"; +import { useMemo, useState } from "react"; type Props = { data: Coin; }; const MainCard = ({ data }: Props) => { + const favorites = useRecoilValue(mainFavoriteAtom); + const isPick = useMemo(() => { + return favorites.find((prev) => prev === data.market) === undefined + ? false + : true; + }, [data.market, favorites]); + + const [pick, setPick] = useState(isPick); + + const { handlePick } = useFavorites({ pick, setPick }); + return ( - - {data.korean_name}({data.english_name}) - + + + {data.korean_name}({data.english_name}) + + handlePick(data.market)}> + {pick ? : } + + diff --git a/components/main/mainCardList/mainCard/style.ts b/components/main/mainCardList/mainCard/style.ts index 4761912..e7a4f6c 100644 --- a/components/main/mainCardList/mainCard/style.ts +++ b/components/main/mainCardList/mainCard/style.ts @@ -11,6 +11,12 @@ export const MainCardContainer = styled.div` padding: 20px; `; +export const MainCardTitleWrap = styled.div` + display: flex; + align-items: center; + justify-content: space-between; +`; + export const MainCardTitle = styled.h1` font-size: 14px; line-height: 1.86; @@ -18,6 +24,15 @@ export const MainCardTitle = styled.h1` color: ${({ theme }) => theme.contrast}; `; +export const MainCardFavIcon = styled.div` + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +`; + export const MainCardDetailButton = styled.button` background: none; border: 0px; diff --git a/components/main/mainFavoriteCardList/MainFavoriteCardList.tsx b/components/main/mainFavoriteCardList/MainFavoriteCardList.tsx new file mode 100644 index 0000000..9cbd697 --- /dev/null +++ b/components/main/mainFavoriteCardList/MainFavoriteCardList.tsx @@ -0,0 +1,12 @@ +import { Coin } from "../../../types/common/common.type"; +import { MainFavCardListContainer } from "./style"; + +type Props = { + data: Coin[] | null; +}; + +const MainFavoriteCardList = () => { + return ; +}; + +export default MainFavoriteCardList; diff --git a/components/main/mainFavoriteCardList/style.ts b/components/main/mainFavoriteCardList/style.ts new file mode 100644 index 0000000..036f87d --- /dev/null +++ b/components/main/mainFavoriteCardList/style.ts @@ -0,0 +1,9 @@ +import styled from "styled-components"; + +export const MainFavCardListContainer = styled.div` + width: 516px; + display: flex; + flex-wrap: wrap; + column-gap: 20px; + row-gap: 20px; +`; diff --git a/components/main/style.ts b/components/main/style.ts index 9114a60..593ffe7 100644 --- a/components/main/style.ts +++ b/components/main/style.ts @@ -1,5 +1,6 @@ import styled from "styled-components"; export const MainContainer = styled.div` - background-color: ${({ theme }) => theme.backgroundColor}; + display: flex; + justify-content: space-between; `; diff --git a/constants/localStorage.contants.ts b/constants/localStorage.contants.ts new file mode 100644 index 0000000..20426aa --- /dev/null +++ b/constants/localStorage.contants.ts @@ -0,0 +1 @@ +export const LOCAL_FAVORITES_KEY = "favorites" as const; diff --git a/constants/product.constants.ts b/constants/product.constants.ts index e90a6fb..21fd5b2 100644 --- a/constants/product.constants.ts +++ b/constants/product.constants.ts @@ -2,7 +2,7 @@ export const COINS_MAX_NUM = 200 as const; export const COIN_DETAIL_CATEGORY = [ { title: "일별시세" }, - { title: "기업정보" }, + { title: "화폐정보" }, ] as const; export const COIN_TICKERS_START_DATE = "14" as const; diff --git a/hooks/main/useFavorites.ts b/hooks/main/useFavorites.ts new file mode 100644 index 0000000..510d802 --- /dev/null +++ b/hooks/main/useFavorites.ts @@ -0,0 +1,47 @@ +import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import { useRecoilState } from "recoil"; +import { LOCAL_FAVORITES_KEY } from "../../constants/localStorage.contants"; +import { mainFavoriteAtom } from "../../store/main/main.store"; +import local from "../../util/local"; + +type Props = { + pick: boolean; + setPick: Dispatch>; +}; + +const useFavorites = ({ pick, setPick }: Props) => { + const [favorites, setFavorites] = useRecoilState(mainFavoriteAtom); + + const handlePick = (coinid: string) => { + handleFavorites(coinid, pick); + setPick((prev) => !prev); + }; + + const handleFavorites = (coinid: string, pick: boolean) => { + const copyFav = favorites; + + if (!pick) { + const isOverlap = favorites.find((prev) => prev === coinid); + + if (isOverlap !== undefined) { + return; + } + + const addFav = copyFav.concat(coinid); + + setFavorites(addFav); + local.set(LOCAL_FAVORITES_KEY, JSON.stringify(addFav)); + } else { + const removeFav = copyFav.filter((prev) => prev !== coinid); + setFavorites(removeFav); + local.set(LOCAL_FAVORITES_KEY, JSON.stringify(removeFav)); + } + }; + + return { + pick, + handlePick, + }; +}; + +export default useFavorites; diff --git a/store/main/main.store.ts b/store/main/main.store.ts new file mode 100644 index 0000000..fa9a472 --- /dev/null +++ b/store/main/main.store.ts @@ -0,0 +1,11 @@ +import { atom } from "recoil"; +import { LOCAL_FAVORITES_KEY } from "../../constants/localStorage.contants"; +import local from "../../util/local"; + +export const mainFavoriteAtom = atom({ + key: "mainFavoriteAtom", + default: + local.get(LOCAL_FAVORITES_KEY) === null + ? [] + : JSON.parse(local.get(LOCAL_FAVORITES_KEY) as string), +});