From a690478ef3de4e06deb68d7b5cedbc9f2b6eb6e3 Mon Sep 17 00:00:00 2001 From: martin-mfg <2026226+martin-mfg@users.noreply.github.com> Date: Sun, 23 Nov 2025 14:24:36 +0100 Subject: [PATCH] refactor useSelector usage, use default userId everywhere --- frontend/frontend/src/axios-override.js | 9 ++++--- frontend/frontend/src/components/Card/SVG.js | 21 ++++++++-------- frontend/frontend/src/pages/App/AppTrends.js | 18 +++++++------- frontend/frontend/src/pages/App/Header.js | 6 ++--- frontend/frontend/src/pages/Auth/SignUp.js | 4 ---- frontend/frontend/src/pages/Home/Home.js | 14 +++++++---- .../frontend/src/pages/Home/stages/Login.js | 14 +++++++---- .../src/pages/Home/stages/SelectCard.js | 8 +++---- .../frontend/src/pages/Landing/Landing.js | 6 ++--- .../frontend/src/pages/Settings/Settings.js | 16 +++++++++---- .../src/redux/selectors/userSelectors.js | 24 +++++++++++++++++++ 11 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 frontend/frontend/src/redux/selectors/userSelectors.js diff --git a/frontend/frontend/src/axios-override.js b/frontend/frontend/src/axios-override.js index a69372da..da3ba872 100644 --- a/frontend/frontend/src/axios-override.js +++ b/frontend/frontend/src/axios-override.js @@ -35,18 +35,17 @@ function createMockResponse(data, config) { }); } -// store userId outside React context so the interceptor can access it -let userId = null; +// store isAuthenticated outside React context so the interceptor can access it +let isAuthenticated = null; -export function setUserId(newUserId) { - userId = newUserId; +export function setIsAuthenticated(newIsAuthenticated) { + isAuthenticated = newIsAuthenticated; } const defaultAdapter = getAdapter(axios.defaults.adapter); // mock responses to unauthenticated "anuraghazra" requests axios.defaults.adapter = async (config) => { - const isAuthenticated = userId && userId.length > 0; if (isAuthenticated) { return defaultAdapter(config); } diff --git a/frontend/frontend/src/components/Card/SVG.js b/frontend/frontend/src/components/Card/SVG.js index 9e59251e..fb486538 100644 --- a/frontend/frontend/src/components/Card/SVG.js +++ b/frontend/frontend/src/components/Card/SVG.js @@ -4,27 +4,29 @@ import React, { useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; - import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; import { createMockReq, createMockRes } from '../../mock-http'; import { default as router } from '../../backend/.vercel/output/functions/api.func/router.js'; -import { setUserId } from '../../axios-override'; +import { setIsAuthenticated } from '../../axios-override'; +import { + useIsAuthenticated, + useUserToken, +} from '../../redux/selectors/userSelectors'; const SvgInline = (props) => { const [svg, setSvg] = useState(null); const [loaded, setLoaded] = useState(false); const containerRef = useRef(null); - const userToken = useSelector((state) => state.user.token); - const userId = useSelector((state) => state.user.userId); + const userToken = useUserToken(); + const isAuthenticated = useIsAuthenticated(); const { url } = props; - // provide userId to non-react code in axios-override.js + // provide isAuthenticated to non-react code in axios-override.js useEffect(() => { - setUserId(userId); - }, [userId]); + setIsAuthenticated(isAuthenticated); + }, [isAuthenticated]); useEffect(() => { const loadSvg = async () => { @@ -35,7 +37,6 @@ const SvgInline = (props) => { let body; let status; - const isAuthenticated = userId && userId.length > 0; if (isAuthenticated && (!userToken || userToken === 'placeholderPAT')) { // waiting for backend call to private-access return; @@ -67,7 +68,7 @@ const SvgInline = (props) => { setLoaded(true); }; loadSvg(); - }, [userToken, userId, props.url]); + }, [userToken, isAuthenticated, props.url]); useEffect(() => { if (loaded && svg && containerRef.current) { diff --git a/frontend/frontend/src/pages/App/AppTrends.js b/frontend/frontend/src/pages/App/AppTrends.js index 0e58f649..783b573e 100644 --- a/frontend/frontend/src/pages/App/AppTrends.js +++ b/frontend/frontend/src/pages/App/AppTrends.js @@ -1,12 +1,7 @@ import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; -import { - BrowserRouter as Router, - Route, - Routes, - useParams, -} from 'react-router-dom'; +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { logout as _logout, setUserAccess as _setUserAccess, @@ -20,11 +15,14 @@ import SettingsScreen from '../Settings'; import { NoMatchScreen } from '../Misc'; import { getUserMetadata } from '../../api'; import Footer from './Footer'; +import { + useIsAuthenticated, + useUserKey, +} from '../../redux/selectors/userSelectors'; function App() { - const userId = useSelector((state) => state.user.userId); - const userKey = useSelector((state) => state.user.userKey); - const isAuthenticated = userId && userId.length > 0; + const userKey = useUserKey(); + const isAuthenticated = useIsAuthenticated(); const dispatch = useDispatch(); const setUserAccess = (access) => diff --git a/frontend/frontend/src/pages/App/Header.js b/frontend/frontend/src/pages/App/Header.js index fc7f8b89..627d40e7 100644 --- a/frontend/frontend/src/pages/App/Header.js +++ b/frontend/frontend/src/pages/App/Header.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; @@ -8,6 +8,7 @@ import { GiHamburgerMenu as HamburgerIcon } from 'react-icons/gi'; import { MdSettings as SettingsIcon } from 'react-icons/md'; import { logout as _logout } from '../../redux/actions/userActions'; +import { useIsAuthenticated } from '../../redux/selectors/userSelectors'; import appIcon from '../../assets/appLogo64.png'; import { classnames } from '../../utils'; import { GITHUB_PUBLIC_AUTH_URL } from '../../constants'; @@ -61,8 +62,7 @@ MobileLink.defaultProps = defaultProps; const Header = ({ mode }) => { const [toggle, setToggle] = useState(false); - const userId = useSelector((state) => state.user.userId); - const isAuthenticated = userId && userId.length > 0; + const isAuthenticated = useIsAuthenticated(); const dispatch = useDispatch(); const logout = () => dispatch(_logout()); diff --git a/frontend/frontend/src/pages/Auth/SignUp.js b/frontend/frontend/src/pages/Auth/SignUp.js index a8d0d85e..56963f36 100644 --- a/frontend/frontend/src/pages/Auth/SignUp.js +++ b/frontend/frontend/src/pages/Auth/SignUp.js @@ -1,5 +1,4 @@ import React from 'react'; -import { useSelector } from 'react-redux'; import { FaGithub as GithubIcon } from 'react-icons/fa'; @@ -13,9 +12,6 @@ import { classnames } from '../../utils'; import mockup from '../../assets/mockup.png'; const SignUpScreen = () => { - // eslint-disable-next-line no-unused-vars - const userId = useSelector((state) => state.user.userId); - return (