From 9c67076aadcd635d0a3e26465704fb329bda525d Mon Sep 17 00:00:00 2001 From: Cailyn Sinclair Date: Thu, 9 Jul 2026 19:05:15 -0700 Subject: [PATCH 1/3] Modernize legacy dependencies Replace abandoned session and analytics integrations, move the client and tooling onto supported versions, and add automated dependency and code security checks. --- .github/dependabot.yml | 17 + .github/workflows/codeql.yml | 33 + .husky/pre-commit | 1 + client/.eslintignore | 3 - client/.eslintrc | 19 - client/babel.config.cjs | 6 + client/config/env.js | 93 - client/config/jest/cssTransform.js | 14 - client/config/jest/fileTransform.js | 40 - client/config/paths.js | 90 - client/eslint.config.cjs | 62 + client/jest.config.cjs | 14 + client/package.json | 144 +- client/scripts/test.js | 53 - client/src/components/Admin/RoomCard.jsx | 18 +- client/src/components/Admin/index.jsx | 8 +- client/src/components/App.jsx | 8 +- client/src/components/App.test.jsx | 18 +- client/src/components/Footer.jsx | 27 +- client/src/components/Header.jsx | 20 +- client/src/components/Lobby/Announcements.jsx | 4 +- .../components/Lobby/Announcements.test.jsx | 22 +- client/src/components/Lobby/UserList.jsx | 18 +- client/src/components/Lobby/index.jsx | 43 +- client/src/components/Navigation.jsx | 10 +- .../components/Room/Common/AdminToolbar.jsx | 18 +- .../src/components/Room/Common/EditDialog.jsx | 16 +- client/src/components/Room/Common/Login.jsx | 12 +- client/src/components/Room/Common/Main.jsx | 16 +- .../Room/Common/ManageUsersDialog.jsx | 28 +- client/src/components/Room/Common/Panel.jsx | 8 +- .../components/Room/Common/StatsDialog.jsx | 16 +- .../Room/Common/TableStatusCell.jsx | 6 +- .../components/Room/Common/TableTimeCell.jsx | 8 +- .../src/components/Room/Common/TimesTable.jsx | 16 +- .../Room/Common/UserSelectorDialog.jsx | 26 +- .../src/components/Room/Common/UserStats.jsx | 14 +- .../components/Room/Common/UserToolbar.jsx | 30 +- .../Room/GrandPrix/GrandPrixMain.jsx | 19 +- .../components/Room/GrandPrix/Leaderboard.jsx | 20 +- .../Room/GrandPrix/RegisterPanel.jsx | 8 +- .../src/components/Room/GrandPrix/index.jsx | 28 +- client/src/components/Room/Normal/index.jsx | 16 +- client/src/components/Room/Panels/Chat.jsx | 38 +- client/src/components/Room/index.jsx | 8 +- client/src/components/RoomConfigureDialog.jsx | 40 +- client/src/components/RoomListItem.jsx | 24 +- client/src/components/Timer/ManualTimer.jsx | 18 +- client/src/components/Timer/SpacebarTimer.jsx | 18 +- client/src/components/Timer/StackmatTimer.jsx | 18 +- client/src/components/Timer/index.jsx | 2 +- client/src/components/User.jsx | 8 +- client/src/components/WCARedirect.jsx | 14 +- .../components/common/EditableTextField.jsx | 18 +- .../src/components/common/EventListItem.jsx | 37 +- client/src/components/common/HelpPopover.jsx | 12 +- client/src/components/common/ListItemLink.jsx | 2 +- client/src/components/common/PrivateRoute.jsx | 7 +- client/src/components/common/Profile.jsx | 18 +- client/src/components/common/Scramble.jsx | 6 +- .../src/components/common/Scramble.test.jsx | 18 +- .../src/components/common/TableCellButton.jsx | 10 +- client/src/custom-service-worker.js | 2 +- client/src/index.jsx | 8 +- client/src/lib/Namespace.js | 6 +- client/src/lib/events.js | 146 +- client/src/lib/events.json | 24 + client/src/lib/protocol.js | 52 +- client/src/lib/protocol.json | 48 + client/src/lib/utils.js | 3 +- client/src/setupTests.js | 9 +- client/src/store/index.js | 30 +- client/src/store/middlewares/default.js | 2 +- client/src/store/middlewares/rooms.js | 22 +- client/src/theme.jsx | 18 +- client/test/fileMock.js | 1 + client/vite.config.mjs | 2 +- compose.yml | 2 +- docker-compose.yml | 2 +- package.json | 8 +- server/.eslintrc.json | 29 - server/auth/index.js | 19 +- server/eslint.config.cjs | 32 + server/index.js | 5 +- server/middlewares/session.js | 8 +- server/models/room.js | 3 +- server/models/room.test.js | 1 - server/package.json | 25 +- server/runtimeConfig.js | 2 +- server/socket/index.js | 8 +- server/socket/lib/commands.js | 2 +- server/socket/lib/roomAuthorization.test.js | 1 - server/socket/lib/roomMap.test.js | 1 - server/socket/lib/roomSockets.test.js | 1 - server/socket/lib/socketHandler.test.js | 1 - server/socket/middlewares/authenticate.js | 4 +- .../middlewares/wrapExpressMiddleware.js | 3 + .../middlewares/wrapExpressMiddleware.test.js | 16 + server/socket/namespaces/default.js | 2 +- server/socket/namespaces/rooms.js | 2 +- yarn.lock | 7129 ++++++----------- 101 files changed, 3070 insertions(+), 6015 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .husky/pre-commit delete mode 100644 client/.eslintignore delete mode 100644 client/.eslintrc create mode 100644 client/babel.config.cjs delete mode 100644 client/config/env.js delete mode 100644 client/config/jest/cssTransform.js delete mode 100644 client/config/jest/fileTransform.js delete mode 100644 client/config/paths.js create mode 100644 client/eslint.config.cjs create mode 100644 client/jest.config.cjs delete mode 100644 client/scripts/test.js create mode 100644 client/src/lib/events.json create mode 100644 client/src/lib/protocol.json create mode 100644 client/test/fileMock.js delete mode 100644 server/.eslintrc.json create mode 100644 server/eslint.config.cjs create mode 100644 server/socket/middlewares/wrapExpressMiddleware.js create mode 100644 server/socket/middlewares/wrapExpressMiddleware.test.js diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..301fce0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + + - package-ecosystem: docker + directory: / + schedule: + interval: weekly + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..700b698 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,33 @@ +name: CodeQL + +on: + pull_request: + push: + branches: + - master + schedule: + - cron: '23 10 * * 1' + +permissions: + contents: read + +jobs: + analyze: + name: Analyze JavaScript + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: javascript-typescript + + - name: Analyze + uses: github/codeql-action/analyze@v4 diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..4f3315a --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +yarn lint && yarn test diff --git a/client/.eslintignore b/client/.eslintignore deleted file mode 100644 index 12a8fb3..0000000 --- a/client/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -build/** -config/** -scripts/** \ No newline at end of file diff --git a/client/.eslintrc b/client/.eslintrc deleted file mode 100644 index 2ae4b20..0000000 --- a/client/.eslintrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": [ - "react-app", - "airbnb", - "plugin:jsx-a11y/recommended" - ], - "plugins": [ - "jsx-a11y" - ], - "rules": { - "semi": 1, - "no-underscore-dangle": 0, - "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], - "no-console": "warn", - "react/jsx-props-no-spreading": [1, { - "custom": "ignore" - }] - } -} \ No newline at end of file diff --git a/client/babel.config.cjs b/client/babel.config.cjs new file mode 100644 index 0000000..9349078 --- /dev/null +++ b/client/babel.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + ['@babel/preset-react', { runtime: 'automatic' }], + ], +}; diff --git a/client/config/env.js b/client/config/env.js deleted file mode 100644 index 856fc7d..0000000 --- a/client/config/env.js +++ /dev/null @@ -1,93 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const paths = require('./paths'); - -// Make sure that including paths.js after env.js will read .env variables. -delete require.cache[require.resolve('./paths')]; - -const NODE_ENV = process.env.NODE_ENV; -if (!NODE_ENV) { - throw new Error( - 'The NODE_ENV environment variable is required but was not specified.' - ); -} - -// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use -const dotenvFiles = [ - `${paths.dotenv}.${NODE_ENV}.local`, - `${paths.dotenv}.${NODE_ENV}`, - // Don't include `.env.local` for `test` environment - // since normally you expect tests to produce the same - // results for everyone - NODE_ENV !== 'test' && `${paths.dotenv}.local`, - paths.dotenv, -].filter(Boolean); - -// Load environment variables from .env* files. Suppress warnings using silent -// if this file is missing. dotenv will never modify any environment variables -// that have already been set. Variable expansion is supported in .env files. -// https://github.com/motdotla/dotenv -// https://github.com/motdotla/dotenv-expand -dotenvFiles.forEach(dotenvFile => { - if (fs.existsSync(dotenvFile)) { - require('dotenv-expand')( - require('dotenv').config({ - path: dotenvFile, - }) - ); - } -}); - -// We support resolving modules according to `NODE_PATH`. -// This lets you use absolute paths in imports inside large monorepos: -// https://github.com/facebook/create-react-app/issues/253. -// It works similar to `NODE_PATH` in Node itself: -// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders -// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. -// Otherwise, we risk importing Node.js core modules into the browser bundle. -// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 -// We also resolve them to make sure all tools using them work consistently. -const appDirectory = fs.realpathSync(process.cwd()); -process.env.NODE_PATH = (process.env.NODE_PATH || '') - .split(path.delimiter) - .filter(folder => folder && !path.isAbsolute(folder)) - .map(folder => path.resolve(appDirectory, folder)) - .join(path.delimiter); - -// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be -// injected into the application by the frontend build configuration. -const REACT_APP = /^REACT_APP_/i; - -function getClientEnvironment(publicUrl) { - const raw = Object.keys(process.env) - .filter(key => REACT_APP.test(key)) - .reduce( - (env, key) => { - env[key] = process.env[key]; - return env; - }, - { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - NODE_ENV: process.env.NODE_ENV || 'development', - // Useful for resolving the correct path to static assets in `public`. - // For example, . - // This should only be used as an escape hatch. Normally you would put - // images into the `src` and `import` them in code to get their paths. - PUBLIC_URL: publicUrl, - } - ); - // Stringify all values for Jest's Babel-based test environment. - const stringified = { - 'process.env': Object.keys(raw).reduce((env, key) => { - env[key] = JSON.stringify(raw[key]); - return env; - }, {}), - }; - - return { raw, stringified }; -} - -module.exports = getClientEnvironment; diff --git a/client/config/jest/cssTransform.js b/client/config/jest/cssTransform.js deleted file mode 100644 index 8f65114..0000000 --- a/client/config/jest/cssTransform.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -// This is a custom Jest transformer turning style imports into empty objects. -// http://facebook.github.io/jest/docs/en/webpack.html - -module.exports = { - process() { - return 'module.exports = {};'; - }, - getCacheKey() { - // The output is always the same. - return 'cssTransform'; - }, -}; diff --git a/client/config/jest/fileTransform.js b/client/config/jest/fileTransform.js deleted file mode 100644 index aab6761..0000000 --- a/client/config/jest/fileTransform.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -const path = require('path'); -const camelcase = require('camelcase'); - -// This is a custom Jest transformer turning file imports into filenames. -// http://facebook.github.io/jest/docs/en/webpack.html - -module.exports = { - process(src, filename) { - const assetFilename = JSON.stringify(path.basename(filename)); - - if (filename.match(/\.svg$/)) { - // Based on how SVGR generates a component name: - // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 - const pascalCaseFilename = camelcase(path.parse(filename).name, { - pascalCase: true, - }); - const componentName = `Svg${pascalCaseFilename}`; - return `const React = require('react'); - module.exports = { - __esModule: true, - default: ${assetFilename}, - ReactComponent: React.forwardRef(function ${componentName}(props, ref) { - return { - $$typeof: Symbol.for('react.element'), - type: 'svg', - ref: ref, - key: null, - props: Object.assign({}, props, { - children: ${assetFilename} - }) - }; - }), - };`; - } - - return `module.exports = ${assetFilename};`; - }, -}; diff --git a/client/config/paths.js b/client/config/paths.js deleted file mode 100644 index a53d246..0000000 --- a/client/config/paths.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; - -const path = require('path'); -const fs = require('fs'); -const url = require('url'); - -// Make sure any symlinks in the project folder are resolved: -// https://github.com/facebook/create-react-app/issues/637 -const appDirectory = fs.realpathSync(process.cwd()); -const resolveApp = relativePath => path.resolve(appDirectory, relativePath); - -const envPublicUrl = process.env.PUBLIC_URL; - -function ensureSlash(inputPath, needsSlash) { - const hasSlash = inputPath.endsWith('/'); - if (hasSlash && !needsSlash) { - return inputPath.substr(0, inputPath.length - 1); - } else if (!hasSlash && needsSlash) { - return `${inputPath}/`; - } else { - return inputPath; - } -} - -const getPublicUrl = appPackageJson => - envPublicUrl || require(appPackageJson).homepage; - -// We use `PUBLIC_URL` environment variable or "homepage" field to infer -// "public path" at which the app is served. -// The build needs to know it to put the right asset hrefs into HTML even in -// single-page apps that may serve index.html for nested URLs like /todos/42. -// We can't use a relative path in HTML because we don't want to load something -// like /todos/42/static/js/bundle.7289d.js. We have to know the root. -function getServedPath(appPackageJson) { - const publicUrl = getPublicUrl(appPackageJson); - const servedUrl = - envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/'); - return ensureSlash(servedUrl, true); -} - -const moduleFileExtensions = [ - 'web.mjs', - 'mjs', - 'web.js', - 'js', - 'web.ts', - 'ts', - 'web.tsx', - 'tsx', - 'json', - 'web.jsx', - 'jsx', -]; - -// Resolve file paths in the order expected by the test tooling. -const resolveModule = (resolveFn, filePath) => { - const extension = moduleFileExtensions.find(extension => - fs.existsSync(resolveFn(`${filePath}.${extension}`)) - ); - - if (extension) { - return resolveFn(`${filePath}.${extension}`); - } - - return resolveFn(`${filePath}.js`); -}; - -// config after eject: we're in ./config/ -module.exports = { - dotenv: resolveApp('.env'), - appPath: resolveApp('.'), - appBuild: resolveApp('build'), - appPublic: resolveApp('public'), - appHtml: resolveApp('index.html'), - appIndexJs: resolveModule(resolveApp, 'src/index'), - appPackageJson: resolveApp('package.json'), - appSrc: resolveApp('src'), - appTsConfig: resolveApp('tsconfig.json'), - appJsConfig: resolveApp('jsconfig.json'), - yarnLockFile: resolveApp('yarn.lock'), - testsSetup: resolveModule(resolveApp, 'src/setupTests'), - proxySetup: resolveApp('src/setupProxy.js'), - appNodeModules: resolveApp('node_modules'), - publicUrl: getPublicUrl(resolveApp('package.json')), - servedPath: getServedPath(resolveApp('package.json')), -}; - - - -module.exports.moduleFileExtensions = moduleFileExtensions; diff --git a/client/eslint.config.cjs b/client/eslint.config.cjs new file mode 100644 index 0000000..cdf94b2 --- /dev/null +++ b/client/eslint.config.cjs @@ -0,0 +1,62 @@ +const js = require('@eslint/js'); +const globals = require('globals'); +const importPlugin = require('eslint-plugin-import'); +const jsxA11y = require('eslint-plugin-jsx-a11y'); +const react = require('eslint-plugin-react'); +const reactHooks = require('eslint-plugin-react-hooks'); + +module.exports = [ + { + ignores: ['build/**'], + }, + js.configs.recommended, + { + files: ['src/**/*.{js,jsx}'], + languageOptions: { + ecmaVersion: 'latest', + globals: { + ...globals.browser, + ...globals.jest, + module: 'readonly', + process: 'readonly', + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + sourceType: 'module', + }, + plugins: { + import: importPlugin, + 'jsx-a11y': jsxA11y, + react, + 'react-hooks': reactHooks, + }, + rules: { + ...importPlugin.configs.recommended.rules, + ...jsxA11y.configs.recommended.rules, + ...react.configs.recommended.rules, + 'import/no-unresolved': ['error', { ignore: ['^react-ga4$'] }], + 'react-hooks/exhaustive-deps': 'warn', + 'react-hooks/rules-of-hooks': 'error', + 'no-console': 'warn', + 'no-underscore-dangle': 'off', + 'jsx-a11y/no-autofocus': 'off', + 'react/jsx-filename-extension': ['warn', { extensions: ['.js', '.jsx'] }], + 'react/jsx-props-no-spreading': ['warn', { custom: 'ignore' }], + 'react/react-in-jsx-scope': 'off', + semi: ['warn', 'always'], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.mjs'], + }, + }, + react: { + version: 'detect', + }, + }, + }, +]; diff --git a/client/jest.config.cjs b/client/jest.config.cjs new file mode 100644 index 0000000..9797e12 --- /dev/null +++ b/client/jest.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + clearMocks: true, + collectCoverageFrom: ['src/**/*.{js,jsx}', '!src/custom-service-worker.js'], + moduleNameMapper: { + '\\.(css|less|sass|scss)$': 'identity-obj-proxy', + '\\.(mp3|ogg)$': '/test/fileMock.js', + }, + roots: ['/src'], + setupFilesAfterEnv: ['/src/setupTests.js'], + testEnvironment: 'jsdom', + transform: { + '^.+\\.[jt]sx?$': 'babel-jest', + }, +}; diff --git a/client/package.json b/client/package.json index 0967463..9cdc5f6 100644 --- a/client/package.json +++ b/client/package.json @@ -3,27 +3,28 @@ "version": "2.0.0", "private": true, "dependencies": { - "@material-ui/core": "^4.11.2", - "@material-ui/icons": "^4.11.2", - "@material-ui/lab": "4.0.0-alpha.46", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^6.5.0", + "@mui/material": "^6.5.0", + "@mui/styles": "^6.5.0", "clsx": "1.1.0", - "connected-react-router": "6.8.0", "date-fns": "^2.16.1", "history": "4.10.1", - "material-ui-confirm": "2.0.4", - "prop-types": "15.7.2", + "material-ui-confirm": "^4.0.0", + "prop-types": "15.8.1", "qs": "^6.9.6", - "react": "^16.14.0", - "react-cube-svg": "^0.1.3", - "react-dom": "^16.14.0", - "react-ga": "2.7.0", + "react": "18.3.1", + "react-cube-svg": "^0.2.3", + "react-dom": "18.3.1", + "react-ga4": "^3.0.1", "react-markdown": "6.0.3", - "react-redux": "^7.2.2", - "react-router-dom": "^5.2.0", - "react-twitch-embed": "^2.1.0", - "react-virtualized": "^9.22.3", - "redux": "^4.0.5", - "redux-thunk": "^2.3.0", + "react-redux": "^8.1.3", + "react-router-dom": "^5.3.4", + "react-twitch-embed": "^3.0.2", + "react-virtualized": "^9.22.6", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", "reselect": "^4.0.0", "socket.io-client": "^4.8.3", "stackmat-signal-processor": "^0.1.0", @@ -34,14 +35,11 @@ "start": "vite", "build": "vite build", "preview": "vite preview", - "test": "node scripts/test.js", - "test:ci": "CI=true node scripts/test.js --watchAll=false --passWithNoTests", + "test": "jest", + "test:ci": "jest --ci --passWithNoTests", "lint": "eslint ./src/", "lint:fix": "eslint --fix ./src/" }, - "eslintConfig": { - "extends": "react-app" - }, "browserslist": { "production": [ ">0.2%", @@ -54,96 +52,28 @@ "last 1 safari version" ] }, - "jest": { - "roots": [ - "/src" - ], - "collectCoverageFrom": [ - "src/**/*.{js,jsx,ts,tsx}", - "!src/**/*.d.ts" - ], - "setupFiles": [ - "react-app-polyfill/jsdom" - ], - "setupFilesAfterEnv": [ - "/src/setupTests.js" - ], - "testMatch": [ - "/src/**/__tests__/**/*.{js,jsx,ts,tsx}", - "/src/**/*.{spec,test}.{js,jsx,ts,tsx}" - ], - "testEnvironment": "jest-environment-jsdom-fourteen", - "transform": { - "^.+\\.(js|jsx|ts|tsx)$": "/node_modules/babel-jest", - "^.+\\.css$": "/config/jest/cssTransform.js", - "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "/config/jest/fileTransform.js" - }, - "transformIgnorePatterns": [ - "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$", - "^.+\\.module\\.(css|sass|scss)$" - ], - "modulePaths": [ - "/usr/lib/nodejs", - "/usr/lib/node_modules", - "/usr/share/javascript" - ], - "moduleNameMapper": { - "^react-native$": "react-native-web", - "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy" - }, - "moduleFileExtensions": [ - "web.js", - "js", - "web.ts", - "ts", - "web.tsx", - "tsx", - "json", - "web.jsx", - "jsx", - "node" - ], - "watchPlugins": [ - "jest-watch-typeahead/filename", - "jest-watch-typeahead/testname" - ] - }, - "babel": { - "presets": [ - "react-app" - ] - }, "devDependencies": { - "@babel/core": "7.7.4", - "@testing-library/jest-dom": "4.2.4", - "@testing-library/react": "9.4.0", - "@testing-library/user-event": "7.2.1", - "@typescript-eslint/eslint-plugin": "^2.34.0", - "@typescript-eslint/parser": "^2.34.0", + "@babel/core": "^7.28.0", + "@babel/preset-env": "^7.28.0", + "@babel/preset-react": "^7.27.1", + "@eslint/js": "^9.39.4", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "6.0.3", - "babel-eslint": "10.0.3", - "babel-jest": "^24.9.0", - "babel-preset-react-app": "^9.1.2", - "camelcase": "^5.3.1", - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0", - "enzyme": "3.11.0", - "enzyme-adapter-react-16": "1.15.2", - "eslint": "^6.6.0", - "eslint-config-airbnb": "18.1.0", - "eslint-config-react-app": "^5.2.1", - "eslint-plugin-flowtype": "3.13.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "6.2.3", - "eslint-plugin-prettier": "3.1.2", + "babel-jest": "^30.4.1", + "eslint": "^9.39.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^1.6.1", + "eslint-plugin-react-hooks": "^7.1.1", + "globals": "^17.7.0", "identity-obj-proxy": "3.0.0", - "jest": "^26.6.3", - "jest-environment-jsdom-fourteen": "^1.0.1", - "jest-resolve": "^26.6.2", - "jest-watch-typeahead": "^0.6.1", - "react-app-polyfill": "^1.0.6", + "jest": "^30.4.2", + "jest-environment-jsdom": "^30.4.1", "vite": "8.1.4", "vite-plugin-pwa": "1.3.0", "workbox-build": "^7.4.1", diff --git a/client/scripts/test.js b/client/scripts/test.js deleted file mode 100644 index b57cb38..0000000 --- a/client/scripts/test.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -// Do this as the first thing so that any code reading it knows the right env. -process.env.BABEL_ENV = 'test'; -process.env.NODE_ENV = 'test'; -process.env.PUBLIC_URL = ''; - -// Makes the script crash on unhandled rejections instead of silently -// ignoring them. In the future, promise rejections that are not handled will -// terminate the Node.js process with a non-zero exit code. -process.on('unhandledRejection', err => { - throw err; -}); - -// Ensure environment variables are read. -require('../config/env'); - - -const jest = require('jest'); -const execSync = require('child_process').execSync; -let argv = process.argv.slice(2); - -function isInGitRepository() { - try { - execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } -} - -function isInMercurialRepository() { - try { - execSync('hg --cwd . root', { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } -} - -// Watch unless on CI or explicitly running all tests -if ( - !process.env.CI && - argv.indexOf('--watchAll') === -1 && - argv.indexOf('--watchAll=false') === -1 -) { - // https://github.com/facebook/create-react-app/issues/5210 - const hasSourceControl = isInGitRepository() || isInMercurialRepository(); - argv.push(hasSourceControl ? '--watch' : '--watchAll'); -} - - -jest.run(argv); diff --git a/client/src/components/Admin/RoomCard.jsx b/client/src/components/Admin/RoomCard.jsx index 6dc0fd2..2e5218c 100644 --- a/client/src/components/Admin/RoomCard.jsx +++ b/client/src/components/Admin/RoomCard.jsx @@ -1,15 +1,15 @@ import React, { useState, useRef } from 'react'; import { useDispatch } from 'react-redux'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import PropTypes from 'prop-types'; -import Card from '@material-ui/core/Card'; -import CardContent from '@material-ui/core/CardContent'; -import CardHeader from '@material-ui/core/CardHeader'; -import Typography from '@material-ui/core/Typography'; -import IconButton from '@material-ui/core/IconButton'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +import CardHeader from '@mui/material/CardHeader'; +import Typography from '@mui/material/Typography'; +import IconButton from '@mui/material/IconButton'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; import { useConfirm } from 'material-ui-confirm'; import { deleteRoom } from '../../store/room/actions'; import { createMessage } from '../../store/messages/actions'; diff --git a/client/src/components/Admin/index.jsx b/client/src/components/Admin/index.jsx index 6817656..abd0832 100644 --- a/client/src/components/Admin/index.jsx +++ b/client/src/components/Admin/index.jsx @@ -1,10 +1,10 @@ import React, { useEffect } from 'react'; import { useDispatch, connect } from 'react-redux'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import PropTypes from 'prop-types'; -import Container from '@material-ui/core/Container'; -import Paper from '@material-ui/core/Paper'; -import Button from '@material-ui/core/Button'; +import Container from '@mui/material/Container'; +import Paper from '@mui/material/Paper'; +import Button from '@mui/material/Button'; import { fetchAdminData } from '../../store/admin/actions'; import RoomCard from './RoomCard'; diff --git a/client/src/components/App.jsx b/client/src/components/App.jsx index f9b3e18..300edae 100644 --- a/client/src/components/App.jsx +++ b/client/src/components/App.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { ConnectedRouter } from 'connected-react-router'; -import CssBaseline from '@material-ui/core/CssBaseline'; +import { Router } from 'react-router-dom'; +import CssBaseline from '@mui/material/CssBaseline'; import { ConfirmProvider } from 'material-ui-confirm'; import { ThemeProvider } from '../theme'; import store from '../store'; @@ -11,14 +11,14 @@ import Navigation from './Navigation'; function App() { return ( - + - + ); } diff --git a/client/src/components/App.test.jsx b/client/src/components/App.test.jsx index b08ffa2..ef6d65a 100644 --- a/client/src/components/App.test.jsx +++ b/client/src/components/App.test.jsx @@ -1,7 +1,21 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { render, screen } from '@testing-library/react'; import App from './App'; +jest.mock('react-ga4', () => ({ + __esModule: true, + default: { + initialize: jest.fn(), + send: jest.fn(), + }, +})); + +jest.mock('./Navigation', () => function MockNavigation() { + return
; +}); + it('renders without crashing', () => { - shallow(); + render(); + + expect(screen.getByTestId('navigation')).toBeInTheDocument(); }); diff --git a/client/src/components/Footer.jsx b/client/src/components/Footer.jsx index 83980d0..045ef52 100644 --- a/client/src/components/Footer.jsx +++ b/client/src/components/Footer.jsx @@ -2,18 +2,19 @@ import React, { useState } from 'react'; import { connect } from 'react-redux'; import { Link as ReactRouterLink } from 'react-router-dom'; import PropTypes from 'prop-types'; -import { makeStyles, useTheme } from '@material-ui/core/styles'; -import Grid from '@material-ui/core/Grid'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import Link from '@material-ui/core/Link'; -import Popover from '@material-ui/core/Popover'; -import Tooltip from '@material-ui/core/Tooltip'; -import IconButton from '@material-ui/core/IconButton'; -import EmojiObjectsIcon from '@material-ui/icons/EmojiObjects'; -import EmojiObjectsOutlinedIcon from '@material-ui/icons/EmojiObjectsOutlined'; -import CloudIcon from '@material-ui/icons/Cloud'; -import CloudOffIcon from '@material-ui/icons/CloudOff'; +import { useTheme } from '@mui/material/styles'; +import { makeStyles } from '@mui/styles'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import Link from '@mui/material/Link'; +import Popover from '@mui/material/Popover'; +import Tooltip from '@mui/material/Tooltip'; +import IconButton from '@mui/material/IconButton'; +import EmojiObjectsIcon from '@mui/icons-material/EmojiObjects'; +import EmojiObjectsOutlinedIcon from '@mui/icons-material/EmojiObjectsOutlined'; +import CloudIcon from '@mui/icons-material/Cloud'; +import CloudOffIcon from '@mui/icons-material/CloudOff'; import { version } from '../../package.json'; import { useToggleTheme } from '../theme'; @@ -86,7 +87,7 @@ function Footer({ onClick={toggleTheme} aria-label="Toggle theme" > - { theme.palette.type === 'dark' + { theme.palette.mode === 'dark' ? : } diff --git a/client/src/components/Header.jsx b/client/src/components/Header.jsx index a30e337..7880e2c 100644 --- a/client/src/components/Header.jsx +++ b/client/src/components/Header.jsx @@ -3,16 +3,16 @@ import qs from 'qs'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; -import { makeStyles } from '@material-ui/core/styles'; -import Grid from '@material-ui/core/Grid'; -import AppBar from '@material-ui/core/AppBar'; -import Typography from '@material-ui/core/Typography'; -import Toolbar from '@material-ui/core/Toolbar'; -import IconButton from '@material-ui/core/IconButton'; -import Avatar from '@material-ui/core/Avatar'; -import Menu from '@material-ui/core/Menu'; -import Button from '@material-ui/core/Button'; -import MenuItem from '@material-ui/core/MenuItem'; +import { makeStyles } from '@mui/styles'; +import Grid from '@mui/material/Grid'; +import AppBar from '@mui/material/AppBar'; +import Typography from '@mui/material/Typography'; +import Toolbar from '@mui/material/Toolbar'; +import IconButton from '@mui/material/IconButton'; +import Avatar from '@mui/material/Avatar'; +import Menu from '@mui/material/Menu'; +import Button from '@mui/material/Button'; +import MenuItem from '@mui/material/MenuItem'; import { apiOrigin } from '../lib/fetch'; import { getNameFromId } from '../lib/events'; diff --git a/client/src/components/Lobby/Announcements.jsx b/client/src/components/Lobby/Announcements.jsx index 1d656f6..c8ee080 100644 --- a/client/src/components/Lobby/Announcements.jsx +++ b/client/src/components/Lobby/Announcements.jsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactMarkdown from 'react-markdown'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; import { lcFetch } from '../../lib/fetch'; const useStyles = makeStyles({ diff --git a/client/src/components/Lobby/Announcements.test.jsx b/client/src/components/Lobby/Announcements.test.jsx index 1161ea0..38d5b7b 100644 --- a/client/src/components/Lobby/Announcements.test.jsx +++ b/client/src/components/Lobby/Announcements.test.jsx @@ -1,6 +1,5 @@ import React from 'react'; -import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; +import { render, screen } from '@testing-library/react'; import Announcements from './Announcements'; import { lcFetch } from '../../lib/fetch'; @@ -8,8 +7,6 @@ jest.mock('../../lib/fetch', () => ({ lcFetch: jest.fn(), })); -const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); - describe('Announcements', () => { beforeEach(() => { lcFetch.mockReset(); @@ -21,19 +18,10 @@ describe('Announcements', () => { text: jest.fn().mockResolvedValue('[Docs](https://example.com)'), }); - let wrapper; - - await act(async () => { - wrapper = mount(); - await flushPromises(); - }); - - wrapper.update(); - - const link = wrapper.find('a').first(); + render(); - expect(link.text()).toEqual('Docs'); - expect(link.prop('href')).toEqual('https://example.com'); - expect(link.prop('target')).toEqual('_blank'); + const link = await screen.findByRole('link', { name: 'Docs' }); + expect(link).toHaveAttribute('href', 'https://example.com'); + expect(link).toHaveAttribute('target', '_blank'); }); }); diff --git a/client/src/components/Lobby/UserList.jsx b/client/src/components/Lobby/UserList.jsx index 02d0e0d..d474b5f 100644 --- a/client/src/components/Lobby/UserList.jsx +++ b/client/src/components/Lobby/UserList.jsx @@ -1,14 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Toolbar from '@material-ui/core/Toolbar'; -// import Divider from '@material-ui/core/Divider'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import Avatar from '@material-ui/core/Avatar'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Toolbar from '@mui/material/Toolbar'; +// import Divider from '@mui/material/Divider'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemAvatar from '@mui/material/ListItemAvatar'; +import Avatar from '@mui/material/Avatar'; const useStyles = makeStyles(() => ({ root: { diff --git a/client/src/components/Lobby/index.jsx b/client/src/components/Lobby/index.jsx index c49589c..cf966da 100644 --- a/client/src/components/Lobby/index.jsx +++ b/client/src/components/Lobby/index.jsx @@ -3,22 +3,20 @@ import { connect, useDispatch } from 'react-redux'; import { Link } from 'react-router-dom'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Container from '@material-ui/core/Container'; -import Grid from '@material-ui/core/Grid'; -import Divider from '@material-ui/core/Divider'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import Button from '@material-ui/core/Button'; -import Alert from '@material-ui/lab/Alert'; -import ListSubheader from '@material-ui/core/ListSubheader'; -import BottomNavigation from '@material-ui/core/BottomNavigation'; -import BottomNavigationAction from '@material-ui/core/BottomNavigationAction'; -import AddIcon from '@material-ui/icons/Add'; -import DynamicFeedIcon from '@material-ui/icons/DynamicFeed'; -import PeopleIcon from '@material-ui/icons/People'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Container from '@mui/material/Container'; +import Grid from '@mui/material/Grid'; +import Divider from '@mui/material/Divider'; +import List from '@mui/material/List'; +import Button from '@mui/material/Button'; +import Alert from '@mui/material/Alert'; +import ListSubheader from '@mui/material/ListSubheader'; +import BottomNavigation from '@mui/material/BottomNavigation'; +import BottomNavigationAction from '@mui/material/BottomNavigationAction'; +import AddIcon from '@mui/icons-material/Add'; +import DynamicFeedIcon from '@mui/icons-material/DynamicFeed'; +import PeopleIcon from '@mui/icons-material/People'; import RoomConfigureDialog from '../RoomConfigureDialog'; import RoomListItem from '../RoomListItem'; import EventListItem from '../common/EventListItem'; @@ -56,7 +54,7 @@ const useStyles = makeStyles((theme) => ({ display: 'flex', flexDirection: 'column', flexGrow: 1, - height: 0, + minHeight: 0, overflowY: 'auto', }, eventList: { @@ -171,19 +169,16 @@ function Lobby({ )} {user.id && ( - } onClick={() => setCreateRoomDialogOpen(true)} > - - - Create Room - + )}
diff --git a/client/src/components/Navigation.jsx b/client/src/components/Navigation.jsx index d9b849f..8120ca1 100644 --- a/client/src/components/Navigation.jsx +++ b/client/src/components/Navigation.jsx @@ -2,11 +2,11 @@ import React, { Suspense, lazy } from 'react'; import PropTypes from 'prop-types'; import { Switch, Route, Redirect } from 'react-router-dom'; import { connect, useDispatch } from 'react-redux'; -// import Backdrop from '@material-ui/core/Backdrop'; -import CircularProgress from '@material-ui/core/CircularProgress'; -import Snackbar from '@material-ui/core/Snackbar'; -import Alert from '@material-ui/lab/Alert'; -import { makeStyles } from '@material-ui/core/styles'; +// import Backdrop from '@mui/material/Backdrop'; +import CircularProgress from '@mui/material/CircularProgress'; +import Snackbar from '@mui/material/Snackbar'; +import Alert from '@mui/material/Alert'; +import { makeStyles } from '@mui/styles'; import PrivateRoute from './common/PrivateRoute'; import Header from './Header'; import Footer from './Footer'; diff --git a/client/src/components/Room/Common/AdminToolbar.jsx b/client/src/components/Room/Common/AdminToolbar.jsx index 200d3a5..e0eeda3 100644 --- a/client/src/components/Room/Common/AdminToolbar.jsx +++ b/client/src/components/Room/Common/AdminToolbar.jsx @@ -1,15 +1,15 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect, useDispatch } from 'react-redux'; -import Toolbar from '@material-ui/core/Toolbar'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import Button from '@material-ui/core/Button'; -import FormGroup from '@material-ui/core/FormGroup'; -import Select from '@material-ui/core/Select'; -import ListSubheader from '@material-ui/core/ListSubheader'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; +import Toolbar from '@mui/material/Toolbar'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import Button from '@mui/material/Button'; +import FormGroup from '@mui/material/FormGroup'; +import Select from '@mui/material/Select'; +import ListSubheader from '@mui/material/ListSubheader'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; import { useConfirm } from 'material-ui-confirm'; import { deleteRoom, diff --git a/client/src/components/Room/Common/EditDialog.jsx b/client/src/components/Room/Common/EditDialog.jsx index 86c4bf8..fcc4756 100644 --- a/client/src/components/Room/Common/EditDialog.jsx +++ b/client/src/components/Room/Common/EditDialog.jsx @@ -1,13 +1,13 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import DialogContent from '@material-ui/core/DialogContent'; -import TextField from '@material-ui/core/TextField'; -import Button from '@material-ui/core/Button'; -import Checkbox from '@material-ui/core/Checkbox'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import TextField from '@mui/material/TextField'; +import Button from '@mui/material/Button'; +import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; import { formatRawTime, parseTime } from '../../../lib/utils'; function EditDialog({ diff --git a/client/src/components/Room/Common/Login.jsx b/client/src/components/Room/Common/Login.jsx index 8650f05..4a27925 100644 --- a/client/src/components/Room/Common/Login.jsx +++ b/client/src/components/Room/Common/Login.jsx @@ -1,12 +1,12 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect } from 'react-redux'; -import Paper from '@material-ui/core/Paper'; -import TextField from '@material-ui/core/TextField'; -import Button from '@material-ui/core/Button'; -import IconButton from '@material-ui/core/IconButton'; -import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import Paper from '@mui/material/Paper'; +import TextField from '@mui/material/TextField'; +import Button from '@mui/material/Button'; +import IconButton from '@mui/material/IconButton'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import { Link } from 'react-router-dom'; import { joinRoom, diff --git a/client/src/components/Room/Common/Main.jsx b/client/src/components/Room/Common/Main.jsx index 4a09c00..f2951b4 100644 --- a/client/src/components/Room/Common/Main.jsx +++ b/client/src/components/Room/Common/Main.jsx @@ -1,12 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; +import { withStyles } from '@mui/styles'; import { connect } from 'react-redux'; -import Grid from '@material-ui/core/Grid'; -import Paper from '@material-ui/core/Paper'; -import Divider from '@material-ui/core/Divider'; -import Typography from '@material-ui/core/Typography'; -import ClickAwayListener from '@material-ui/core/ClickAwayListener'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import ClickAwayListener from '@mui/material/ClickAwayListener'; import { Cube } from 'react-cube-svg'; import UIfx from 'uifx'; import notificationAsset from '../../../assets/notification.mp3'; @@ -24,7 +24,7 @@ import Timer from '../../Timer/index'; import Scramble from '../../common/Scramble'; import UserStats from './UserStats'; -const useStyles = withStyles((theme) => ({ +const withComponentStyles = withStyles((theme) => ({ root: { display: 'flex', flexGrow: 1, @@ -279,4 +279,4 @@ const mapStateToProps = (state) => ({ user: state.user, }); -export default connect(mapStateToProps)(useStyles(Main)); +export default connect(mapStateToProps)(withComponentStyles(Main)); diff --git a/client/src/components/Room/Common/ManageUsersDialog.jsx b/client/src/components/Room/Common/ManageUsersDialog.jsx index 0434a32..994ef7b 100644 --- a/client/src/components/Room/Common/ManageUsersDialog.jsx +++ b/client/src/components/Room/Common/ManageUsersDialog.jsx @@ -2,20 +2,20 @@ import React from 'react'; import clsx from 'clsx'; import { connect, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Checkbox from '@material-ui/core/Checkbox'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListSubheader from '@material-ui/core/ListSubheader'; -import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import Avatar from '@material-ui/core/Avatar'; +import { makeStyles } from '@mui/styles'; +import Button from '@mui/material/Button'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import ListSubheader from '@mui/material/ListSubheader'; +import ListItemAvatar from '@mui/material/ListItemAvatar'; +import Avatar from '@mui/material/Avatar'; import { kickUser, updateUser, updateBanned } from '../../../store/room/actions'; import { getUsersInRoom, diff --git a/client/src/components/Room/Common/Panel.jsx b/client/src/components/Room/Common/Panel.jsx index 0043d9a..4953262 100644 --- a/client/src/components/Room/Common/Panel.jsx +++ b/client/src/components/Room/Common/Panel.jsx @@ -1,10 +1,10 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import Paper from '@material-ui/core/Paper'; -import Toolbar from '@material-ui/core/Toolbar'; -import Divider from '@material-ui/core/Divider'; -import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@mui/material/Paper'; +import Toolbar from '@mui/material/Toolbar'; +import Divider from '@mui/material/Divider'; +import { makeStyles } from '@mui/styles'; const useStyles = makeStyles(() => ({ root: { diff --git a/client/src/components/Room/Common/StatsDialog.jsx b/client/src/components/Room/Common/StatsDialog.jsx index 7ec72cc..204f4cb 100644 --- a/client/src/components/Room/Common/StatsDialog.jsx +++ b/client/src/components/Room/Common/StatsDialog.jsx @@ -1,13 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Typography from '@material-ui/core/Typography'; -import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@mui/styles'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import Typography from '@mui/material/Typography'; +import Paper from '@mui/material/Paper'; import { formatTime } from '../../../lib/utils'; const useStyles = makeStyles(() => ({ diff --git a/client/src/components/Room/Common/TableStatusCell.jsx b/client/src/components/Room/Common/TableStatusCell.jsx index 23bf4f4..c26c85f 100644 --- a/client/src/components/Room/Common/TableStatusCell.jsx +++ b/client/src/components/Room/Common/TableStatusCell.jsx @@ -1,9 +1,9 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import TableCell from '@material-ui/core/TableCell'; +import { makeStyles } from '@mui/styles'; +import Typography from '@mui/material/Typography'; +import TableCell from '@mui/material/TableCell'; const useStyles = makeStyles(() => ({ root: { diff --git a/client/src/components/Room/Common/TableTimeCell.jsx b/client/src/components/Room/Common/TableTimeCell.jsx index 03939f3..f9cdabb 100644 --- a/client/src/components/Room/Common/TableTimeCell.jsx +++ b/client/src/components/Room/Common/TableTimeCell.jsx @@ -1,10 +1,10 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import Typography from '@material-ui/core/Typography'; -import TableCell from '@material-ui/core/TableCell'; +import { makeStyles } from '@mui/styles'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import TableCell from '@mui/material/TableCell'; import { formatTime } from '../../../lib/utils'; import { useEditDialog } from './EditDialogProvider'; diff --git a/client/src/components/Room/Common/TimesTable.jsx b/client/src/components/Room/Common/TimesTable.jsx index 54d8cd2..e6e1451 100644 --- a/client/src/components/Room/Common/TimesTable.jsx +++ b/client/src/components/Room/Common/TimesTable.jsx @@ -1,14 +1,14 @@ import React, { createRef } from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import TableContainer from '@material-ui/core/TableContainer'; -import Table from '@material-ui/core/Table'; -import TableHead from '@material-ui/core/TableHead'; -import TableBody from '@material-ui/core/TableBody'; -import TableRow from '@material-ui/core/TableRow'; -import TableCell from '@material-ui/core/TableCell'; +import { makeStyles } from '@mui/styles'; +import Typography from '@mui/material/Typography'; +import TableContainer from '@mui/material/TableContainer'; +import Table from '@mui/material/Table'; +import TableHead from '@mui/material/TableHead'; +import TableBody from '@mui/material/TableBody'; +import TableRow from '@mui/material/TableRow'; +import TableCell from '@mui/material/TableCell'; import { useStatsDialog } from './StatsDialogProvider'; import TableCellButton from '../../common/TableCellButton'; import TableStatusCell from './TableStatusCell'; diff --git a/client/src/components/Room/Common/UserSelectorDialog.jsx b/client/src/components/Room/Common/UserSelectorDialog.jsx index 4d15637..22eb97e 100644 --- a/client/src/components/Room/Common/UserSelectorDialog.jsx +++ b/client/src/components/Room/Common/UserSelectorDialog.jsx @@ -1,18 +1,18 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import Checkbox from '@material-ui/core/Checkbox'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; -import Avatar from '@material-ui/core/Avatar'; +import { makeStyles } from '@mui/styles'; +import Button from '@mui/material/Button'; +import Checkbox from '@mui/material/Checkbox'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemAvatar from '@mui/material/ListItemAvatar'; +import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; +import Avatar from '@mui/material/Avatar'; const useStyles = makeStyles(() => ({})); diff --git a/client/src/components/Room/Common/UserStats.jsx b/client/src/components/Room/Common/UserStats.jsx index 08e0c13..4d3379a 100644 --- a/client/src/components/Room/Common/UserStats.jsx +++ b/client/src/components/Room/Common/UserStats.jsx @@ -1,12 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Table from '@material-ui/core/Table'; -import TableHead from '@material-ui/core/TableHead'; -import TableBody from '@material-ui/core/TableBody'; -import TableRow from '@material-ui/core/TableRow'; -import TableCell from '@material-ui/core/TableCell'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableHead from '@mui/material/TableHead'; +import TableBody from '@mui/material/TableBody'; +import TableRow from '@mui/material/TableRow'; +import TableCell from '@mui/material/TableCell'; import { formatTime } from '../../../lib/utils'; const useStyles = makeStyles((theme) => ({ diff --git a/client/src/components/Room/Common/UserToolbar.jsx b/client/src/components/Room/Common/UserToolbar.jsx index 1c34885..ffae149 100644 --- a/client/src/components/Room/Common/UserToolbar.jsx +++ b/client/src/components/Room/Common/UserToolbar.jsx @@ -1,21 +1,21 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect } from 'react-redux'; -import Toolbar from '@material-ui/core/Toolbar'; -import FormGroup from '@material-ui/core/FormGroup'; -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import SettingsIcon from '@material-ui/icons/Settings'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormControl from '@material-ui/core/FormControl'; -import InputLabel from '@material-ui/core/InputLabel'; -import Checkbox from '@material-ui/core/Checkbox'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; +import Toolbar from '@mui/material/Toolbar'; +import FormGroup from '@mui/material/FormGroup'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import SettingsIcon from '@mui/icons-material/Settings'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import InputLabel from '@mui/material/InputLabel'; +import Checkbox from '@mui/material/Checkbox'; +import Select from '@mui/material/Select'; +import MenuItem from '@mui/material/MenuItem'; import { lcFetch } from '../../../lib/fetch'; import { updateCompeting } from '../../../store/room/actions'; import { updateProfile } from '../../../store/user/actions'; diff --git a/client/src/components/Room/GrandPrix/GrandPrixMain.jsx b/client/src/components/Room/GrandPrix/GrandPrixMain.jsx index 7bc2331..fca1c9b 100644 --- a/client/src/components/Room/GrandPrix/GrandPrixMain.jsx +++ b/client/src/components/Room/GrandPrix/GrandPrixMain.jsx @@ -1,14 +1,15 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { withStyles, makeStyles, useTheme } from '@material-ui/core/styles'; +import { useTheme } from '@mui/material/styles'; +import { makeStyles, withStyles } from '@mui/styles'; import { connect, useDispatch } from 'react-redux'; -import Grid from '@material-ui/core/Grid'; -import Box from '@material-ui/core/Box'; -import Paper from '@material-ui/core/Paper'; -import Divider from '@material-ui/core/Divider'; -import Typography from '@material-ui/core/Typography'; -import ClickAwayListener from '@material-ui/core/ClickAwayListener'; -import Button from '@material-ui/core/Button'; +import Grid from '@mui/material/Grid'; +import Box from '@mui/material/Box'; +import Paper from '@mui/material/Paper'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import ClickAwayListener from '@mui/material/ClickAwayListener'; +import Button from '@mui/material/Button'; import { Cube } from 'react-cube-svg'; import { formatISO9075 } from 'date-fns'; import calcStats from '../../../lib/stats'; @@ -29,7 +30,7 @@ import UserStats from '../Common/UserStats'; import UserSelectorDialog from '../Common/UserSelectorDialog'; const getCountdownColor = (theme, countdown) => { - if (theme.palette.type === 'light') { + if (theme.palette.mode === 'light') { if (countdown < 0) { return theme.palette.background.paper; } diff --git a/client/src/components/Room/GrandPrix/Leaderboard.jsx b/client/src/components/Room/GrandPrix/Leaderboard.jsx index 68afe90..42ecf00 100644 --- a/client/src/components/Room/GrandPrix/Leaderboard.jsx +++ b/client/src/components/Room/GrandPrix/Leaderboard.jsx @@ -1,16 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect, useDispatch } from 'react-redux'; -import { makeStyles } from '@material-ui/core/styles'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import Paper from '@material-ui/core/Paper'; -import TableContainer from '@material-ui/core/TableContainer'; -import Table from '@material-ui/core/Table'; -import TableHead from '@material-ui/core/TableHead'; -import TableBody from '@material-ui/core/TableBody'; -import TableRow from '@material-ui/core/TableRow'; -import TableCell from '@material-ui/core/TableCell'; +import { makeStyles } from '@mui/styles'; +import Toolbar from '@mui/material/Toolbar'; +import Typography from '@mui/material/Typography'; +import Paper from '@mui/material/Paper'; +import TableContainer from '@mui/material/TableContainer'; +import Table from '@mui/material/Table'; +import TableHead from '@mui/material/TableHead'; +import TableBody from '@mui/material/TableBody'; +import TableRow from '@mui/material/TableRow'; +import TableCell from '@mui/material/TableCell'; import TableStatusCell from '../Common/TableStatusCell'; import TableTimeCell from '../Common/TableTimeCell'; import { StatsDialogProvider } from '../Common/StatsDialogProvider'; diff --git a/client/src/components/Room/GrandPrix/RegisterPanel.jsx b/client/src/components/Room/GrandPrix/RegisterPanel.jsx index f426b26..f94ec7e 100644 --- a/client/src/components/Room/GrandPrix/RegisterPanel.jsx +++ b/client/src/components/Room/GrandPrix/RegisterPanel.jsx @@ -2,10 +2,10 @@ import React, { useState } from 'react'; import { connect, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { formatDistanceToNow, formatRFC7231 } from 'date-fns'; -import { makeStyles } from '@material-ui/core/styles'; -import Box from '@material-ui/core/Box'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; +import { makeStyles } from '@mui/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; import { updateRegistration } from '../../../store/room/actions'; import { getRegisteredUsers } from '../../../store/room/selectors'; diff --git a/client/src/components/Room/GrandPrix/index.jsx b/client/src/components/Room/GrandPrix/index.jsx index 7a1cf3e..cbf779c 100644 --- a/client/src/components/Room/GrandPrix/index.jsx +++ b/client/src/components/Room/GrandPrix/index.jsx @@ -1,21 +1,21 @@ import React, { useState } from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect } from 'react-redux'; -import Grid from '@material-ui/core/Grid'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import Paper from '@material-ui/core/Paper'; -import BottomNavigation from '@material-ui/core/BottomNavigation'; -import BottomNavigationAction from '@material-ui/core/BottomNavigationAction'; -import Divider from '@material-ui/core/Divider'; -import IconButton from '@material-ui/core/IconButton'; -import ChatIcon from '@material-ui/icons/Chat'; -import TimerIcon from '@material-ui/icons/Timer'; -import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; -import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import Grid from '@mui/material/Grid'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Typography from '@mui/material/Typography'; +import Paper from '@mui/material/Paper'; +import BottomNavigation from '@mui/material/BottomNavigation'; +import BottomNavigationAction from '@mui/material/BottomNavigationAction'; +import Divider from '@mui/material/Divider'; +import IconButton from '@mui/material/IconButton'; +import ChatIcon from '@mui/icons-material/Chat'; +import TimerIcon from '@mui/icons-material/Timer'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import Main from './GrandPrixMain'; import AdminToolbar from '../Common/AdminToolbar'; import UserToolbar from '../Common/UserToolbar'; diff --git a/client/src/components/Room/Normal/index.jsx b/client/src/components/Room/Normal/index.jsx index 1ab53d4..465bc61 100644 --- a/client/src/components/Room/Normal/index.jsx +++ b/client/src/components/Room/Normal/index.jsx @@ -1,15 +1,15 @@ import React, { useState } from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect } from 'react-redux'; -import Grid from '@material-ui/core/Grid'; -import Paper from '@material-ui/core/Paper'; -import BottomNavigation from '@material-ui/core/BottomNavigation'; -import BottomNavigationAction from '@material-ui/core/BottomNavigationAction'; -import Divider from '@material-ui/core/Divider'; -import ChatIcon from '@material-ui/icons/Chat'; -import TimerIcon from '@material-ui/icons/Timer'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import BottomNavigation from '@mui/material/BottomNavigation'; +import BottomNavigationAction from '@mui/material/BottomNavigationAction'; +import Divider from '@mui/material/Divider'; +import ChatIcon from '@mui/icons-material/Chat'; +import TimerIcon from '@mui/icons-material/Timer'; import Main from '../Common/Main'; import Chat from '../Panels/Chat'; import AdminToolbar from '../Common/AdminToolbar'; diff --git a/client/src/components/Room/Panels/Chat.jsx b/client/src/components/Room/Panels/Chat.jsx index b02a11a..d29e5a2 100644 --- a/client/src/components/Room/Panels/Chat.jsx +++ b/client/src/components/Room/Panels/Chat.jsx @@ -2,25 +2,25 @@ import React, { useState, useRef, useEffect } from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Toolbar from '@material-ui/core/Toolbar'; -import FormControl from '@material-ui/core/FormControl'; -import Input from '@material-ui/core/Input'; -import Alert from '@material-ui/lab/Alert'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListItemAvatar from '@material-ui/core/ListItemAvatar'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import Avatar from '@material-ui/core/Avatar'; -import Typography from '@material-ui/core/Typography'; -import IconButton from '@material-ui/core/IconButton'; -import Icon from '@material-ui/core/Icon'; -import NotificationImportantIcon from '@material-ui/icons/NotificationImportant'; -import PersonIcon from '@material-ui/icons/Person'; -import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; -import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Toolbar from '@mui/material/Toolbar'; +import FormControl from '@mui/material/FormControl'; +import Input from '@mui/material/Input'; +import Alert from '@mui/material/Alert'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemAvatar from '@mui/material/ListItemAvatar'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import Avatar from '@mui/material/Avatar'; +import Typography from '@mui/material/Typography'; +import IconButton from '@mui/material/IconButton'; +import Icon from '@mui/material/Icon'; +import NotificationImportantIcon from '@mui/icons-material/NotificationImportant'; +import PersonIcon from '@mui/icons-material/Person'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import { sendChat } from '../../../store/chat/actions'; import Panel from '../Common/Panel'; diff --git a/client/src/components/Room/index.jsx b/client/src/components/Room/index.jsx index 8b449a4..d9910ae 100644 --- a/client/src/components/Room/index.jsx +++ b/client/src/components/Room/index.jsx @@ -1,11 +1,11 @@ import React, { useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@mui/styles'; import { connect, useDispatch } from 'react-redux'; -import Paper from '@material-ui/core/Paper'; -import Backdrop from '@material-ui/core/Backdrop'; -import CircularProgress from '@material-ui/core/CircularProgress'; +import Paper from '@mui/material/Paper'; +import Backdrop from '@mui/material/Backdrop'; +import CircularProgress from '@mui/material/CircularProgress'; import qs from 'qs'; import Login from './Common/Login'; import { diff --git a/client/src/components/RoomConfigureDialog.jsx b/client/src/components/RoomConfigureDialog.jsx index 3ca0100..0116e4c 100644 --- a/client/src/components/RoomConfigureDialog.jsx +++ b/client/src/components/RoomConfigureDialog.jsx @@ -2,26 +2,26 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; import { format } from 'date-fns'; -import { makeStyles } from '@material-ui/core/styles'; -import Divider from '@material-ui/core/Divider'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import Switch from '@material-ui/core/Switch'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import InputLabel from '@material-ui/core/InputLabel'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Accordion from '@material-ui/core/Accordion'; -import AccordionDetails from '@material-ui/core/AccordionDetails'; -import AccordionSummary from '@material-ui/core/AccordionSummary'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { makeStyles } from '@mui/styles'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import TextField from '@mui/material/TextField'; +import Switch from '@mui/material/Switch'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import FormHelperText from '@mui/material/FormHelperText'; +import InputLabel from '@mui/material/InputLabel'; +import Select from '@mui/material/Select'; +import MenuItem from '@mui/material/MenuItem'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import Accordion from '@mui/material/Accordion'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; const useStyles = makeStyles((theme) => ({ fab: { diff --git a/client/src/components/RoomListItem.jsx b/client/src/components/RoomListItem.jsx index 0dfcbf8..eeddca6 100644 --- a/client/src/components/RoomListItem.jsx +++ b/client/src/components/RoomListItem.jsx @@ -3,18 +3,18 @@ import { useHistory } from 'react-router-dom'; import { connect, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { formatDistanceToNow } from 'date-fns'; -import Tooltip from '@material-ui/core/Tooltip'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; -import Typography from '@material-ui/core/Typography'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import IconButton from '@material-ui/core/IconButton'; -import PublicIcon from '@material-ui/icons/Public'; -import PrivateIcon from '@material-ui/icons/Lock'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; +import Tooltip from '@mui/material/Tooltip'; +import ListItem from '@mui/material/ListItem'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; +import Typography from '@mui/material/Typography'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import IconButton from '@mui/material/IconButton'; +import PublicIcon from '@mui/icons-material/Public'; +import PrivateIcon from '@mui/icons-material/Lock'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; import { useConfirm } from 'material-ui-confirm'; import { lcFetch } from '../lib/fetch'; // import ListItem from './ListItemLink'; diff --git a/client/src/components/Timer/ManualTimer.jsx b/client/src/components/Timer/ManualTimer.jsx index f9cef7a..f7c3eb9 100644 --- a/client/src/components/Timer/ManualTimer.jsx +++ b/client/src/components/Timer/ManualTimer.jsx @@ -1,19 +1,19 @@ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { withStyles } from '@material-ui/core/styles'; -import Box from '@material-ui/core/Box'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import Input from '@material-ui/core/Input'; -import Checkbox from '@material-ui/core/Checkbox'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import { withStyles } from '@mui/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import Input from '@mui/material/Input'; +import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; import { formatTime, parseTime, setInterval, clearInterval, now, } from '../../lib/utils'; import initialStyles from './styles'; -const useStyles = withStyles((theme) => ({ +const withComponentStyles = withStyles((theme) => ({ ...initialStyles(theme), input: { maxWidth: '300px', @@ -554,4 +554,4 @@ ManualTimer.defaultProps = { onPriming: () => {}, }; -export default useStyles(ManualTimer); +export default withComponentStyles(ManualTimer); diff --git a/client/src/components/Timer/SpacebarTimer.jsx b/client/src/components/Timer/SpacebarTimer.jsx index d291dec..cf6f2ed 100644 --- a/client/src/components/Timer/SpacebarTimer.jsx +++ b/client/src/components/Timer/SpacebarTimer.jsx @@ -1,19 +1,19 @@ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { withStyles } from '@material-ui/core/styles'; -import Box from '@material-ui/core/Box'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import Checkbox from '@material-ui/core/Checkbox'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import { withStyles } from '@mui/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import Checkbox from '@mui/material/Checkbox'; +import FormGroup from '@mui/material/FormGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; import { formatTime, setInterval, clearInterval, now, } from '../../lib/utils'; import styles from './styles'; -const useStyles = withStyles(styles); +const withComponentStyles = withStyles(styles); /* Complicated beast. @@ -475,4 +475,4 @@ Timer.defaultProps = { onPriming: () => {}, }; -export default useStyles(Timer); +export default withComponentStyles(Timer); diff --git a/client/src/components/Timer/StackmatTimer.jsx b/client/src/components/Timer/StackmatTimer.jsx index 039ec65..cf2908e 100644 --- a/client/src/components/Timer/StackmatTimer.jsx +++ b/client/src/components/Timer/StackmatTimer.jsx @@ -3,19 +3,19 @@ import StackmatSignalProcessor from 'stackmat-signal-processor'; import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { withStyles } from '@material-ui/core/styles'; -import Box from '@material-ui/core/Box'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import Checkbox from '@material-ui/core/Checkbox'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import { withStyles } from '@mui/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import Checkbox from '@mui/material/Checkbox'; +import FormGroup from '@mui/material/FormGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; import { formatTime, setInterval, clearInterval, now, } from '../../lib/utils'; import styles from './styles'; -const useStyles = withStyles(styles); +const withComponentStyles = withStyles(styles); const STATUS = { RESTING: 'RESTING', @@ -427,4 +427,4 @@ Timer.defaultProps = { onPriming: () => {}, }; -export default useStyles(Timer); +export default withComponentStyles(Timer); diff --git a/client/src/components/Timer/index.jsx b/client/src/components/Timer/index.jsx index d796505..a0be36e 100644 --- a/client/src/components/Timer/index.jsx +++ b/client/src/components/Timer/index.jsx @@ -1,4 +1,4 @@ -/* eslint-disable react/jsx-props-no-spreading */ + import React from 'react'; import PropTypes from 'prop-types'; import SpacebarTimer from './SpacebarTimer'; diff --git a/client/src/components/User.jsx b/client/src/components/User.jsx index 57183c5..b53b4e3 100644 --- a/client/src/components/User.jsx +++ b/client/src/components/User.jsx @@ -1,9 +1,9 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Popover from '@material-ui/core/Popover'; -import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@mui/styles'; +import Popover from '@mui/material/Popover'; +import Typography from '@mui/material/Typography'; const useStyles = makeStyles((theme) => ({ root: { @@ -26,7 +26,7 @@ const useStyles = makeStyles((theme) => ({ paddingBottom: '.5em', }, admin: { - color: theme.palette.type === 'light' ? theme.palette.primary.main : '#9EBDFF', + color: theme.palette.mode === 'light' ? theme.palette.primary.main : '#9EBDFF', }, })); diff --git a/client/src/components/WCARedirect.jsx b/client/src/components/WCARedirect.jsx index 52a3f06..17cad31 100644 --- a/client/src/components/WCARedirect.jsx +++ b/client/src/components/WCARedirect.jsx @@ -3,13 +3,13 @@ import PropTypes from 'prop-types'; import { connect, useDispatch } from 'react-redux'; import qs from 'qs'; import { Redirect, useLocation } from 'react-router-dom'; -import { makeStyles } from '@material-ui/core/styles'; -import Box from '@material-ui/core/Box'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import LinearProgress from '@material-ui/core/LinearProgress'; -import Alert from '@material-ui/lab/Alert'; -import AlertTitle from '@material-ui/lab/AlertTitle'; +import { makeStyles } from '@mui/styles'; +import Box from '@mui/material/Box'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import LinearProgress from '@mui/material/LinearProgress'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; import { lcFetch } from '../lib/fetch'; import { userChanged } from '../store/user/actions'; diff --git a/client/src/components/common/EditableTextField.jsx b/client/src/components/common/EditableTextField.jsx index 8302b26..93a83e8 100644 --- a/client/src/components/common/EditableTextField.jsx +++ b/client/src/components/common/EditableTextField.jsx @@ -1,14 +1,14 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Input from '@material-ui/core/Input'; -import InputLabel from '@material-ui/core/InputLabel'; -import Button from '@material-ui/core/Button'; -import ButtonGroup from '@material-ui/core/ButtonGroup'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import ClickAwayListener from '@material-ui/core/ClickAwayListener'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Input from '@mui/material/Input'; +import InputLabel from '@mui/material/InputLabel'; +import Button from '@mui/material/Button'; +import ButtonGroup from '@mui/material/ButtonGroup'; +import FormControl from '@mui/material/FormControl'; +import FormHelperText from '@mui/material/FormHelperText'; +import ClickAwayListener from '@mui/material/ClickAwayListener'; const useStyles = makeStyles((theme) => ({ root: { diff --git a/client/src/components/common/EventListItem.jsx b/client/src/components/common/EventListItem.jsx index b953217..c990023 100644 --- a/client/src/components/common/EventListItem.jsx +++ b/client/src/components/common/EventListItem.jsx @@ -3,23 +3,24 @@ import { useHistory } from 'react-router-dom'; import { connect, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { formatDistanceToNow } from 'date-fns'; -import Tooltip from '@material-ui/core/Tooltip'; -import { makeStyles, useTheme } from '@material-ui/core/styles'; -import Card from '@material-ui/core/Card'; -import CardHeader from '@material-ui/core/CardHeader'; -import CardContent from '@material-ui/core/CardContent'; -import CardActions from '@material-ui/core/CardActions'; -import CardMedia from '@material-ui/core/CardMedia'; -import Alert from '@material-ui/lab/Alert'; -import Typography from '@material-ui/core/Typography'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import IconButton from '@material-ui/core/IconButton'; -import Button from '@material-ui/core/Button'; -import PublicIcon from '@material-ui/icons/Public'; -import PrivateIcon from '@material-ui/icons/Lock'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import ShareIcon from '@material-ui/icons/Share'; +import Tooltip from '@mui/material/Tooltip'; +import { useTheme } from '@mui/material/styles'; +import { makeStyles } from '@mui/styles'; +import Card from '@mui/material/Card'; +import CardHeader from '@mui/material/CardHeader'; +import CardContent from '@mui/material/CardContent'; +import CardActions from '@mui/material/CardActions'; +import CardMedia from '@mui/material/CardMedia'; +import Alert from '@mui/material/Alert'; +import Typography from '@mui/material/Typography'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import IconButton from '@mui/material/IconButton'; +import Button from '@mui/material/Button'; +import PublicIcon from '@mui/icons-material/Public'; +import PrivateIcon from '@mui/icons-material/Lock'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import ShareIcon from '@mui/icons-material/Share'; import { useConfirm } from 'material-ui-confirm'; import { TwitchEmbed } from 'react-twitch-embed'; import { lcFetch } from '../../lib/fetch'; @@ -167,7 +168,7 @@ function RoomListItem({ id={`channel-${room.twitchChannel}-${room._id}`} muted withChat={false} - theme={theme.palette.type} + theme={theme.palette.mode} width="100%" /> diff --git a/client/src/components/common/HelpPopover.jsx b/client/src/components/common/HelpPopover.jsx index ba58ece..b0cd17f 100644 --- a/client/src/components/common/HelpPopover.jsx +++ b/client/src/components/common/HelpPopover.jsx @@ -1,10 +1,10 @@ import React, { useState } from 'react'; -import Popover from '@material-ui/core/Popover'; -import Typography from '@material-ui/core/Typography'; -import IconButton from '@material-ui/core/IconButton'; -import HelpIcon from '@material-ui/icons/Help'; +import Popover from '@mui/material/Popover'; +import Typography from '@mui/material/Typography'; +import IconButton from '@mui/material/IconButton'; +import HelpIcon from '@mui/icons-material/Help'; -export default () => { +const HelpPopover = () => { const [helpAnchor, setHelpAnchor] = useState(null); return ( @@ -39,3 +39,5 @@ export default () => {
); }; + +export default HelpPopover; diff --git a/client/src/components/common/ListItemLink.jsx b/client/src/components/common/ListItemLink.jsx index 26318db..74e3db7 100644 --- a/client/src/components/common/ListItemLink.jsx +++ b/client/src/components/common/ListItemLink.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; -import ListItem from '@material-ui/core/ListItem'; +import ListItem from '@mui/material/ListItem'; function ListItemLink({ children, to, disabled }) { return ( diff --git a/client/src/components/common/PrivateRoute.jsx b/client/src/components/common/PrivateRoute.jsx index d1564e2..e91d6b8 100644 --- a/client/src/components/common/PrivateRoute.jsx +++ b/client/src/components/common/PrivateRoute.jsx @@ -4,7 +4,7 @@ import { Route, Redirect } from 'react-router-dom'; import { connect } from 'react-redux'; const PrivateRoute = ({ - user, children, isAdminRoute, ...rest + user, isAdminRoute, ...rest }) => { const { fetching, id } = user; const loggedIn = !fetching && id; @@ -24,16 +24,11 @@ const PrivateRoute = ({ }; PrivateRoute.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), isAdminRoute: PropTypes.bool, user: PropTypes.shape(), }; PrivateRoute.defaultProps = { - children: [], isAdminRoute: false, user: { }, diff --git a/client/src/components/common/Profile.jsx b/client/src/components/common/Profile.jsx index 9a9bda0..738ccec 100644 --- a/client/src/components/common/Profile.jsx +++ b/client/src/components/common/Profile.jsx @@ -1,15 +1,15 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { makeStyles } from '@material-ui/core/styles'; -import Paper from '@material-ui/core/Paper'; -import Grid from '@material-ui/core/Grid'; -import Avatar from '@material-ui/core/Avatar'; -import Typography from '@material-ui/core/Typography'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Checkbox from '@material-ui/core/Checkbox'; -import Divider from '@material-ui/core/Divider'; -import Alert from '@material-ui/lab/Alert'; +import { makeStyles } from '@mui/styles'; +import Paper from '@mui/material/Paper'; +import Grid from '@mui/material/Grid'; +import Avatar from '@mui/material/Avatar'; +import Typography from '@mui/material/Typography'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import Divider from '@mui/material/Divider'; +import Alert from '@mui/material/Alert'; import EditableTextField from './EditableTextField'; import { lcFetch } from '../../lib/fetch'; import { updateProfile } from '../../store/user/actions'; diff --git a/client/src/components/common/Scramble.jsx b/client/src/components/common/Scramble.jsx index 5629e7e..6556cba 100644 --- a/client/src/components/common/Scramble.jsx +++ b/client/src/components/common/Scramble.jsx @@ -1,8 +1,8 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@mui/styles'; +import Typography from '@mui/material/Typography'; const useStyles = makeStyles((theme) => ({ root: { @@ -18,7 +18,7 @@ const useStyles = makeStyles((theme) => ({ disabled: { color: theme.palette.text.disabled, }, - // eslint-disable-next-line quote-props + minx: { lineHeight: '.90rem', fontSize: '.75rem', diff --git a/client/src/components/common/Scramble.test.jsx b/client/src/components/common/Scramble.test.jsx index 1fbad03..76e2ba2 100644 --- a/client/src/components/common/Scramble.test.jsx +++ b/client/src/components/common/Scramble.test.jsx @@ -1,15 +1,25 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { render, screen } from '@testing-library/react'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; import Scramble from './Scramble'; const scramble = 'test'; +const theme = createTheme(); + +const renderScramble = (props) => render( + + + , +); it('renders without crashing', () => { - shallow(); + renderScramble({ scrambles: [scramble] }); + + expect(screen.getByText(scramble)).toBeInTheDocument(); }); it('renders 3x3 text correctly', () => { - const component = shallow(); + renderScramble({ event: '333', scrambles: [scramble] }); - expect(component.text()).toEqual(scramble); + expect(screen.getByText(scramble)).toHaveTextContent(scramble); }); diff --git a/client/src/components/common/TableCellButton.jsx b/client/src/components/common/TableCellButton.jsx index bccea20..c67a799 100644 --- a/client/src/components/common/TableCellButton.jsx +++ b/client/src/components/common/TableCellButton.jsx @@ -1,9 +1,9 @@ import React from 'react'; import clsx from 'clsx'; import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import TableCell from '@material-ui/core/TableCell'; -import Button from '@material-ui/core/Button'; +import { makeStyles } from '@mui/styles'; +import TableCell from '@mui/material/TableCell'; +import Button from '@mui/material/Button'; const useStyles = makeStyles(() => ({ root: { @@ -26,13 +26,13 @@ function TableCellButton({