From 2dca0d8a863b2a8ed92f1ff2423061b6b3ee75ab Mon Sep 17 00:00:00 2001 From: Chun Yu Date: Thu, 19 Jan 2023 10:38:18 +0800 Subject: [PATCH 1/2] Implement Crowd Frontend --- frontend/package.json | 1 + frontend/src/components/Crowd/CrowdLevel.tsx | 95 ++++++++++++++++++++ frontend/src/routes/Crowd/index.tsx | 54 +++++++++++ frontend/src/routes/Routes.tsx | 8 ++ frontend/yarn.lock | 56 ++++++++++++ 5 files changed, 214 insertions(+) create mode 100644 frontend/src/components/Crowd/CrowdLevel.tsx create mode 100644 frontend/src/routes/Crowd/index.tsx diff --git a/frontend/package.json b/frontend/package.json index 399074e52..075c158bd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -56,6 +56,7 @@ "redux": "^4.0.5", "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0", + "socket.io-client": "^4.5.4", "styled-components": "^5.2.1", "typedoc": "^0.23.14", "typescript": "^4.8.3", diff --git a/frontend/src/components/Crowd/CrowdLevel.tsx b/frontend/src/components/Crowd/CrowdLevel.tsx new file mode 100644 index 000000000..03d8133d1 --- /dev/null +++ b/frontend/src/components/Crowd/CrowdLevel.tsx @@ -0,0 +1,95 @@ +import React from 'react' +import styled from 'styled-components' + +// MAGIC NUMBERS +const HIGH = 45 +const MEDIUM = 20 +const LOW = 0 + +const LevelContainer = styled.div` + display: flex; + justify-content: space-evenly; + align-items: center; + padding: 5px; + border: 1px solid; + min-height: 70px; + border-radius: 20px; + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); +` + +const LevelHeader = styled.h2` + font-weight: 600; + font-size: 17px; + margin: 8.5px 0; +` + +const TextContainer = styled.div` + display: flex; + flex-direction: column; +` + +const LevelText = styled.p` + font-size: 25px; + font-weight: 500; + color: ${(props) => { + if (props.level == null) { + return 'default' + } + + if (props.level > HIGH) { + return 'red' + } + + if (props.level > MEDIUM) { + return 'orange' + } + + if (props.level > LOW) { + return 'green' + } + return 'default' + }}; +` + +type CrowdProps = { + name: string + level: number | null + icon: React.ReactNode +} + +type LevelProps = { + level: number | null +} + +export const CrowdLevel = (props: CrowdProps) => { + const getCrowdText = (level: number | null): string => { + if (level == null) { + return `Undefined at this moment` + } + + const roundedLevel: number = +level.toFixed(2) + + if (roundedLevel > HIGH) { + return `HIGH (${roundedLevel})` + } + + if (roundedLevel > MEDIUM) { + return `MEDIUM (${roundedLevel})` + } + + if (roundedLevel > LOW) { + return `LOW (${roundedLevel})` + } + return `Undefined at this moment` + } + + return ( + + {props.icon} + + {props.name} + {getCrowdText(props.level)} + + + ) +} diff --git a/frontend/src/routes/Crowd/index.tsx b/frontend/src/routes/Crowd/index.tsx new file mode 100644 index 000000000..2f17ead30 --- /dev/null +++ b/frontend/src/routes/Crowd/index.tsx @@ -0,0 +1,54 @@ +import React, { useEffect, useState } from 'react' +import styled from 'styled-components' +import io from 'socket.io-client' +import BottomNavBar from '../../components/Mobile/BottomNavBar' +import { CrowdLevel } from '../../components/Crowd/CrowdLevel' +import CommHallIcon from '../../assets/facilitiesLogos/MainAreaCommHall.svg' + +const socket = io('https://crowd.api.rhapp.lol') + +const CrowdIcon = styled.img` + width: 60px; + height: 60px; +` + +const CrowdMainContainer = styled.div` + background-color: #fff; + height: 100vh; + margin: 23px; +` + +export default function Crowd() { + const [isConnected, setIsConnected] = useState(socket.connected) + const [crowdLevelCH, setCrowdLevelCH] = useState(null) + + useEffect(() => { + socket.on('connect', () => { + setIsConnected(true) + }) + + socket.on('disconnect', () => { + setIsConnected(false) + }) + + socket.on('crowd-level:ch', (data) => { + setCrowdLevelCH(data.level) + }) + + return () => { + socket.off('connect') + socket.off('disconnect') + socket.off('crowd-level:ch') + } + }, []) + + return ( + <> + +

Crowd Levels

+ } /> +
+ + + ) +} diff --git a/frontend/src/routes/Routes.tsx b/frontend/src/routes/Routes.tsx index f1f7c0471..284a4c2a3 100644 --- a/frontend/src/routes/Routes.tsx +++ b/frontend/src/routes/Routes.tsx @@ -109,6 +109,9 @@ export enum PATHS { //GYM GYM_MAIN = '/gym', + + //CROWD + CROWD_MAIN = '/crowd', } //DOCUMENTATION @@ -212,6 +215,9 @@ const Payment = React.lazy(() => import(/* webpackChuckName: "Payment" */ './Sup //GYM const Gym = React.lazy(() => import(/* webpackChunckName: "Gym" */ './GymPage')) + +//CROWD +const Crowd = React.lazy(() => import(/* webpackChunckName: "Gym" */ './Crowd')) export default class Routes extends React.Component { render() { return ( @@ -284,6 +290,8 @@ export default class Routes extends React.Component { + + diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 722303542..570188104 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1556,6 +1556,11 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + "@surma/rollup-plugin-off-main-thread@^1.1.1": version "1.4.2" resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz" @@ -4421,6 +4426,13 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz" @@ -4855,6 +4867,22 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" +engine.io-client@~6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.2.3.tgz#a8cbdab003162529db85e9de31575097f6d29458" + integrity sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + xmlhttprequest-ssl "~2.0.0" + +engine.io-parser@~5.0.3: + version "5.0.6" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.6.tgz#7811244af173e157295dec9b2718dfe42a64ef45" + integrity sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw== + enhanced-resolve@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz" @@ -12268,6 +12296,24 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +socket.io-client@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.5.4.tgz#d3cde8a06a6250041ba7390f08d2468ccebc5ac9" + integrity sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.2" + engine.io-client "~6.2.3" + socket.io-parser "~4.2.1" + +socket.io-parser@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.1.tgz#01c96efa11ded938dcb21cbe590c26af5eff65e5" + integrity sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + sockjs-client@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz" @@ -14029,6 +14075,11 @@ ws@^7.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz" integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz" @@ -14039,6 +14090,11 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz" From 16fca0c0080298dafa2e4ff6d7ec366a2b521a16 Mon Sep 17 00:00:00 2001 From: Chun Yu Date: Thu, 19 Jan 2023 11:24:33 +0800 Subject: [PATCH 2/2] Update landing page --- frontend/src/routes/Home/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/Home/index.tsx b/frontend/src/routes/Home/index.tsx index aeef75048..115395f02 100644 --- a/frontend/src/routes/Home/index.tsx +++ b/frontend/src/routes/Home/index.tsx @@ -96,11 +96,11 @@ export default function Home() { }, }, { - name: 'gym', + name: 'crowd', src: gym_icon, filter: 'brightness(5)', clickHandler: () => { - history.push(PATHS.GYM_MAIN) + history.push(PATHS.CROWD_MAIN) }, }, {