diff --git a/package-lock.json b/package-lock.json index 2487a2258efd4d8b8c41bb157f824ce54f7d1cc7..eebb9801a94f9afcd6109058e86be670ac8475ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "react-dom": "^18.2.0", "react-router-dom": "^6.16.0", "react-scripts": "5.0.1", + "socket.io-client": "^4.7.2", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, @@ -3344,6 +3345,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -6845,6 +6851,46 @@ "node": ">= 0.8" } }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -15393,6 +15439,32 @@ "node": ">=8" } }, + "node_modules/socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -17606,6 +17678,14 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -19871,6 +19951,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -22459,6 +22544,31 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, + "engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + }, + "dependencies": { + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==" + }, "enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -28459,6 +28569,26 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + } + }, + "socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -30133,6 +30263,11 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 083665f904ac0faf8d040a19ed9233b18580a580..7afe1eea0f126e221080d571571342eb3ff13578 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "react-dom": "^18.2.0", "react-router-dom": "^6.16.0", "react-scripts": "5.0.1", + "socket.io-client": "^4.7.2", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, diff --git a/src/_app/App.tsx b/src/_app/App.tsx index f1dab050c6b499440a033c7bb2309d96e1ee340e..0b6823c71270cb95ac49dba61950fc3eefdf36e4 100644 --- a/src/_app/App.tsx +++ b/src/_app/App.tsx @@ -1,15 +1,16 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import '../common/css/common.css'; import '../common/css/reset.css'; import { Routes, Route, useNavigate } from "react-router-dom"; import Connector from "../common/instances/Connector"; +import Socket from "../common/instances/Socket"; import BottomSheet from "../components/bottom-sheet/BottomSheet"; import Header from "../components/header/Header"; import Toast from "../components/toast/Toast"; import { BSProvider } from "../contexts/bottom-sheet"; import { CartProvider } from "../contexts/cart"; -import { ToastProvider } from "../contexts/toast"; +import { ToastContext, ToastProvider } from "../contexts/toast"; import CartPage from "../pages/cart-page/CartPage"; import HistoryPage from "../pages/history-page/HistoryPage"; import LoginPage from "../pages/login-page/LoginPage"; @@ -24,20 +25,34 @@ import S from './App.module.css'; import APP_ROUTE from "./config/route"; import Wrapper from "./modules/wrapper/Wrapper"; +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 navigator = useNavigate(); + useEffect(() => { - console.log('GLOBAL loginState: ', login); - if (!login) navigator(APP_ROUTE.LOGIN); - // else navigator(APP_ROUTE.MAIN); + if (!login) { + navigator(APP_ROUTE.LOGIN); + return; + } + + socket.current = new Socket(); + console.log(socket.current); + + return () => socket.current?.disconnect(); }, [login]); + + return ( <BSProvider> <ToastProvider> diff --git a/src/common/instances/Socket.ts b/src/common/instances/Socket.ts new file mode 100644 index 0000000000000000000000000000000000000000..d457e3102223995921b6a3de81ff08695a7a5ecc --- /dev/null +++ b/src/common/instances/Socket.ts @@ -0,0 +1,28 @@ +import { io } from "socket.io-client"; + +import { SOCKET_URL } from "../utils/api"; + + +class Socket { + private ioInstance = io(SOCKET_URL, { withCredentials: true }); + + constructor() { + this.ioInstance.on('connect', () => { + console.log('Connected to Socket.IO server'); + }); + + this.ioInstance.on('auth', (e) => { + console.log('auth', e); + }); + } + + onOrder(listener: (a: any) => void) { + return this.ioInstance.on('order', listener); + } + + disconnect() { + this.ioInstance.disconnect(); + } +} + +export default Socket; diff --git a/src/common/utils/api.ts b/src/common/utils/api.ts index 721ce865448b510b1d5189056dd3aadfae1c168a..b6c4cbedf8f599bd825db80eb3c0c2e530d0c9ec 100644 --- a/src/common/utils/api.ts +++ b/src/common/utils/api.ts @@ -16,7 +16,11 @@ type FetchMethod = typeof FETCH_METHOD[keyof typeof FETCH_METHOD]; const DEV_API_URL = 'http://localhost:8080'; const PROD_API_URL = ''; +const DEV_SOCKET_URL = 'ws://localhost:8080'; +const PROD_SOCKET_URL = ''; + const API_URL = process.env.NODE_ENV === 'production' ? PROD_API_URL : DEV_API_URL; +const SOCKET_URL = process.env.NODE_ENV === 'production' ? PROD_SOCKET_URL : DEV_SOCKET_URL; /** * @name fetchData @@ -55,4 +59,4 @@ async function fetchData<T> ( return { status, response }; } -export { fetchData, FETCH_METHOD, RESPONSE_STATUS }; +export { fetchData, FETCH_METHOD, RESPONSE_STATUS, SOCKET_URL }; diff --git a/src/components/toast/Toast.tsx b/src/components/toast/Toast.tsx index 3c60261270c18bcc07d1ff3f140bd285e906c564..a77e3b75f699bf3768d112ce72a5a0f081c4beb7 100644 --- a/src/components/toast/Toast.tsx +++ b/src/components/toast/Toast.tsx @@ -6,17 +6,18 @@ import { ToastContext } from "../../contexts/toast"; import S from './Toast.module.css'; -import type { ReactNode,FC } from 'react'; +import type { ReactNode, FC } from 'react'; // TODO:: Consider about lots of toasts. T^T const Toast: FC = () => { - const { toastItem } = useContext(ToastContext); + const { toastItem, setToastItem } = useContext(ToastContext); const [retEl, setRetEl] = useState<ReactNode>(<></>); const navigator = useNavigate(); const removeToast = () => { setRetEl(<></>); + setToastItem(null); }; const handleClickToast = (goto?: string) => { diff --git a/src/contexts/toast/index.tsx b/src/contexts/toast/index.tsx index 54d243519e519e29f634bdca6802dc1c51e9a35e..55dc79bc2fdb1dde2117f05db514fb9d5d05413e 100644 --- a/src/contexts/toast/index.tsx +++ b/src/contexts/toast/index.tsx @@ -5,7 +5,7 @@ import type { FC, ReactNode } from "react"; interface ToastContextType { toastItem: ToastData | null - setToastItem: (d: ToastData) => void; + setToastItem: (d: ToastData | null) => void; } const ToastContext = createContext<ToastContextType>({ @@ -23,8 +23,8 @@ const ToastProvider: FC<pProps> = ({ children }) => { }, [item]); - const setToastItem = (toastItem: ToastData) => { - setItem(() => toastItem); + const setToastItem = (toastItem: ToastData | null) => { + setItem(toastItem); };