diff --git a/.eslintrc.js b/.eslintrc.js index 34d437930f4335db784ff173a694f6a52cd26e83..403e49619126927e57d3d28090d4c1b4a36e872f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,6 +41,7 @@ module.exports = { // react.js "react/react-in-jsx-scope": "off", + "react/prop-types": "off", // typescript "@typescript-eslint/consistent-type-imports": ["error", { @@ -58,6 +59,8 @@ module.exports = { "minimumDescriptionLength": 3 } ], + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", // plugins "import/order": ["error", { diff --git a/src/_app/App.tsx b/src/_app/App.tsx index 2bea1fb47e24f57671d6ca80fe317d7c35b24948..b54e65b7d0204554868e30c2847d4b2b93c211bb 100644 --- a/src/_app/App.tsx +++ b/src/_app/App.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useRef, useState } from 'react'; +import { useContext, useEffect, useRef, useState } from 'react'; import '../common/css/common.css'; import '../common/css/reset.css'; import { Routes, Route, useNavigate } from "react-router-dom"; @@ -30,17 +30,24 @@ import type { CartItemPostModel } from "../pages/cart-page/config/type"; import type { MutableRefObject } from 'react'; + function App() { const { setToastItem } = useContext(ToastContext); const [headerName, setHeaderName] = useState(''); const [login, setLogin] = useState(true); - const connector = new Connector(setLogin); - let socket: MutableRefObject<Socket|null> = useRef(null); + + const connector: MutableRefObject<Connector|null> = useRef(null); + const socket: MutableRefObject<Socket|null> = useRef(null); const navigator = useNavigate(); + useEffect(() => { + connector.current = new Connector(setLogin); + console.log('app', connector.current); + }, []); + useEffect(() => { if (!login) { navigator(APP_ROUTE.LOGIN); @@ -48,7 +55,6 @@ function App() { } socket.current = new Socket(); - console.log(socket.current); socket.current?.onOrder((d: CartItemPostModel) => { console.log(d); @@ -86,7 +92,7 @@ function App() { <Route path={APP_ROUTE.ORDER.SUCCESS} element={<SuccessPage connector={connector} />} /> <Route path={APP_ROUTE.ORDER.FAIL} element={<FailPage />} /> <Route path={APP_ROUTE.ORDER.CANCEL} element={<CancelPage />} /> - <Route path={APP_ROUTE.ADMIN} element={<AdminPage />} /> + <Route path={APP_ROUTE.ADMIN} element={<AdminPage connector={connector} />} /> </Routes> </article> </Wrapper> diff --git a/src/common/constants/index.js b/src/common/constants/index.js index 3c5aa6387d251dbfc9163fa9854ba383610a391a..a97d352d8615228dc861babdb2c529c55cd542ab 100644 --- a/src/common/constants/index.js +++ b/src/common/constants/index.js @@ -6,7 +6,8 @@ const CONFIRM = Object.freeze({ }); const ALERT = Object.freeze({ - REQ_FAIL: '요청에 실패하였습니다' + REQ_FAIL: '요청에 실패하였습니다', + REQ_WRONG: '잘못된 접근입니다' }); diff --git a/src/common/instances/Connector.ts b/src/common/instances/Connector.ts index bf5af4a8f2ff9725aa5e19e40b9057f4e20cd820..f5b69cd17f8c1999d655cf3c71c9cebd069c0f7f 100644 --- a/src/common/instances/Connector.ts +++ b/src/common/instances/Connector.ts @@ -6,18 +6,30 @@ type LoginInstance = Dispatch<SetStateAction<boolean>>; class Connector { private setLoginInstance: LoginInstance; + private isAdmin = false; + private randomUuid = Math.random(); constructor(setLogin: LoginInstance) { + console.log('constructed'); this.setLoginInstance = setLogin; } - async login<T>(payload?: any): Promise<boolean> { + setIsAdmin(b: boolean) { + this.isAdmin = b; + console.log('setIsAdmin', b); + } + + getIsAdmin() { + console.log('getIsAdmin', this.isAdmin); + return this.isAdmin; + } + + async login<T>(payload?: any): Promise<T> { const postRequest = await fetchData<T>('/user/login', FETCH_METHOD.POST, payload); if (postRequest.status === RESPONSE_STATUS.OK) { this.setLoginInstance(true); - return true; } - return false; + return postRequest.response; } async get<T>(url: string, payload?: any): Promise<T> { diff --git a/src/common/instances/Socket.ts b/src/common/instances/Socket.ts index d457e3102223995921b6a3de81ff08695a7a5ecc..4d450a1fd3cf973f16e698f8687f5756e848413c 100644 --- a/src/common/instances/Socket.ts +++ b/src/common/instances/Socket.ts @@ -8,11 +8,11 @@ class Socket { constructor() { this.ioInstance.on('connect', () => { - console.log('Connected to Socket.IO server'); + // console.log('Connected to Socket.IO server'); }); this.ioInstance.on('auth', (e) => { - console.log('auth', e); + // console.log('auth', e); }); } diff --git a/src/common/types/fc.ts b/src/common/types/fc.ts new file mode 100644 index 0000000000000000000000000000000000000000..3e9625fc3b89fbea91a896bf70a8bc110fbc96a1 --- /dev/null +++ b/src/common/types/fc.ts @@ -0,0 +1,13 @@ +import type Connector from "../instances/Connector"; +import type { FC } from "react"; + +interface PageDefaultProp { + connector: { + current: Connector | null; + } +} + +type GFC = FC<PageDefaultProp>; +type GFCWithProp<T> = FC<PageDefaultProp & T>; + +export type { GFC, GFCWithProp }; diff --git a/src/contexts/bottom-sheet/index.tsx b/src/contexts/bottom-sheet/index.tsx index e4f03595dbb82ca5d6e424337d85156bb231637d..193429f0447da7e4cb72cd75fda05e0728e99c80 100644 --- a/src/contexts/bottom-sheet/index.tsx +++ b/src/contexts/bottom-sheet/index.tsx @@ -19,7 +19,7 @@ const BSProvider: FC<pProps> = ({ children }) => { const [item, setItem] = useState<BSContextType['bSElement']>(null); useEffect(() => { - console.log('GLOBAL BSProvider: ', item); + // console.log('GLOBAL BSProvider: ', item); } ,[item]); const setBSElement = (el: ReactNode | null) => { diff --git a/src/contexts/cart/index.tsx b/src/contexts/cart/index.tsx index de51499b661c2affbefa00f26c92ce679796026a..0a8bbd055c06595b4e4f9a759cdb115d377c3cba 100644 --- a/src/contexts/cart/index.tsx +++ b/src/contexts/cart/index.tsx @@ -29,7 +29,7 @@ const CartProvider: FC<pProps> = ({ children }) => { flushCartItem(); } - console.log('GLOBAL CartProvider: ', item); + // console.log('GLOBAL CartProvider: ', item); }, [item]); diff --git a/src/contexts/toast/index.tsx b/src/contexts/toast/index.tsx index 55dc79bc2fdb1dde2117f05db514fb9d5d05413e..7f63ed4c01847da6f792a3115af10302a43e719c 100644 --- a/src/contexts/toast/index.tsx +++ b/src/contexts/toast/index.tsx @@ -19,7 +19,7 @@ const ToastProvider: FC<pProps> = ({ children }) => { useEffect(() => { - console.log('GLOBAL ToastProvider: ', item); + // console.log('GLOBAL ToastProvider: ', item); }, [item]); diff --git a/src/pages/admin-page/AdminPage.tsx b/src/pages/admin-page/AdminPage.tsx index 85ab9aa5d88b822e06d1405703e1c7da6e3b4e9e..49ff62e7574a2e29dc950b17dc75acaf444d7d7f 100644 --- a/src/pages/admin-page/AdminPage.tsx +++ b/src/pages/admin-page/AdminPage.tsx @@ -1,5 +1,30 @@ -const AdminPage = () => { - return (<div>admin</div>); +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; + +import APP_ROUTE from "../../_app/config/route"; +import { ALERT } from "../../common/constants"; + +import type Connector from "../../common/instances/Connector"; +import type { GFC } from "../../common/types/fc"; + + +const AdminPage: GFC = ({ connector }) => { + if (!connector) return <></>; + + const navigator = useNavigate(); + + useEffect(() => { + console.log('adminpage', connector); + // if (!connector.getIsAdmin()) { + // alert(ALERT.REQ_WRONG); + // navigator(APP_ROUTE.LOGIN); + // return; + // } + }, [connector]); + + return ( + <div>admin</div> + ); }; export default AdminPage; diff --git a/src/pages/cart-page/CartPage.tsx b/src/pages/cart-page/CartPage.tsx index 6ffc400be4c16aea3587f64128a5c58c1009599a..7e99ca0cd8f4344892da1c8ebda976b2231d3a2b 100644 --- a/src/pages/cart-page/CartPage.tsx +++ b/src/pages/cart-page/CartPage.tsx @@ -7,18 +7,15 @@ import { sum } from "../../common/utils/jjLodash"; import QuantityController from "../../components/quantity-controller/QuantityController"; import { CartContext } from "../../contexts/cart"; - import S from './CartPage.module.css'; import type { CartItemData, OrderPostModel } from "./config/type"; -import type Connector from "../../common/instances/Connector"; -import type { FC } from "react"; +import type { GFC } from "../../common/types/fc"; -interface Props { - connector: Connector; -} -const CartPage: FC<Props> = ({ connector }) => { +const CartPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const { cartItem, setCartItem } = useContext(CartContext); const [quantities, setQuantities] = useState<number[]>([]); const [totalPrice, setTotalPrice] = useState(0); @@ -54,7 +51,7 @@ const CartPage: FC<Props> = ({ connector }) => { try { const _device = detectDeviceType(); - const orderRequest = await connector.post<OrderPostModel>('/order', { + const orderRequest = await connector.current!.post<OrderPostModel>('/order', { shopId: cartItem.shop._id, items: cartItem.menus.map((d) => ({ menuId: d._id, quantity: d.quantity })), takeout: cartItem.takeout diff --git a/src/pages/history-page/HistoryPage.tsx b/src/pages/history-page/HistoryPage.tsx index f74ce27e5609d0547251fc429d1444e52979e562..d62155f06c8b4e036aaab06858986e17218db596 100644 --- a/src/pages/history-page/HistoryPage.tsx +++ b/src/pages/history-page/HistoryPage.tsx @@ -5,21 +5,19 @@ import { ALERT } from "../../common/constants"; import OrderBox from "./modules/order-box/OrderBox"; import type { HistoryPageModel } from "./config/type"; -import type Connector from "../../common/instances/Connector"; -import type { FC } from "react"; +import type { GFC } from "../../common/types/fc"; -interface Props { - connector: Connector; -} -const HistoryPage: FC<Props> = ({ connector }) => { +const HistoryPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const [model, setModel] = useState<HistoryPageModel|null>(null); useEffect(() => { void (async () => { try { - const response = await connector.get<HistoryPageModel>('/order'); + const response = await connector.current!.get<HistoryPageModel>('/order'); setModel(response); } catch { alert(ALERT.REQ_FAIL); @@ -30,7 +28,7 @@ const HistoryPage: FC<Props> = ({ connector }) => { <div> { model && model.map((d, i) => ( - <OrderBox waitingCount={d.waitingCount} name={'menu_name'} + <OrderBox waitingCount={d.waitingCount} name={'menu_name'} price={d.totalPrice} status={d.status} shop={'shop_name'} takeout={d.takeout} key={`orderbox-${i}`} /> diff --git a/src/pages/login-page/LoginPage.tsx b/src/pages/login-page/LoginPage.tsx index e70595e2aacb25ecffc9815ec85465d536a8d1c2..3c62822d4cf892154efd8293e29df8342cf19f6f 100644 --- a/src/pages/login-page/LoginPage.tsx +++ b/src/pages/login-page/LoginPage.tsx @@ -3,24 +3,21 @@ import { useNavigate } from "react-router-dom"; import APP_ROUTE from "../../_app/config/route"; + import S from './LoginPage.module.css'; import type { LoginPagePostModel } from "./config/type"; -import type Connector from "../../common/instances/Connector"; -import type { FC } from "react"; - +import type { GFC } from "../../common/types/fc"; -interface Props { - connector: Connector; -} -const LoginPage: FC<Props> = ({ connector }) => { +const LoginPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const [account, setAccount] = useState({ loginId: '', password: '' }); const navigate = useNavigate(); - const handleChangeId = (e: any) => { setAccount((prev) => ({ ...prev, @@ -41,8 +38,15 @@ const LoginPage: FC<Props> = ({ connector }) => { const handleLogin = () => { void (async () => { try { - await connector.login<LoginPagePostModel>(account); - navigate(APP_ROUTE.MAIN); + const response = await connector.current!.login<LoginPagePostModel>(account); + if (response.role?.isAdmin) { + connector.current!.setIsAdmin(true); + console.log('loginpage', connector); + navigate(APP_ROUTE.ADMIN); + } else { + connector.current!.setIsAdmin(false); + navigate(APP_ROUTE.MAIN); + } } catch (e) { console.error(e); } diff --git a/src/pages/main-page/MainPage.tsx b/src/pages/main-page/MainPage.tsx index 77f70ebf849f8a0bd516fb8f1f2eb62487ce9cc8..d7c625ac62fbc70c4804f175c096f8fa060ee556 100644 --- a/src/pages/main-page/MainPage.tsx +++ b/src/pages/main-page/MainPage.tsx @@ -3,26 +3,25 @@ import { Link } from "react-router-dom"; import { ALERT } from "../../common/constants"; + import S from "./MainPage.module.css"; import ShopBox from "./modules/shop-box/ShopBox"; import type { MainPageModel } from "./config/type"; -import type Connector from "../../common/instances/Connector"; -import type { FC } from "react"; +import type { GFC } from "../../common/types/fc"; -interface Props { - connector: Connector; -} -const MainPage: FC<Props> = ({ connector }) => { +const MainPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const [model, setModel] = useState<MainPageModel|null>(null); useEffect(() => { void (async () => { try { - const response = await connector.get<MainPageModel>('/shop'); - setModel(response); + const response = await connector.current!.get<MainPageModel>('/shop'); + setModel(response as MainPageModel); } catch { alert(ALERT.REQ_FAIL); } diff --git a/src/pages/menu-page/MenuPage.tsx b/src/pages/menu-page/MenuPage.tsx index 024d64c880de6e7410bd9ce2985ccb9029adf728..88ff2ea0a2e5cf0e205db3a69d17626d4b91f606 100644 --- a/src/pages/menu-page/MenuPage.tsx +++ b/src/pages/menu-page/MenuPage.tsx @@ -6,23 +6,24 @@ import { ALERT } from "../../common/constants"; import MenuBox from "./modules/menu-box/MenuBox"; import type { MenuPageModel } from "./config/type"; -import type Connector from "../../common/instances/Connector"; -import type { Dispatch, FC, SetStateAction } from "react"; +import type { GFCWithProp } from "../../common/types/fc"; +import type { Dispatch, SetStateAction } from "react"; interface Props { - connector: Connector; setHeaderName: Dispatch<SetStateAction<string>>; } -const MenuPage: FC<Props> = ({ connector, setHeaderName }) => { +const MenuPage: GFCWithProp<Props> = ({ connector, setHeaderName }) => { + if (!connector) return <></>; + const [model, setModel] = useState<MenuPageModel|null>(null); const { pathname } = useLocation(); useEffect(() => { void (async () => { try { - const response = await connector.get<MenuPageModel>( + const response = await connector.current!.get<MenuPageModel>( `/shop/${pathname.split('/').at(2)}/menu`, ); setModel(response); diff --git a/src/pages/order-page/success-page/SuccessPage.tsx b/src/pages/order-page/success-page/SuccessPage.tsx index 1e99e6542b79ece9e35738b67ce2e66370adbbe9..269db00c4b7d1a6a3a3628a79eb18dfaae675b52 100644 --- a/src/pages/order-page/success-page/SuccessPage.tsx +++ b/src/pages/order-page/success-page/SuccessPage.tsx @@ -4,14 +4,12 @@ import { useLocation } from "react-router-dom"; import { getQueryStrings } from "../../../common/utils/query"; import type { OrderApprovePostModel } from "./config/type"; -import type Connector from "../../../common/instances/Connector"; -import type { FC } from "react"; +import type { GFC } from "../../../common/types/fc"; -interface Props { - connector: Connector; -} -const SuccessPage: FC<Props> = ({ connector }) => { +const SuccessPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const location = useLocation(); useEffect(() => { @@ -19,7 +17,7 @@ const SuccessPage: FC<Props> = ({ connector }) => { void (async () => { try { - await connector.post<OrderApprovePostModel>('/order/approve', { + await connector.current!.post<OrderApprovePostModel>('/order/approve', { pg_token: getQueryStrings(location.search, 'pg_token'), payment_id: localStorage.getItem('payment_id'), }); diff --git a/src/pages/signup-page/SignupPage.tsx b/src/pages/signup-page/SignupPage.tsx index 773f0b6d6bbd0fa087029d3936be56d0d8cc7f86..e0694b1b9dd8b964ab11ce7e78da2bec2fa897ab 100644 --- a/src/pages/signup-page/SignupPage.tsx +++ b/src/pages/signup-page/SignupPage.tsx @@ -3,16 +3,15 @@ import { useNavigate } from "react-router-dom"; import APP_ROUTE from "../../_app/config/route"; -import S from './SignupPage.module.css'; -import type Connector from "../../common/instances/Connector"; +import S from './SignupPage.module.css'; +import type { GFC } from "../../common/types/fc"; -interface Props { - connector: Connector; -} -const SignupPage: React.FC<Props> = ({ connector }) => { +const SignupPage: GFC = ({ connector }) => { + if (!connector) return <></>; + const navigate = useNavigate(); const [accountData, setAccountData] = useState({ loginId: '', @@ -83,7 +82,7 @@ const SignupPage: React.FC<Props> = ({ connector }) => { ){ try { void(async () => { - await connector.post('/user/register', accountData); + await connector.current!.post('/user/register', accountData); navigate(APP_ROUTE.LOGIN); })(); } catch (e) {