diff --git a/.env b/.env index 56d4893..addb6ce 100644 --- a/.env +++ b/.env @@ -4,5 +4,5 @@ WDS_SOCKET_PORT=0 NODE_PATH=src/ REACT_APP_API_ROOT=http://localhost:8080 REACT_APP_HOME_URL=http://localhost:3000 -REACT_APP_API_URL=http://readyvery.com/api/v1 +REACT_APP_API_URL=http://readyvery.com REACT_APP_KAKAO_LOGIN=http://localhost:8080/oauth2/authorization/kakao \ No newline at end of file diff --git a/src/App.js b/src/App.js index 299ac14..db5b05e 100644 --- a/src/App.js +++ b/src/App.js @@ -24,12 +24,15 @@ function App() { const NewMyPage = Auth(Mypage, true); const expiredTime = 1000 * 60 * 60 * 24; + // const expiredTime = 65000; useInterval(() => { - if ( - cookies.refreshToken !== "undefined" && - cookies.refreshToken !== undefined && - cookies.refreshToken - ) { + // console.log(cookies.refreshToken); + // if ( + // cookies.refreshToken !== "undefined" && + // cookies.refreshToken !== undefined && + // cookies.refreshToken + // ) { + if(cookies.accessToken){ const config = { withCredentials: true, }; @@ -43,9 +46,12 @@ function App() { } }) .catch((err) => { + console.log(err); + alert("토큰이 만료되었습니다. 로그인을 진행해주세요."); navigate("/"); }); - } + } + // } }, expiredTime - 60000); return (
diff --git a/src/Atom/status.jsx b/src/Atom/status.jsx index 3af86b4..dc63bbf 100644 --- a/src/Atom/status.jsx +++ b/src/Atom/status.jsx @@ -1,5 +1,6 @@ import axios from "axios"; import { atom, selector } from "recoil"; +import { Refresh } from "../hoc/handleRefresh"; export const storeState = atom({ key: "storeState", // 전역적으로 고유한 값 @@ -19,7 +20,10 @@ export const isAuthenticatedState = atom({ export const getAuthenticatedSelector = selector({ key: "auth/get", get: async ({ get }) => { - return get(isAuthenticatedState); + const tokenResult = Refresh(); + if(tokenResult){ + return "재발급 성공"; + } else { return "토큰 유효"; } }, set: ({ set }) => { diff --git a/src/components/views/Chart/Chart.jsx b/src/components/views/Chart/Chart.jsx index 48c3bf2..c8d5bdb 100644 --- a/src/components/views/Chart/Chart.jsx +++ b/src/components/views/Chart/Chart.jsx @@ -10,7 +10,7 @@ export default function Chart ({ data }) { indexBy="day" margin={{ top: 20, right: 0, bottom: 30, left: 30 }} padding={0.5} - width={812} + width={710} height={390} valueScale={{ type: 'linear' }} indexScale={{ type: 'band', round: true }} diff --git a/src/components/views/Header/Header.css b/src/components/views/Header/Header.css index 204594d..09bcfec 100644 --- a/src/components/views/Header/Header.css +++ b/src/components/views/Header/Header.css @@ -12,8 +12,9 @@ bottom: 0; left: 0; right: 0; - min-width: 73.75rem; - /* min-width: 64rem; */ + /* min-width: 73.75rem; */ + width: 64rem; + max-width: 64rem; height: 5.5rem; background-color: #2e2d2d; z-index: 101; diff --git a/src/components/views/Inven/InvenBox.jsx b/src/components/views/Inven/InvenBox.jsx index 0bf9249..efd7642 100644 --- a/src/components/views/Inven/InvenBox.jsx +++ b/src/components/views/Inven/InvenBox.jsx @@ -6,7 +6,7 @@ const InvenBox = ({handleModal, invenProps: {category, name, soldOut}}) => { {!soldOut ? (
) : ( -
+
)} {category} diff --git a/src/components/views/NavBar/NavBar.css b/src/components/views/NavBar/NavBar.css index 093bec1..6237dda 100644 --- a/src/components/views/NavBar/NavBar.css +++ b/src/components/views/NavBar/NavBar.css @@ -1,8 +1,8 @@ .navbar { width: 8.875rem; /* height: 46.25rem; */ - height: 45.75rem; - /* height: 42.5rem; */ + /* height: 45.75rem; */ + height: 42.5rem; background-color: #2e2d2d; display: flex; diff --git a/src/hoc/auth.jsx b/src/hoc/auth.jsx index c983392..b5ce7c0 100644 --- a/src/hoc/auth.jsx +++ b/src/hoc/auth.jsx @@ -10,15 +10,24 @@ function Auth(SpecificComponent, option) { const navigate = useNavigate(); const location = useLocation(); const userInfo = useRecoilValue(getUserSelector); + // const tokenInfo = useRecoilValue(getAuthenticatedSelector); const setIsLoggedIn = useSetRecoilState(loginState); const [cookies] = useCookies(["accessToken"]); useEffect(() => { - const isAuth = window.localStorage.getItem("isAuthenticated"); + console.log(userInfo); + // console.log(tokenInfo); + console.log(window.localStorage.getItem("isAuthenticated")); + console.log(cookies?.accessToken); + // const isAuth = window.localStorage.getItem("isAuthenticated"); if (userInfo === "404" && location.pathname !== "/") { navigate("/"); } else { - if (!isAuth && cookies?.accessToken) { + // if(userInfo !== "404"){ + // const tokenInfo = useRecoilValue(getAuthenticatedSelector); + // console.log(tokenInfo); + // } + if (!window.localStorage.getItem("isAuthenticated") && cookies?.accessToken) { // 첫 로그인 시 window.localStorage.setItem("isAuthenticated", true); setIsLoggedIn({ diff --git a/src/hoc/handleRefresh.jsx b/src/hoc/handleRefresh.jsx index 7dd26ea..e834c46 100644 --- a/src/hoc/handleRefresh.jsx +++ b/src/hoc/handleRefresh.jsx @@ -1,5 +1,6 @@ import axios from "axios"; import moment from "moment"; +import { useCookies } from "react-cookie"; import { useRecoilState } from 'recoil'; import { loginState } from '../Atom/status'; @@ -8,6 +9,7 @@ const Refresh = async () => { const apiUrl = process.env.REACT_APP_API_ROOT; const [loginInfo, setLoginInfo] = useRecoilState(loginState); const expireAt = loginInfo.expiredTime; + const [cookies] = useCookies(["accessToken"]); console.log("만료확인"); // 토큰이 만료되었다면 @@ -26,9 +28,12 @@ const Refresh = async () => { ); console.log("재발급 성공", res); setLoginInfo({ + accessToken: cookies, expiredTime: moment().add(1, "hour").format("yyyy-MM-DD HH:mm:ss") }); - } + + return true; + } else {return false;} }; const refreshErrorHandle = () => { diff --git a/src/pages/Home/Home.css b/src/pages/Home/Home.css new file mode 100644 index 0000000..8662011 --- /dev/null +++ b/src/pages/Home/Home.css @@ -0,0 +1,15 @@ +.inven-wrapper{ + display: flex; +} + +nav{ + width: 8.875rem; + /* height: 46.25rem; */ + /* height: 42.5rem; */ + height: 45.75rem; + z-index: 1; +} + +main{ + width: calc(100vw - 8.875rem); +} \ No newline at end of file diff --git a/src/pages/Home/MainHome.css b/src/pages/Home/MainHome.css index 7e8feda..602da68 100644 --- a/src/pages/Home/MainHome.css +++ b/src/pages/Home/MainHome.css @@ -1,7 +1,7 @@ .Main-Box { width: 100%; /* 너비 설정 */ height: 95%; /* 높이 설정 */ - padding: 5% 0% 0% 0%; + /* padding: 5% 0% 0% 0%; */ } .status-header { diff --git a/src/pages/Inventory/MainInven.css b/src/pages/Inventory/MainInven.css index 2de0b41..ac8436f 100644 --- a/src/pages/Inventory/MainInven.css +++ b/src/pages/Inventory/MainInven.css @@ -6,8 +6,10 @@ .mainInven-title__wrapper{ display: flex; height: 5.0625rem; - width: 100%; - min-width: calc(73.75rem - 8.875rem); + /* width: 100%; */ + width: 55.125rem; + /* min-width: calc(73.75rem - 8.875rem); */ + min-width: calc(64rem - 8.875rem); background-color: #4F4F4F; border-bottom: 0.5rem solid #d82356; position: relative; @@ -24,38 +26,45 @@ .mainInven-title__span1{ width: 15%; - min-width: 8.3125rem; + /* min-width: 8.3125rem; */ + min-width: 8.26875rem; } .mainInven-title__span2__wrapper{ width: 25%; - min-width: 17.8125rem; + /* min-width: 17.8125rem; */ + min-width: 13.78125rem; display: flex; justify-content: space-between; } -.mainInven-title__span2{ - /* width: 25%; */ -} - .mainInven-title__span3{ width: 60%; /* min-width: 39.625rem; */ + min-width: 33.075rem; + + white-space: nowrap; } .mainInven-category__modal{ position: absolute; - left: calc((100vw - 8.875rem) * 0.275); + /* left: calc((100vw - 8.875rem) * 0.275); */ + top: 10rem; + left: 17.14375rem; + /* left: 0; */ display: flex; flex-direction: column; - width: 17.1875rem; + /* width: 17.1875rem; */ + width: 13.78125rem; + height: 37.4375rem; border-radius: 0 0 0.625rem 0.625rem; background-color: #4F4F4F; z-index: 0; + overflow-y: auto; } .mainInven-category__modal span{ - width: 17.1875rem; + width: 13.78125rem; height: 3.0625rem; line-height: 3.0625rem; font-size: 1.5625rem; @@ -71,8 +80,11 @@ } .mainInven-category-content__wrapper{ - width: 100%; - height: calc(45.75rem - 5.0625rem); + /* width: 100%; */ + width: calc(64rem - 8.875rem); + /* height: calc(48rem - 5.5rem); */ + /* height: calc(45.75rem - 5.0625rem); */ + height: 37.4375rem; /* height: calc(46.25rem - 5.0625rem); */ /* height: calc(42.5rem - 5.0625rem); */ overflow-y: auto; @@ -92,7 +104,8 @@ display: flex; width: 100%; - min-width: calc(73.75rem - 8.875rem); + /* min-width: calc(73.75rem - 8.875rem); */ + min-width: calc(64rem - 8.875rem); height: 3.6875rem; border-bottom: #dadada solid 0.125rem; } @@ -123,7 +136,7 @@ .mainInven-category-content__span1{ width: 15%; - min-width: 8.3125rem; + min-width: 8.26875rem; display: flex; justify-content: center; @@ -132,20 +145,21 @@ .mainInven-category-content__span2{ width: 25%; - min-width: 17.8125rem; + min-width: 13.78125rem; white-space: nowrap; } .mainInven-category-content__span3{ width: 60%; - min-width: 39.625rem; + /* min-width: 39.625rem; */ + min-width: 33.075rem; white-space: nowrap; } /* 모달 */ -.modal-wrapper{ +.inven-modal-wrapper{ position: absolute; top: 5.5rem; bottom: 0; @@ -157,7 +171,7 @@ display: flex; } -.modal-box{ +.inven-modal-box{ position: absolute; top: calc(50% - 12.15625rem); left: calc(50% - 17.1875rem); @@ -170,32 +184,32 @@ padding: 2.0625rem 3.25rem; } -.modal-close__wrapper{ +.inven-modal-close__wrapper{ display: flex; justify-content: flex-end; } -.modal-box-img__wrapper{ +.inven-modal-box-img__wrapper{ height: 30%; } -.modal-box-txt__wrapper{ +.inven-modal-box-txt__wrapper{ height: 30%; } -.modal-box-txt{ +.inven-modal-box-txt{ font-size: 1.5625rem; font-family: "SemiBold"; } -.modal-box-close-btn__wrapper{ +.inven-modal-box-close-btn__wrapper{ display: flex; flex-direction: column; justify-content: flex-end; height: 30%; } -.modal-box-close-btn{ +.inven-modal-box-close-btn{ width: 19.375rem; height: 3.125rem; margin: 0 auto; diff --git a/src/pages/Inventory/MainInven.jsx b/src/pages/Inventory/MainInven.jsx index acb6886..f867d57 100644 --- a/src/pages/Inventory/MainInven.jsx +++ b/src/pages/Inventory/MainInven.jsx @@ -1,4 +1,5 @@ -import React, { useEffect, useState } from "react"; +import axios from "axios"; +import React, { useCallback, useEffect, useState } from "react"; import close from "../../assets/icons/icon_closeModal.svg"; import downArrow from "../../assets/icons/icon_downArrow.svg"; import upArrow from "../../assets/icons/icon_upArrow.svg"; @@ -8,23 +9,79 @@ import "./MainInven.css"; function MainInven () { + const apiUrl = process.env.REACT_APP_API_ROOT; const [category, setCategory] = useState("전체"); const [isCategoryOpen, setIsCategoryOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); - const categoryList = ["전체", "커피", "논커피", "티", "에이드", "프라페", "스무디", "마카롱", "아이스크림", "와플", "크로플", "베이커리"]; - const chnMenu = () => setIsCategoryOpen(!isCategoryOpen); + // const chnMenu = () => setIsCategoryOpen(!isCategoryOpen); + + const [categoryList, setCategoryList] = useState([]); + const [invenList, setInvenList] = useState([]); + + const fetchData = useCallback(() => { + const config = { + withCredentials: true + }; + + axios.get(`${apiUrl}/api/v1/inventory`, config) + .then((res) => { + console.log(res); + console.log(res.data.categorys.map((e) => e.name)); + setInvenList(res.data); + setCategoryList(["전체", ...res.data.categorys.map((e) => e.name)]); + }) + .catch((err) => console.log(err)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + fetchData(); + }, [fetchData]); + + // const memoizedCategoryList = useMemo(() => { + // return categoryList; + // }, [categoryList]); + + // const memoizedInvenList = useMemo(() => { + // return invenList; + // }, [invenList]); + + // useEffect(() => {console.log(invenList);}, [invenList]); const chnCategory = (e) => { setCategory(e); setIsCategoryOpen((prev) => !prev); } - const handleModal = () => { + const [currentBox, setCurrentBox] = useState({ + "idx": 0, + "soldOut": false + }); + + const handleModal = (idx, soldOut) => { + console.log(idx, !soldOut); setIsModalOpen((prev) => !prev); - // /api/v1/inventory [patch] - // /api/v1/inventory [get] + setCurrentBox({ + "idx": idx, + "soldOut": !soldOut + }); + + fetchData(); + } + + const patchData = () => { + const config = { + withCredentials: true + }; + + axios.patch(`${apiUrl}/api/v1/inventory`, currentBox, config) + .then((res) => { + console.log(res); + setIsModalOpen(false); + }) + .catch((err) => console.log(err)); } useEffect(() => { @@ -41,124 +98,11 @@ function MainInven () { }; }, []); - const invenList = { - "category" : [ - { - "name" : "커피", - "foodies" : [ - { - "idx" : 123, - "name": "아메리카노", - "soldOut" : true, - - }, - { - "idx" : 133, - "name": "라떼", - "soldOut" : false, - - }, - ], - - }, - { - "name" : "티", - "foodies" : [ - { - "idx" : 124, - "name": "녹차", - "soldOut" : true, - - }, - { - "idx" : 143, - "name": "홍차", - "soldOut" : false, - - }, - ], - - }, - { - "name" : "에이드", - "foodies" : [ - { - "idx" : 125, - "name": "망고 에이드", - "soldOut" : true, - - }, - { - "idx" : 153, - "name": "청포도 에이드", - "soldOut" : false, - - }, - ], - - }, - { - "name" : "프라페", - "foodies" : [ - { - "idx" : 126, - "name": "오레오 프라페", - "soldOut" : true, - - }, - { - "idx" : 163, - "name": "초코 프라페", - "soldOut" : false, - - }, - ], - - }, - { - "name" : "스무디", - "foodies" : [ - { - "idx" : 127, - "name": "무화과 스무디", - "soldOut" : true, - - }, - { - "idx" : 173, - "name": "망고 스무디", - "soldOut" : false, - - }, - ], - - }, - { - "name" : "마카롱", - "foodies" : [ - { - "idx" : 128, - "name": "앙버터 마카롱", - "soldOut" : true, - - }, - { - "idx" : 183, - "name": "로투스 마카롱", - "soldOut" : false, - - }, - ], - - }, - ], - }; - return (
품절 -
+
setIsCategoryOpen((prev) => !prev)}> {category} {isCategoryOpen ? (downArrow) : (upArrow)} @@ -168,7 +112,7 @@ function MainInven () { {isCategoryOpen && (
- {categoryList.map((e, i) => ( + {categoryList?.map((e, i) => ( <> chnCategory(e)}>{e}
@@ -178,37 +122,37 @@ function MainInven () { )}
- {invenList.category - .filter((cate) => category === "전체" || cate.name === category) - .map((categoryItem) => - categoryItem.foodies.map((foodItem) => ( -
+ {invenList?.categorys + ?.filter((cate) => category === "전체" || cate.name === category) + ?.map((categoryItem) => + categoryItem?.foodies?.map((foodItem) => ( + handleModal(foodItem.idx, foodItem.soldOut)} invenProps={{ category: categoryItem.name, name: foodItem.name, soldOut: foodItem.soldOut }} /> -
+ ) ))}
{isModalOpen && ( -
-
-
+
+
+
setIsModalOpen((prev) => !prev)}> close
-
cherry
-
-
품절 처리 시
-
고객님은 해당 메뉴를 주문할 수 없습니다.
+
cherry
+
+
품절 처리 시
+
고객님은 해당 메뉴를 주문할 수 없습니다.
-
-
확인
+
+
patchData()}>확인
diff --git a/src/pages/Main/MainPage.css b/src/pages/Main/MainPage.css index a032044..a677b24 100644 --- a/src/pages/Main/MainPage.css +++ b/src/pages/Main/MainPage.css @@ -1,6 +1,6 @@ .mainpage-wrapper{ width: 100%; - /* height: 100%; */ + height: 100vh; background-color: #fff; display: flex; diff --git a/src/pages/Mypage/MainMypage.css b/src/pages/Mypage/MainMypage.css index e45735a..b28b5c1 100644 --- a/src/pages/Mypage/MainMypage.css +++ b/src/pages/Mypage/MainMypage.css @@ -3,8 +3,10 @@ flex-direction: column; padding: 4.3125rem 4rem 2rem 4rem; - width: 100%; - height: calc(100% + 5.5rem); + /* width: 100%; */ + /* height: calc(100% + 5.5rem); */ + width: calc(64rem - 8.875rem); + height: calc(48rem - 5.5rem); justify-content: space-between; } diff --git a/src/pages/Mypage/MainMypage.jsx b/src/pages/Mypage/MainMypage.jsx index 21f5697..9876476 100644 --- a/src/pages/Mypage/MainMypage.jsx +++ b/src/pages/Mypage/MainMypage.jsx @@ -1,5 +1,5 @@ import axios from "axios"; -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useCookies } from "react-cookie"; import { useNavigate } from "react-router-dom"; import { useSetRecoilState } from "recoil"; @@ -15,14 +15,24 @@ const MainMypage = () => { const [, , removeCookies] = useCookies(); const setIsLoggedIn = useSetRecoilState(loginState); const setIsAuthenticated = useSetRecoilState(isAuthenticatedState); + const [cafeInfo, setCafeInfo] = useState({}); - const fetchData = async () => { - // const response = await axios.get(`${process.env.REACT_APP_API_URL}/user/info`); - // console.log(response); + const fetchData = () => { + const config = { + withCredentials: true + }; + + axios.get(`${apiUrl}/api/v1/user/info`, config) + .then((res) => { + console.log(res); + setCafeInfo(res.data); + }) + .catch((err) => console.log(err)); }; useEffect(() => { fetchData(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleLogout = () => { @@ -56,17 +66,15 @@ const MainMypage = () => {
오늘도 준비된 -
- 오르다커피 사장님 -
+
{cafeInfo?.storeName} 사장님
readyvery
- 레디베리 상담 - 매일 00:00 ~ 24:00 + 레디베리 상담 + 매일 09:00 ~ 18:00
kakao @@ -81,26 +89,22 @@ const MainMypage = () => {
가게명 - 오르다커피 + {cafeInfo?.storeName}
가게주소 - - 경기 부천시 지봉로 46 백호빌딩 2층 - + {cafeInfo?.address}
매장 연락처 - 0507-1358-6887 + {cafeInfo?.phone}
영업시간 - - 평일 08:40-23:00 / 토요일 11:00-22:00 / 일요일 휴무 - + {cafeInfo?.openTime}
diff --git a/src/pages/Sales/MainSales.css b/src/pages/Sales/MainSales.css index 17ef6bb..b7dad98 100644 --- a/src/pages/Sales/MainSales.css +++ b/src/pages/Sales/MainSales.css @@ -16,8 +16,12 @@ .sales-total-txt__wrapper{ display: flex; justify-content: space-between; - width: 56.25rem; + /* width: 56.25rem; */ + /* width: 55.125rem; */ + width: 90%; + min-width: calc(55.125rem * 0.9); margin: 0 auto; + white-space: nowrap; } .sales-total-txt{ @@ -34,12 +38,17 @@ } .sales-revenue__wrapper{ - width: 56.25rem; /* 900px */ - height: 34.8125rem; /* 557px */ + /*width: 56.25rem;*/ /* 900px */ + /* width: 55.125rem; */ + width: 90%; + min-width: calc(55.125rem * 0.9); + /* min-width: calc(64rem - 8.875rem); */ + /* height: 34.8125rem; 557px */ + height: 31.5rem; border-radius: 0.625rem; box-shadow: 0 5px 5px rgba(0, 0, 0, 0.25); margin: 0 auto; - padding: 1.65625rem 2.625rem; + padding: 1rem 2.625rem; } .sales-revenue-title{ diff --git a/src/pages/Sales/Sales.css b/src/pages/Sales/Sales.css index 55491e5..0537f5e 100644 --- a/src/pages/Sales/Sales.css +++ b/src/pages/Sales/Sales.css @@ -12,5 +12,6 @@ nav{ main{ width: calc(100vw - 8.875rem); + max-width: 55.125rem; margin-top: 5.5rem; } \ No newline at end of file