diff --git a/index.html b/index.html index 82a12a44..30153d88 100644 --- a/index.html +++ b/index.html @@ -39,10 +39,11 @@ }); -
+
+
diff --git a/src/apis/fetchUserInfo.ts b/src/apis/fetchUserInfo.ts index e6a19232..2ca7e791 100644 --- a/src/apis/fetchUserInfo.ts +++ b/src/apis/fetchUserInfo.ts @@ -1,9 +1,20 @@ -import { IUserInfo } from "./../types/userInfo"; +import { ProfileData } from "@type/profile"; import { axiosInstance } from "@apis/axiosInstance"; import { END_POINTS } from "@/constants/api"; -// 유저 정보를 불러오는 api입니다. -export const fetchUserInfo = async (): Promise => { +export const fetchUserInfo = async (): Promise => { const { data } = await axiosInstance.get(END_POINTS.USER_INFO); - return data.data as IUserInfo; + return data.data; +}; + +export const changeName = async (name: string) => { + const res = await axiosInstance.patch(END_POINTS.CHANGE_NAME, { name }); + return res; +}; + +export const changeNumber = async (number: string) => { + const res = await axiosInstance.patch(END_POINTS.CHANGE_NUMBER, { + phone: number, + }); + return res; }; diff --git a/src/apis/patchAccount.ts b/src/apis/patchAccount.ts index 07d181f8..2936c6d0 100644 --- a/src/apis/patchAccount.ts +++ b/src/apis/patchAccount.ts @@ -1,8 +1,8 @@ import { END_POINTS } from "@constants/api"; -import type { AccountProps } from "@type/account"; +import type { AccountData } from "@type/profile"; import { axiosInstance } from "./axiosInstance"; -export const patchAccount = async (accountData: AccountProps) => { +export const patchAccount = async (accountData: AccountData) => { const { data } = await axiosInstance.patch(END_POINTS.ACCOUNT, accountData); return data.data; diff --git a/src/apis/useProfileApi.ts b/src/apis/useProfileApi.ts deleted file mode 100644 index 01e2dca3..00000000 --- a/src/apis/useProfileApi.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { axiosInstance } from "./axiosInstance"; - -const useProfileApi = () => { - const getProfileData = async (endPoint: string) => { - const apiURL = `${endPoint}`; - const { data } = await axiosInstance.get(apiURL); - - return data.data; - }; - - const changeName = async (endPoint: string, name: string) => { - const apiURL = `${endPoint}`; - const res = await axiosInstance.patch(apiURL, { name }); - return res; - }; - - const changeNumber = async (endPoint: string, number: string) => { - const apiURL = `${endPoint}`; - const res = await axiosInstance.patch(apiURL, { phone: number }); - return res; - }; - - return { getProfileData, changeName, changeNumber }; -}; - -export default useProfileApi; diff --git a/src/components/A2HS/A2HS.style.ts b/src/components/A2HS/A2HS.style.ts index 558554ef..06469178 100644 --- a/src/components/A2HS/A2HS.style.ts +++ b/src/components/A2HS/A2HS.style.ts @@ -14,7 +14,7 @@ export const BackDrop = styled(motion.div)` height: 100%; background-color: rgba(0, 0, 0, 0.45); transition: opacity 0.5s ease; - z-index: 3; + z-index: 11; `; export const A2HSContainer = styled(motion.div)` @@ -27,16 +27,16 @@ export const A2HSContainer = styled(motion.div)` left: 50%; width: 90%; max-width: 518px; - bottom: 60px; + bottom: 0px; background-color: ${({ theme }) => theme.color.white}; - padding: 2.5rem 1.25rem; - gap: 1.2rem; + padding: 4rem 1.25rem 3rem; + gap: 1.5rem; box-shadow: 0px -2px 5px rgba(0, 0, 0, 0.2); border-radius: 28px 28px 0px 0px; - z-index: 3; + z-index: 12; transform: translateX(-50%); @@ -96,6 +96,8 @@ export const ButtonWrapper = styled.div` align-items: center; width: 100%; + + margin-top: 1rem; `; export const Message = styled.span` @@ -112,10 +114,10 @@ const Button = styled.button` ${({ theme }) => theme.typo.button2}; - width: 60%; + width: 70%; @media (max-width: ${breakpoints.tablet}) { - width: 80%; + width: 90%; } @media (max-width: ${breakpoints.mobile}) { diff --git a/src/components/A2HS/A2HS.tsx b/src/components/A2HS/A2HS.tsx index 9a9813d4..cf4c0bab 100644 --- a/src/components/A2HS/A2HS.tsx +++ b/src/components/A2HS/A2HS.tsx @@ -3,41 +3,45 @@ import useA2HS from "@hooks/common/useA2HS"; import IcPercentHotelSrc from "@assets/icons/ic_percent_hotel-app.png"; import * as S from "./A2HS.style"; import { AnimatePresence } from "framer-motion"; +import { useState } from "react"; const A2HS = () => { const { deferredPrompt, install, clearPrompt } = useA2HS(); - const modalRoot = document.getElementById("modal-root"); + const appRoot = document.getElementById("app-install-pop"); + const [isShow, SetIsShow] = useState(true); const backdropVariants = { hidden: { opacity: 0 }, visible: { opacity: 1 }, + exit: { opacity: 0 }, }; const modalVariants = { hidden: { y: "100vh", x: "50", opacity: 0 }, visible: { y: 0, x: "50", opacity: 1 }, - exit: { y: "100vh", x: "50", opacity: 0 }, + exit: { y: "-100", x: "50", opacity: 0 }, }; - if (!deferredPrompt || !modalRoot) return null; + if (!deferredPrompt || !appRoot) return null; return ReactDOM.createPortal( - {deferredPrompt && ( + {isShow && ( <> SetIsShow(false)} variants={backdropVariants} - transition={{ duration: 0.5, delay: 1 }} + transition={{ duration: 0.5 }} /> @@ -60,7 +64,7 @@ const A2HS = () => { )} , - modalRoot, + appRoot, ); }; diff --git a/src/components/account/enterAccountInfo/EnterAccountInfo.tsx b/src/components/account/enterAccountInfo/EnterAccountInfo.tsx index 9a534445..cb352802 100644 --- a/src/components/account/enterAccountInfo/EnterAccountInfo.tsx +++ b/src/components/account/enterAccountInfo/EnterAccountInfo.tsx @@ -2,24 +2,26 @@ import { useEffect, useRef, useState } from "react"; import * as S from "./EnterAccountInfo.style"; import { BANK_LIST } from "@/constants/bank"; import { AnimatePresence, useAnimation } from "framer-motion"; -import type { AccountProps } from "@type/account"; + import { useLocation, useNavigate } from "react-router-dom"; import { PATH } from "@/constants/path"; import useToastConfig from "@hooks/common/useToastConfig"; import usePreventLeave from "@hooks/common/usePreventLeave"; import { patchAccount } from "@apis/patchAccount"; -import { UndoIcon } from "@components/layout/header/HeaderTop.style"; +import type { AccountData } from "@type/profile"; +import { useUserInfoStore } from "@/store/store"; const EnterAccountInfo = ({ accountInfo, setAccountInfo, }: { - accountInfo: AccountProps; - setAccountInfo?: React.Dispatch>; + accountInfo: AccountData; + setAccountInfo?: React.Dispatch>; }) => { usePreventLeave(true); const { pathname } = useLocation(); const navigate = useNavigate(); + const setUserInfo = useUserInfoStore((state) => state.setUserInfo); const { handleToast } = useToastConfig(); const controls = useAnimation(); const accountNumberRef = useRef(null); @@ -88,7 +90,7 @@ const EnterAccountInfo = ({ if (!handleErrorToast()) { return; } - const updatedInfo: AccountProps = { + const updatedInfo: AccountData = { accountNumber: newAccountNumber, bank: newBank, }; @@ -98,6 +100,7 @@ const EnterAccountInfo = ({ try { await patchAccount(updatedInfo).then(() => { setAccountInfo(updatedInfo); + setUserInfo(updatedInfo); handleToast(false, ["계좌 등록이 완료되었습니다!"]); navigate(PATH.MANAGE_ACCOUNT, { replace: true }); @@ -114,7 +117,7 @@ const EnterAccountInfo = ({ try { await patchAccount(updatedInfo).then(() => { handleToast(false, ["계좌 변경이 완료되었습니다"]); - + setUserInfo(updatedInfo); navigate(PATH.MANAGE_ACCOUNT, { replace: true }); }); } catch (err) { @@ -122,73 +125,60 @@ const EnterAccountInfo = ({ } } - /** 양도글 작성 일 때, - if (pathname === PATH.양도글작성 && setAccountInfo) { - 로직 작성... - return; - } - */ - return; }; return ( - <> - - navigate(-1)} /> -

계좌 등록

-
- -

입금받을 계좌를 등록해주세요

- accountOnChange(e)} - /> - setShowBankList(true)} - > - {newBank ? newBank : "은행"} - - - setShowBankList(false)} - /> - - -

은행

- - {BANK_LIST.map((item) => { - return ( - - bankOnChange(e)} - checked={item.name === accountInfo?.bank} - /> - - {item.name} - - ); - })} - -
-
- - {buttonText} - -
- + +

입금받을 계좌를 등록해주세요

+ accountOnChange(e)} + /> + setShowBankList(true)} + > + {newBank ? newBank : "은행"} + + + setShowBankList(false)} + /> + + +

은행

+ + {BANK_LIST.map((item) => { + return ( + + bankOnChange(e)} + checked={item.name === accountInfo?.bank} + /> + + {item.name} + + ); + })} + +
+
+ + {buttonText} + +
); }; diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index eecdf9a3..c6b43e11 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -3,8 +3,8 @@ import Header from "./header/HeaderTop"; import * as S from "./Layout.style"; import BottomNav from "./navBottom/NavBottom"; import A2HS from "../A2HS/A2HS"; -import { useLocation } from "react-router-dom"; -import { PATH } from "@/constants/path"; +import { isMobile } from "@/utils/isMobile"; + interface ChildrenProps { children: React.ReactNode; isHeaderOn: boolean; @@ -12,16 +12,15 @@ interface ChildrenProps { } const Layout = ({ children, isHeaderOn, isBottomNavOn }: ChildrenProps) => { - const { pathname } = useLocation(); + const isMobileDevice = isMobile(); return ( {isHeaderOn &&
} - {children} - {pathname === PATH.ROOT && } - {isBottomNavOn && } + + {isBottomNavOn && } ); diff --git a/src/components/layout/navBottom/NavBottom.style.ts b/src/components/layout/navBottom/NavBottom.style.ts index c16a078f..486b92f7 100644 --- a/src/components/layout/navBottom/NavBottom.style.ts +++ b/src/components/layout/navBottom/NavBottom.style.ts @@ -13,7 +13,7 @@ export const BottomNavContainer = styled.section<{ $isMobile: boolean }>` bottom: 0; width: 100%; max-width: 768px; - z-index: 10; + z-index: 1; height: ${({ $isMobile }) => ($isMobile ? "78px" : "60px")}; justify-content: center; align-items: flex-start; diff --git a/src/components/layout/navBottom/NavBottom.tsx b/src/components/layout/navBottom/NavBottom.tsx index 628aeb7e..a6636ec8 100644 --- a/src/components/layout/navBottom/NavBottom.tsx +++ b/src/components/layout/navBottom/NavBottom.tsx @@ -1,13 +1,15 @@ import { PATH } from "@/constants/path"; import { useLocation } from "react-router-dom"; import * as S from "./NavBottom.style"; -import { isMobile } from "@/utils/isMobile"; -import { useState } from "react"; import ToolTip from "./toolTip/ToolTip"; +import useTooltip from "@/hooks/common/useTooltip"; -const BottomNav = () => { - const isMobileDevice = isMobile(); - const [isToolTipOn, setIsToolTipOn] = useState(true); +interface BottomNavProps { + isMobile: boolean; +} + +const BottomNav = ({ isMobile }: BottomNavProps) => { + const { isToolTipVisible, hideTooltipForWeek } = useTooltip(); const { pathname } = useLocation(); const navList = [ @@ -38,9 +40,11 @@ const BottomNav = () => { ]; return ( - - {isToolTipOn && ( - 숙박권을 판매해보세요. + + {isToolTipVisible && ( + + 숙박권을 판매해보세요. + )} {navList.map((item) => { diff --git a/src/constants/api.ts b/src/constants/api.ts index 5c54d666..fb7bc510 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -28,6 +28,8 @@ export const END_POINTS = { STOCK: (productId: string) => `/v1/products/${productId}/stock`, NEW_TOKEN: "/v1/token/refresh", SEARCH: "/v1/products/search", + CHANGE_NAME: "/v1/members/name", + CHANGE_NUMBER: "/v1/members/phone", } as const; export const STATUS_CODE = { diff --git a/src/constants/regex.ts b/src/constants/regex.ts index 4a099f06..c3bf3578 100644 --- a/src/constants/regex.ts +++ b/src/constants/regex.ts @@ -2,3 +2,5 @@ export const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; export const PHONE_NUMBER_REGEX = /^01[0-9]-\d{3,4}-\d{4}$/; + +export const KOREAN_REGEX = /^[ㄱ-ㅎ가-힣ㅏ-ㅣ]+$/; diff --git a/src/hooks/api/useUserInfoQuery.ts b/src/hooks/api/useUserInfoQuery.ts new file mode 100644 index 00000000..dd693a75 --- /dev/null +++ b/src/hooks/api/useUserInfoQuery.ts @@ -0,0 +1,37 @@ +import { useSuspenseQuery } from "@tanstack/react-query"; + +import { fetchUserInfo } from "@/apis/fetchUserInfo"; +import type { AccountData, ProfileData } from "@/types/profile"; + +interface AccountQueryProps { + accountData: AccountData; + rawData: ProfileData; +} + +export const useAccountQuery = () => { + const accountQuery = useSuspenseQuery({ + queryKey: ["myProfile"], + queryFn: async () => await fetchUserInfo(), + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + select: (res) => { + const accountData = { accountNumber: res.accountNumber, bank: res.bank }; + const rawData = res; + return { accountData, rawData }; + }, + }); + + return accountQuery; +}; + +export const useUserInfoQuery = () => { + const userInfoQuery = useSuspenseQuery({ + queryKey: ["userInfo"], + queryFn: async () => await fetchUserInfo(), + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + }); + return userInfoQuery; +}; diff --git a/src/hooks/common/useLoadUserInfo.ts b/src/hooks/common/useLoadUserInfo.ts index 9875a9b9..f5af0444 100644 --- a/src/hooks/common/useLoadUserInfo.ts +++ b/src/hooks/common/useLoadUserInfo.ts @@ -1,21 +1,21 @@ -import useProfileApi from "@apis/useProfileApi"; +import { fetchUserInfo } from "@/apis/fetchUserInfo"; import { useUserInfoStore } from "@store/store"; import { useEffect } from "react"; export const useLoadUserInfo = (isShow: boolean) => { const userInfo = useUserInfoStore((state) => state.userInfo); const setUserInfo = useUserInfoStore((state) => state.setUserInfo); - const { getProfileData } = useProfileApi(); - useEffect(() => { - const fetchUserInfo = async () => { + console.log(); + const getUserInfo = async () => { if (isShow && userInfo === null) { - const response = await getProfileData("/v1/members"); + const response = await fetchUserInfo(); + console.log(response); setUserInfo(response); } }; - fetchUserInfo(); + getUserInfo(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isShow, userInfo]); diff --git a/src/hooks/common/useTooltip.ts b/src/hooks/common/useTooltip.ts new file mode 100644 index 00000000..e77ed6a4 --- /dev/null +++ b/src/hooks/common/useTooltip.ts @@ -0,0 +1,21 @@ +import { useState, useEffect } from "react"; +import { tooltip } from "@utils/tooltip"; + +const useTooltip = () => { + const [isToolTipVisible, setIsToolTipVisible] = useState(true); + + useEffect(() => { + if (tooltip.isValidateHideTooltip) { + setIsToolTipVisible(false); + } + }, []); + + const hideTooltipForWeek = () => { + tooltip.setHideTooltip(); + setIsToolTipVisible(false); + }; + + return { isToolTipVisible, hideTooltipForWeek }; +}; + +export default useTooltip; diff --git a/src/pages/connectYanoljaPage/IntroPage/IntroPage.style.ts b/src/pages/connectYanoljaPage/IntroPage/IntroPage.style.ts index a255cc5c..cad4c93b 100644 --- a/src/pages/connectYanoljaPage/IntroPage/IntroPage.style.ts +++ b/src/pages/connectYanoljaPage/IntroPage/IntroPage.style.ts @@ -1,15 +1,16 @@ import { hexToRgba } from "@utils/hexTorgba"; import { breakpoints } from "@styles/theme"; import styled, { DefaultTheme } from "styled-components"; +import { motion } from "framer-motion"; export const PageContainer = styled.div` width: 100%; - height: 100%; + height: 100vh; - background-color: ${({ theme }) => theme.color.black}; + background-color: ${({ theme }) => theme.color.white}; `; -export const MainWrapper = styled.div` +export const MainWrapper = styled(motion.div)` display: flex; flex-direction: column; align-items: center; @@ -73,9 +74,9 @@ export const XIcon = styled.div` } `; -export const Title = styled.p` +export const Title = styled(motion.p)` ${({ theme }) => theme.typo.title4}; - color: ${({ theme }) => theme.color.percentOrange}; + color: ${({ theme }) => theme.color.greyScale1}; line-height: 1.8; `; diff --git a/src/pages/connectYanoljaPage/IntroPage/IntroPage.tsx b/src/pages/connectYanoljaPage/IntroPage/IntroPage.tsx index d9d897c1..339ccab0 100644 --- a/src/pages/connectYanoljaPage/IntroPage/IntroPage.tsx +++ b/src/pages/connectYanoljaPage/IntroPage/IntroPage.tsx @@ -1,5 +1,5 @@ import XIcon from "@assets/icons/ic_x.png"; -import PercentHotelLogo from "@assets/logos/Percent-hotel_logo.png"; +import PercentHotelLogo from "@assets/logos/Percent-hotel_logo_b.png"; import YanoljaLogo from "@assets/logos/Yanolja_CI.png"; import { PATH } from "@constants/path"; import { useNavigate } from "react-router-dom"; @@ -9,9 +9,43 @@ import * as S from "./IntroPage.style.ts"; const IntroPage = () => { const navigate = useNavigate(); + const containerVariants = { + hidden: { + opacity: 0, + y: -30, + }, + visible: { + opacity: 1, + y: 0, + transition: { + delay: 0.3, + duration: 0.7, + }, + }, + }; + + const titleVariants = { + hidden: { + opacity: 0, + y: -10, + }, + visible: { + opacity: 1, + y: 0, + transition: { + delay: 0.4, + duration: 0.7, + }, + }, + }; + return ( - + 퍼센트호텔 로고 @@ -21,7 +55,7 @@ const IntroPage = () => { 야놀자 로고 - + 야놀자 계정 연동하고
쉽고 빠르게 거래하기 diff --git a/src/pages/myPage/MyPage.tsx b/src/pages/myPage/MyPage.tsx index 0d4b1e47..9b5db458 100644 --- a/src/pages/myPage/MyPage.tsx +++ b/src/pages/myPage/MyPage.tsx @@ -2,32 +2,16 @@ import { Outlet, useNavigate } from "react-router-dom"; import MyPageNav from "./components/myPageNav/MyPageNav"; import * as S from "./MyPage.style"; -import useProfileApi from "@apis/useProfileApi"; -import { useEffect, useState } from "react"; -import { ProfileData } from "./manage/manageProfile/ManageProfile.type"; -import { END_POINTS } from "@constants/api"; import { PATH } from "@constants/path"; +import { useLoadUserInfo } from "@/hooks/common/useLoadUserInfo"; +import useAuthStore from "@/store/authStore"; const MyPage = () => { const navigate = useNavigate(); - // FIXME: 전역상태로 야놀자 연동 여부 확인하도록 수정 - const { getProfileData } = useProfileApi(); - const [userProfile, setUserProfile] = useState(); - const isConnected = userProfile?.linkedToYanolja; + const userInfo = useLoadUserInfo(true); + const isLoggedIn = useAuthStore((state) => state.isLoggedIn); + const isConnected = userInfo?.linkedToYanolja; localStorage.setItem("isConnected", JSON.stringify(isConnected)); - const fetchUserProfile = async () => { - try { - const res = await getProfileData(END_POINTS.USER_INFO); - setUserProfile(res); - } catch (err) { - console.log(err); - } - }; - - useEffect(() => { - fetchUserProfile(); - // eslint-disable-next-line - }, []); const connectToYanolja = () => { navigate(PATH.YANOLJA_ACCOUNT); @@ -36,12 +20,12 @@ const MyPage = () => { return ( - {userProfile ? ( -

{userProfile.email} 님

+ {isLoggedIn && userInfo ? ( +

{userInfo.email} 님

) : (

로그인 후 판매글을 작성해보세요

)} - {!userProfile ? ( + {!userInfo ? ( ) : isConnected ? ( 야놀자와 연동된 계정입니다 diff --git a/src/pages/myPage/info/Info.tsx b/src/pages/myPage/info/Info.tsx index 26c98407..f3dcc955 100644 --- a/src/pages/myPage/info/Info.tsx +++ b/src/pages/myPage/info/Info.tsx @@ -5,18 +5,21 @@ import { PATH } from "@constants/path"; import { logout } from "@apis/logout"; import useToastConfig from "@hooks/common/useToastConfig"; import useAuthStore from "@/store/authStore"; +import { ACCESS_TOKEN, REFRESH_TOKEN } from "@/constants/api"; const Info = () => { const navigate = useNavigate(); const { handleToast } = useToastConfig(); const [showLogoutModal, setShowLogoutModal] = useState(false); + const isLoggedIn = useAuthStore((state) => state.isLoggedIn); const setIsLoggedIn = useAuthStore((state) => state.setIsLoggedIn); const infoList = [ { name: "문의하기", handler: () => alert("문의하기") }, - { name: "로그아웃", handler: () => setShowLogoutModal(true) }, + isLoggedIn + ? { name: "로그아웃", handler: () => setShowLogoutModal(true) } + : { name: "로그인", handler: () => navigate(PATH.LOGIN) }, ]; - const logoutCancelHandler = () => { setShowLogoutModal(false); }; @@ -24,7 +27,8 @@ const Info = () => { const logoutConfirmHandler = async () => { try { await logout(); - localStorage.clear(); + localStorage.removeItem(ACCESS_TOKEN); + localStorage.removeItem(REFRESH_TOKEN); setIsLoggedIn(false); navigate(PATH.ROOT); } catch (err) { diff --git a/src/pages/myPage/manage/Manage.tsx b/src/pages/myPage/manage/Manage.tsx index 2ec7d576..cacad31b 100644 --- a/src/pages/myPage/manage/Manage.tsx +++ b/src/pages/myPage/manage/Manage.tsx @@ -1,40 +1,22 @@ import { PATH } from "@constants/path"; import * as S from "./Manage.style"; import rightArrow from "@assets/icons/RightArrow.svg"; -import useProfileApi from "@apis/useProfileApi"; -import { useEffect, useState } from "react"; -import type { ProfileData } from "./manageProfile/ManageProfile.type"; -import { END_POINTS } from "@constants/api"; +import { useLoadUserInfo } from "@/hooks/common/useLoadUserInfo"; const Manage = () => { const manageList = [ { path: PATH.MANAGE_PROFILE, name: "프로필 변경" }, { path: PATH.MANAGE_ACCOUNT, name: "정산 계좌 관리" }, ]; - // FIXME: 전역 상태로 야놀자 연동여부를 체크하도록 변경 - const { getProfileData } = useProfileApi(); - const [userProfile, setUserProfile] = useState(); - const fetchUserProfile = async () => { - try { - const res = await getProfileData(END_POINTS.USER_INFO); - setUserProfile(res); - } catch (err) { - console.log(err); - } - }; - - useEffect(() => { - fetchUserProfile(); - // eslint-disable-next-line - }, []); + const userInfo = useLoadUserInfo(true); return (

관리

{manageList.map((item, index) => { const hideAccountManage = - index === 1 && userProfile?.linkedToYanolja === false; + index === 1 && userInfo?.linkedToYanolja === false; return ( diff --git a/src/pages/myPage/manage/accountInfo/AccountInfo.style.ts b/src/pages/myPage/manage/accountInfo/AccountInfo.style.ts index b9c57d21..b49f58f0 100644 --- a/src/pages/myPage/manage/accountInfo/AccountInfo.style.ts +++ b/src/pages/myPage/manage/accountInfo/AccountInfo.style.ts @@ -12,6 +12,8 @@ export const AccountInfoWrapper = styled.div` ${({ theme }) => theme.typo.body4} color: ${({ theme }) => theme.color.black}; + padding-top: 1.25rem; + div { height: 33px; line-height: 33px; diff --git a/src/pages/myPage/manage/accountInfo/AccountInfo.tsx b/src/pages/myPage/manage/accountInfo/AccountInfo.tsx index 307fb856..0b9b40d5 100644 --- a/src/pages/myPage/manage/accountInfo/AccountInfo.tsx +++ b/src/pages/myPage/manage/accountInfo/AccountInfo.tsx @@ -1,15 +1,15 @@ import { useNavigate } from "react-router-dom"; -import { ProfileData } from "../manageProfile/ManageProfile.type"; + import * as S from "./AccountInfo.style"; import { PATH } from "@constants/path"; -import type { AccountProps } from "@type/account"; +import type { ProfileData, AccountData } from "@type/profile"; const AccountInfo = ({ data, accountInfo, }: { data: ProfileData; - accountInfo: AccountProps; + accountInfo: AccountData; }) => { const { bank, accountNumber, name } = data; const navigate = useNavigate(); diff --git a/src/pages/myPage/manage/manageAccount/ManageAccount.tsx b/src/pages/myPage/manage/manageAccount/ManageAccount.tsx index 5373201f..2e5f4f60 100644 --- a/src/pages/myPage/manage/manageAccount/ManageAccount.tsx +++ b/src/pages/myPage/manage/manageAccount/ManageAccount.tsx @@ -1,44 +1,16 @@ import RegisterAccount from "../registerAccount/RegisterAccount"; -import useProfileApi from "@apis/useProfileApi"; -import type { ProfileData } from "../manageProfile/ManageProfile.type"; -import { useEffect, useState } from "react"; -import type { AccountProps } from "@type/account"; + +import { useEffect } from "react"; import AccountInfo from "../accountInfo/AccountInfo"; -import { END_POINTS } from "@constants/api"; import { useNavigate, useSearchParams } from "react-router-dom"; import { PATH } from "@constants/path"; import useToastConfig from "@hooks/common/useToastConfig"; +import { useAccountQuery } from "@/hooks/api/useUserInfoQuery"; const ManageAccount = () => { const navigate = useNavigate(); const [search] = useSearchParams(); - const { getProfileData } = useProfileApi(); const { handleToast } = useToastConfig(); - const [data, setData] = useState(); - const noPrevAccount = !data?.accountNumber && !data?.bank; - const [accountInfo, setAccountInfo] = useState({ - accountNumber: data?.accountNumber, - bank: data?.bank, - }); - const [isLoading, setIsLoading] = useState(true); - - const fetchData = async () => { - setIsLoading(true); - try { - const res = await getProfileData(END_POINTS.USER_INFO); - if (!res.linkedToYanolja) { - handleToast(true, [<>잘못된 접근 방식입니다]); - navigate(PATH.SETTING, { replace: true }); - return; - } - setData(res); - setAccountInfo({ accountNumber: res.accountNumber, bank: res.bank }); - } catch (error) { - console.log(error); - } finally { - setIsLoading(false); - } - }; useEffect(() => { if ( @@ -50,18 +22,23 @@ const ManageAccount = () => { if (search.get("step") && search.get("step") !== "first") { navigate(PATH.MANAGE_ACCOUNT, { replace: true }); } - - fetchData(); - // eslint-disable-next-line + // eslint-disable-next-line react-hooks/exhaustive-deps }, [search]); - if (isLoading) return
Loading...
; + const { data } = useAccountQuery(); + + const noPrevAccount = + !data?.accountData.accountNumber && !data.accountData.bank; - if (!data) return
Data fetching Error
; + if (!data.rawData.linkedToYanolja) { + handleToast(true, [<>잘못된 접근 방식입니다]); + navigate(PATH.SETTING, { replace: true }); + return null; + } if (noPrevAccount) return ; - return ; + return ; }; export default ManageAccount; diff --git a/src/pages/myPage/manage/manageName/ManageName.tsx b/src/pages/myPage/manage/manageName/ManageName.tsx index 5d547668..57928956 100644 --- a/src/pages/myPage/manage/manageName/ManageName.tsx +++ b/src/pages/myPage/manage/manageName/ManageName.tsx @@ -1,8 +1,8 @@ import { useRef, useState } from "react"; import * as S from "./ManageName.style"; -// import Toast from "@/components/toast/Toast"; -import useProfileApi from "@/apis/useProfileApi"; import useToastConfig from "@hooks/common/useToastConfig"; +import { changeName } from "@/apis/fetchUserInfo"; +import { KOREAN_REGEX } from "@/constants/regex"; const ManageName = ({ prevName, @@ -14,8 +14,6 @@ const ManageName = ({ const [name, setName] = useState(prevName); const [isChanging, setIsChanging] = useState(false); const inputRef = useRef(null); - const koreanRegex = /^[ㄱ-ㅎ가-힣ㅏ-ㅣ]+$/; - const { changeName } = useProfileApi(); const { handleToast } = useToastConfig(); const nameChangeHandler = (event: React.ChangeEvent) => { @@ -32,7 +30,7 @@ const ManageName = ({ setIsChanging(false); if (prevName === name) return; try { - await changeName("/v1/members/name", name).then(() => { + await changeName(name).then(() => { handleToast(true, [<>이름이 성공적으로 변경되었습니다!]); }); } catch (err) { @@ -50,7 +48,7 @@ const ManageName = ({ }; } - if (!koreanRegex.test(name)) { + if (!KOREAN_REGEX.test(name)) { return { helpMessage: "이름은 한글로만 입력해 주세요", state: "onError", diff --git a/src/pages/myPage/manage/managePhoneNumber/ManagePhoneNumber.tsx b/src/pages/myPage/manage/managePhoneNumber/ManagePhoneNumber.tsx index 728918af..34348578 100644 --- a/src/pages/myPage/manage/managePhoneNumber/ManagePhoneNumber.tsx +++ b/src/pages/myPage/manage/managePhoneNumber/ManagePhoneNumber.tsx @@ -1,7 +1,8 @@ import { useRef, useState } from "react"; import * as S from "./ManagePhoneNumber.style"; -import useProfileApi from "@/apis/useProfileApi"; import useToastConfig from "@hooks/common/useToastConfig"; +import { changeNumber } from "@/apis/fetchUserInfo"; +import { useUserInfoStore } from "@/store/store"; const ManagePhoneNumber = ({ prevPhoneNumber, @@ -11,8 +12,8 @@ const ManagePhoneNumber = ({ const [phoneNumber, setPhoneNumber] = useState(prevPhoneNumber); const [isChanging, setIsChanging] = useState(false); const inputRef = useRef(null); - const { changeNumber } = useProfileApi(); const { handleToast } = useToastConfig(); + const setUserInfo = useUserInfoStore((state) => state.setUserInfo); const phoneNumberChangeHandler = ( event: React.ChangeEvent, @@ -30,7 +31,8 @@ const ManagePhoneNumber = ({ setIsChanging(false); if (prevPhoneNumber === phoneNumber) return; try { - await changeNumber("/v1/members/phone", phoneNumber).then(() => { + await changeNumber(phoneNumber).then(() => { + setUserInfo({ phone: phoneNumber }); handleToast(true, [<>전화번호가 성공적으로 변경되었습니다!]); }); } catch (err) { diff --git a/src/pages/myPage/manage/manageProfile/ManageProfile.style.ts b/src/pages/myPage/manage/manageProfile/ManageProfile.style.ts index 02d7760f..b0f30a96 100644 --- a/src/pages/myPage/manage/manageProfile/ManageProfile.style.ts +++ b/src/pages/myPage/manage/manageProfile/ManageProfile.style.ts @@ -1,7 +1,7 @@ import styled from "styled-components"; export const ManageContainer = styled.div` - padding: 32px 20px; + padding-top: 56px; h1 { ${({ theme }) => theme.typo.body2} @@ -12,6 +12,8 @@ export const ManageContainer = styled.div` `; export const ManageInfoWrapper = styled.div` + padding: 1.25rem; + ${({ theme }) => theme.typo.body4} color: ${({ theme }) => theme.color.black}; diff --git a/src/pages/myPage/manage/manageProfile/ManageProfile.tsx b/src/pages/myPage/manage/manageProfile/ManageProfile.tsx index bf6b8a5d..02578f1e 100644 --- a/src/pages/myPage/manage/manageProfile/ManageProfile.tsx +++ b/src/pages/myPage/manage/manageProfile/ManageProfile.tsx @@ -2,46 +2,23 @@ import ManageEmail from "../manageEmail/ManageEmail"; import ManageName from "../manageName/ManageName"; import ManagePhoneNumber from "../managePhoneNumber/ManagePhoneNumber"; import * as S from "./ManageProfile.style"; -import useProfileApi from "@/apis/useProfileApi"; -import type { ProfileData } from "./ManageProfile.type"; -import { useEffect, useState } from "react"; -import { END_POINTS } from "@constants/api"; -const ManageProfile = () => { - const { getProfileData } = useProfileApi(); - const [userProfile, setUserProfile] = useState(); - const [isLoading, setIsLoading] = useState(true); - - const fetchUserProfile = async () => { - try { - const res = await getProfileData(END_POINTS.USER_INFO); - setUserProfile(res); - } catch (err) { - console.log(err); - } finally { - setIsLoading(false); - } - }; - - useEffect(() => { - fetchUserProfile(); - // eslint-disable-next-line - }, []); +import { useUserInfoQuery } from "@/hooks/api/useUserInfoQuery"; - if (isLoading) return
Loading...
; - - if (!userProfile) return
Data Fetching Error
; +const ManageProfile = () => { + const { data: userInfo } = useUserInfoQuery(); + if (!userInfo) throw new Error("계정을 찾을 수 없습니다"); return ( -

나의 계정

- +

나의 계정

+ - +
); diff --git a/src/pages/myPage/manage/manageProfile/ManageProfile.type.ts b/src/pages/myPage/manage/manageProfile/ManageProfile.type.ts deleted file mode 100644 index 168dd13b..00000000 --- a/src/pages/myPage/manage/manageProfile/ManageProfile.type.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ProfileData { - accountNumber: string | undefined; - bank: string | undefined; - email: string; - id: number; - linkedToYanolja: boolean; - phone: string; - name: string; -} diff --git a/src/pages/myPage/manage/registerAccount/RegisterAccount.tsx b/src/pages/myPage/manage/registerAccount/RegisterAccount.tsx index 4f446b4f..a658d2f3 100644 --- a/src/pages/myPage/manage/registerAccount/RegisterAccount.tsx +++ b/src/pages/myPage/manage/registerAccount/RegisterAccount.tsx @@ -3,16 +3,16 @@ import * as S from "./RegisterAccount.style"; import { useNavigate, useSearchParams } from "react-router-dom"; import TermsAgreement from "@/components/account/termsAgreement/TermsAgreement"; import EnterAccountInfo from "@/components/account/enterAccountInfo/EnterAccountInfo"; -import type { AccountProps } from "@/types/account"; import { PATH } from "@constants/path"; +import type { AccountData } from "@/types/profile"; const RegisterAccount = () => { const navigate = useNavigate(); const [step, setStep] = useState("first"); const [path, setPath] = useSearchParams(); - const [accountInfo, setAccountInfo] = useState({ - accountNumber: undefined, - bank: undefined, + const [accountInfo, setAccountInfo] = useState({ + accountNumber: null, + bank: null, }); const handleStep = (step: string) => { diff --git a/src/pages/searchPage/Search.tsx b/src/pages/searchPage/Search.tsx index 00b76657..9bf226f6 100644 --- a/src/pages/searchPage/Search.tsx +++ b/src/pages/searchPage/Search.tsx @@ -41,6 +41,8 @@ const Search = () => { pageParam, pageSize, ), + refetchOnMount: false, + refetchOnWindowFocus: false, initialPageParam: 0, getNextPageParam: (lastPage) => { const lastData = lastPage?.content; @@ -94,7 +96,6 @@ const Search = () => { - {isLoading && } {!isLoading && data && !data?.pages?.[0]?.content?.length && ( diff --git a/src/pages/searchPage/components/filterModal/FilterModal.style.ts b/src/pages/searchPage/components/filterModal/FilterModal.style.ts index 8ca219c6..f757e19c 100644 --- a/src/pages/searchPage/components/filterModal/FilterModal.style.ts +++ b/src/pages/searchPage/components/filterModal/FilterModal.style.ts @@ -1,6 +1,7 @@ import styled from "styled-components"; import CloseButton from "@assets/icons/ic_close-button.svg?react"; import WarningIcon from "@assets/icons/ic_warning.svg?react"; +import { motion } from "framer-motion"; export const ModalContainer = styled.div` display: flex; @@ -15,7 +16,7 @@ export const ModalContainer = styled.div` z-index: 11; `; -export const ModalContent = styled.div` +export const ModalContent = styled(motion.div)` max-width: 768px; min-width: 360px; width: 100%; diff --git a/src/pages/searchPage/components/filterModal/FilterModal.tsx b/src/pages/searchPage/components/filterModal/FilterModal.tsx index 6dd69b9e..9efa9204 100644 --- a/src/pages/searchPage/components/filterModal/FilterModal.tsx +++ b/src/pages/searchPage/components/filterModal/FilterModal.tsx @@ -1,6 +1,7 @@ import { useSearchFilterInfoStore } from "@store/store"; import * as S from "./FilterModal.style"; import { forwardRef } from "react"; +import { AnimatePresence } from "framer-motion"; interface FilterModalProps { setIsModalOpen: React.Dispatch>; @@ -47,37 +48,51 @@ const FilterModal = forwardRef( setIsModalOpen(false); }; + const modalVariants = { + hidden: { y: "100vh", opacity: 0 }, + visible: { y: 0, opacity: 1, transition: { duration: 0.5 } }, + exit: { y: "100vh", opacity: 0, transition: { duration: 0.2 } }, + }; + return ( - - - -
- 정렬 -
- -
-
- {navList.map(({ id, name }) => ( - registerFilter(e, name)} - className={searchInfo.sorted === name ? "active" : ""} - > - {id === 1 ? ( - <> - {name}{" "} - - - ) : ( - name - )} - - ))} -
-
+ + + + +
+ 정렬 +
+ +
+
+ {navList.map(({ id, name }) => ( + registerFilter(e, name)} + className={searchInfo.sorted === name ? "active" : ""} + > + {id === 1 ? ( + <> + {name}{" "} + + + ) : ( + name + )} + + ))} +
+
+
); }, ); diff --git a/src/pages/searchPage/components/searchNav/SearchNav.tsx b/src/pages/searchPage/components/searchNav/SearchNav.tsx index 85ebc12d..6baaec73 100644 --- a/src/pages/searchPage/components/searchNav/SearchNav.tsx +++ b/src/pages/searchPage/components/searchNav/SearchNav.tsx @@ -37,24 +37,22 @@ const SeachNav = () => { }; return ( - <> - - - - {navList.map(({ id, label, name }) => ( - handleCellClick(label)} - className={isActive[label] ? "active" : ""} - > - {name} - - ))} - - - - - + + + + {navList.map(({ id, label, name }) => ( + handleCellClick(label)} + className={isActive[label] ? "active" : ""} + > + {name} + + ))} + + + + ); }; diff --git a/src/pages/transferWritingPage/TransferWriting.style.ts b/src/pages/transferWritingPage/TransferWriting.style.ts index c26b1e94..944b6331 100644 --- a/src/pages/transferWritingPage/TransferWriting.style.ts +++ b/src/pages/transferWritingPage/TransferWriting.style.ts @@ -11,6 +11,8 @@ export const Subtitle = styled.p` position: sticky; top: 56px; + + z-index: 1; `; export const TransferItemList = styled.div` diff --git a/src/pages/transferWritingPage/TransferWriting.tsx b/src/pages/transferWritingPage/TransferWriting.tsx index ce922327..1b9f32a8 100644 --- a/src/pages/transferWritingPage/TransferWriting.tsx +++ b/src/pages/transferWritingPage/TransferWriting.tsx @@ -15,7 +15,6 @@ import { ResponseError } from "@/components/error/Error"; const TransferWriting = () => { const { handleToast } = useToastConfig(); - // FIXME: 유저 정보 전역으로 관리 const { data: userData, isLoading } = useQuery({ queryKey: ["UserInfo"], queryFn: fetchUserInfo, diff --git a/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx b/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx index f7a17c43..df2848e7 100644 --- a/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx +++ b/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx @@ -1,10 +1,10 @@ -import { IUserInfo } from "@/types/userInfo"; +import type { ProfileData } from "@/types/profile"; import * as S from "./AccountSection.style"; interface AccountProps { bank: string | null; accountNumber: string | null; - userInfo?: IUserInfo; + userInfo?: ProfileData; onSetAccount: React.Dispatch>; } diff --git a/src/routes/router.tsx b/src/routes/router.tsx index ce7e1691..bd5db882 100644 --- a/src/routes/router.tsx +++ b/src/routes/router.tsx @@ -289,7 +289,7 @@ const routes = createBrowserRouter([ }> - , + diff --git a/src/store/store.ts b/src/store/store.ts index 96ba0840..5216cc1f 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -1,28 +1,9 @@ -import type { ReactNode } from "react"; -import { IReservation } from "@/types/reservationList"; - -import { create } from "zustand"; // create로 zustand를 불러옵니다. +import { create } from "zustand"; import { persist } from "zustand/middleware"; -import type { MemberResponse } from "@type/login"; import { ISearchFilterInfo } from "@/types/searchFilterInfo"; - -/* - zustand 사용법: - 기본적으로 storeState 타입을 만들고, 이걸 - create(() => ({ ...storeState })) - 식으로 쓰면 됩니다! -*/ - -/* - storeState는 보통 아래처럼 구성합니다. - { - 데이터, - 데이터 조작 set함수1, - 데이터 조작 set함수2, - 데이터 조작 set함수3, - ... - } -*/ +import type { ProfileData } from "@/types/profile"; +import type { ReactNode } from "react"; +import type { IReservation } from "@/types/reservationList"; // 예약내역 선택 아이템 전역상태 타입 interface ReservationState { @@ -62,43 +43,21 @@ export const useSelectedItemStore = create( ), ); -// 유저정보 전역상태 interface UserState { - userInfo: MemberResponse | null; - setUserInfo: (userInfo: MemberResponse) => void; + userInfo: ProfileData | null; + setUserInfo: (userInfo: Partial) => void; } -// 유저정보 전역상태 store export const useUserInfoStore = create((set) => ({ userInfo: null, setUserInfo: (updatedInfo) => set((state) => ({ - userInfo: { - ...state.userInfo, - ...updatedInfo, - }, + userInfo: state.userInfo + ? { ...state.userInfo, ...updatedInfo } + : (updatedInfo as ProfileData), })), })); -// export const useUserInfoStore = create((set) => ({ -// userInfo: { -// id: 0, -// email: "", -// name: "", -// phone: "", -// accountNumber: "", -// bank: "", -// linkedToYanolja: false, -// }, -// setUserInfo: (updatedInfo) => -// set((state) => ({ -// userInfo: { -// ...state.userInfo, -// ...updatedInfo, -// }, -// })), -// })); - export type configType = { isShow: boolean; isError: boolean; diff --git a/src/styles/globalStyle.ts b/src/styles/globalStyle.ts index 196873b4..4ca66018 100644 --- a/src/styles/globalStyle.ts +++ b/src/styles/globalStyle.ts @@ -4,8 +4,7 @@ export const GlobalStyle = createGlobalStyle` *{margin:0;padding:0;font:inherit;color:inherit;} *, :after, :before {box-sizing:border-box;} :root {-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:default;line-height:1.2;overflow-wrap:break-word;word-break:break-word;tab-size:4;} - html, body {height:100%;background-color: ${({ theme }) => - theme.color.greyScale6};} + html, body {height:100%;} img, svg {display: block;max-width:100%;} button {background:none;border:0;cursor:pointer;} a {text-decoration:none} @@ -14,4 +13,11 @@ export const GlobalStyle = createGlobalStyle` box-sizing: border-box; font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; } + + body { + background-color: ${({ theme }) => theme.color.greyScale6}; + letter-spacing: -.3px; + overflow-y: auto; + overflow-x: hidden; + } `; diff --git a/src/types/account.ts b/src/types/account.ts deleted file mode 100644 index bfeb0462..00000000 --- a/src/types/account.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface AccountProps { - accountNumber: string | undefined; - bank: string | undefined; -} diff --git a/src/types/login.ts b/src/types/login.ts index ac7665eb..690ca73a 100644 --- a/src/types/login.ts +++ b/src/types/login.ts @@ -1,15 +1,6 @@ -export interface MemberResponse { - id: number; - email: string; - name: string; - phone: string; - accountNumber: string; - bank: string; - linkedToYanolja: boolean; -} - +import type { ProfileData } from "./profile"; export interface LoginData { - memberResponse: MemberResponse; + memberResponse: ProfileData; tokenResponse: { accessToken: string; refreshToken: string; diff --git a/src/types/profile.ts b/src/types/profile.ts new file mode 100644 index 00000000..80f5e933 --- /dev/null +++ b/src/types/profile.ts @@ -0,0 +1,16 @@ +import { Nullable } from "./nullable"; + +export interface AccountData { + accountNumber: Nullable; + bank: Nullable; +} + +export interface ProfileData { + accountNumber: Nullable; + bank: Nullable; + email: string; + id: number; + linkedToYanolja: boolean; + phone: string; + name: string; +} diff --git a/src/types/userInfo.ts b/src/types/userInfo.ts deleted file mode 100644 index a06f9ed8..00000000 --- a/src/types/userInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface IUserInfo { - id: string; - email: string; - name: string; - phone: string; - accountNumber: string | null; - bank: string | null; - linkedToYanolja: boolean; -} diff --git a/src/utils/a2hs.ts b/src/utils/a2hs.ts index e504033d..f81f9991 100644 --- a/src/utils/a2hs.ts +++ b/src/utils/a2hs.ts @@ -1,18 +1,14 @@ export class a2hs { - // localStorage 키값 private static HIDE_INSTALL_A2HS = "hide_install_a2hs"; - // localStorage 값 가져오기 static get hideInstallA2HS() { return localStorage.getItem(this.HIDE_INSTALL_A2HS); } - // localStorage에 저장된 값이 현재 시간보다 큰 경우 (숨겨야 하는 경우) true 반환 static get isValidateHideInstallA2HS() { return Number(a2hs.hideInstallA2HS) > Date.now(); } - // 일주일 후 기준으로 localStorage 값 설정 static setHideInstallA2HS() { const currentAfterWeek = String( new Date().setDate(new Date().getDate() + 7), @@ -20,7 +16,6 @@ export class a2hs { localStorage.setItem(this.HIDE_INSTALL_A2HS, currentAfterWeek); } - // localStorage에 설정된 값이 현재 시간보다 작을 때 (보여야 하는 경우) localStorage 값 제거 static clear() { localStorage.removeItem(this.HIDE_INSTALL_A2HS); } diff --git a/src/utils/tooltip.ts b/src/utils/tooltip.ts new file mode 100644 index 00000000..3988741f --- /dev/null +++ b/src/utils/tooltip.ts @@ -0,0 +1,22 @@ +export class tooltip { + private static HIDE_TOOLTIP = "hide_tooltip"; + + static get hideTooltip() { + return localStorage.getItem(this.HIDE_TOOLTIP); + } + + static get isValidateHideTooltip() { + return Number(tooltip.hideTooltip) > Date.now(); + } + + static setHideTooltip() { + const currentAfterWeek = String( + new Date().setDate(new Date().getDate() + 1), + ); + localStorage.setItem(this.HIDE_TOOLTIP, currentAfterWeek); + } + + static clear() { + localStorage.removeItem(this.HIDE_TOOLTIP); + } +}