From a0c6515b2322f9a07116a2cdab668f75b17fed3c Mon Sep 17 00:00:00 2001 From: DillonDavidson Date: Tue, 26 Mar 2024 03:56:37 -0700 Subject: [PATCH 1/2] Added features to the Settings Page and a test file --- app/src/App.js | 27 +-- app/src/contexts/FontSizeContext.js | 139 +++++++++++++ app/src/global.css | 10 + app/src/pages/SettingsPage.js | 31 --- app/src/pages/SettingsPage.module.css | 53 ----- app/src/pages/Skeleton.js | 24 --- app/src/pages/home/Home.module.css | 1 + app/src/pages/{ => login}/Login.css | 0 app/src/pages/{ => login}/Login.js | 0 app/src/pages/{ => quests}/QuestsPage.js | 12 +- .../pages/{ => quests}/QuestsPage.module.css | 11 +- app/src/pages/quiz/QuizPage.js | 19 +- app/src/pages/quiz/QuizPage.module.css | 22 +- app/src/pages/settings/SettingsPage.js | 79 ++++++++ .../pages/settings/SettingsPage.module.css | 191 ++++++++++++++++++ app/src/pages/skeleton/Skeleton.js | 31 +++ .../pages/{ => skeleton}/Skeleton.module.css | 7 +- app/src/tests/SettingsPage.test.js | 31 +++ 18 files changed, 547 insertions(+), 141 deletions(-) mode change 100644 => 100755 app/src/App.js create mode 100755 app/src/contexts/FontSizeContext.js mode change 100644 => 100755 app/src/global.css delete mode 100644 app/src/pages/SettingsPage.js delete mode 100644 app/src/pages/SettingsPage.module.css delete mode 100644 app/src/pages/Skeleton.js mode change 100644 => 100755 app/src/pages/home/Home.module.css rename app/src/pages/{ => login}/Login.css (100%) rename app/src/pages/{ => login}/Login.js (100%) rename app/src/pages/{ => quests}/QuestsPage.js (87%) mode change 100644 => 100755 rename app/src/pages/{ => quests}/QuestsPage.module.css (87%) mode change 100644 => 100755 mode change 100644 => 100755 app/src/pages/quiz/QuizPage.js mode change 100644 => 100755 app/src/pages/quiz/QuizPage.module.css create mode 100755 app/src/pages/settings/SettingsPage.js create mode 100755 app/src/pages/settings/SettingsPage.module.css create mode 100755 app/src/pages/skeleton/Skeleton.js rename app/src/pages/{ => skeleton}/Skeleton.module.css (80%) mode change 100644 => 100755 create mode 100755 app/src/tests/SettingsPage.test.js diff --git a/app/src/App.js b/app/src/App.js old mode 100644 new mode 100755 index 93503e21..c484529d --- a/app/src/App.js +++ b/app/src/App.js @@ -5,12 +5,13 @@ import { useNavigationType, useLocation, } from "react-router-dom"; -import Skeleton from "./pages/Skeleton"; -import Login from "./pages/Login"; +import { FontSizeProvider } from "./contexts/FontSizeContext"; +import Skeleton from "./pages/skeleton/Skeleton"; +import Login from "./pages/login/Login"; import Home from "./pages/home/Home"; -import SettingsPage from './pages/SettingsPage'; +import SettingsPage from './pages/settings/SettingsPage'; import QuizPage from "./pages/quiz/QuizPage"; -import QuestsPage from './pages/QuestsPage'; +import QuestsPage from './pages/quests/QuestsPage'; function App() { const action = useNavigationType(); @@ -49,14 +50,16 @@ function App() { }, [pathname]); return ( - - } /> - } /> - } /> - } /> - } /> - } /> - + + + } /> + } /> + } /> + } /> + } /> + } /> + + ); } export default App; \ No newline at end of file diff --git a/app/src/contexts/FontSizeContext.js b/app/src/contexts/FontSizeContext.js new file mode 100755 index 00000000..df4c0d27 --- /dev/null +++ b/app/src/contexts/FontSizeContext.js @@ -0,0 +1,139 @@ +import React, { createContext, useState, useContext, useEffect } from 'react'; + +const FontSizeContext = createContext(); + +export const useFontSize = () => useContext(FontSizeContext); + +export const FontSizeProvider = ({ children }) => { + const defaultTitleFontSize = 24; + const defaultTextFontSize = 18; + const defaultButtonFontSize = 12; + + const MIN_TITLE_FONT_SIZE = 18; + const MAX_TITLE_FONT_SIZE = 36; + const MIN_TEXT_FONT_SIZE = 12; + const MAX_TEXT_FONT_SIZE = 30; + const MIN_BUTTON_FONT_SIZE = 6; + const MAX_BUTTON_FONT_SIZE = 24; + + const [titleFontSize, setTitleFontSize] = useState(() => { + const storedSize = localStorage.getItem('titleFontSize'); + return storedSize ? parseInt(storedSize) : defaultTitleFontSize; + }); + + const [textFontSize, setTextFontSize] = useState(() => { + const storedSize = localStorage.getItem('textFontSize'); + return storedSize ? parseInt(storedSize) : defaultTextFontSize; + }); + + const [buttonFontSize, setButtonFontSize] = useState(() => { + const storedSize = localStorage.getItem('buttonFontSize'); + return storedSize ? parseInt(storedSize) : defaultButtonFontSize; + }); + + // Define state for dark mode preference + const [darkMode, setDarkMode] = useState(() => { + const storedMode = localStorage.getItem('darkMode'); + return storedMode ? JSON.parse(storedMode) : false; + }); + + // Toggle dark mode function + const toggleDarkMode = () => { + setDarkMode(prevMode => !prevMode); + localStorage.setItem('darkMode', JSON.stringify(!darkMode)); + }; + + useEffect(() => { + // Apply dark mode styles dynamically + if (darkMode) { + document.documentElement.classList.add('dark-mode'); + } else { + document.documentElement.classList.remove('dark-mode'); + } + // Update dark mode preference in local storage + localStorage.setItem('darkMode', JSON.stringify(darkMode)); + }, [darkMode]); + + const updateFontSize = (size, setter, key) => { + setter(size); + localStorage.setItem(key, size.toString()); + }; + + const increaseFontSize = () => { + if (titleFontSize < MAX_TITLE_FONT_SIZE) + { + updateFontSize(titleFontSize + 2, setTitleFontSize, 'titleFontSize'); + } + + if (textFontSize < MAX_TEXT_FONT_SIZE) + { + updateFontSize(textFontSize + 2, setTextFontSize, 'textFontSize'); + } + + if (buttonFontSize < MAX_BUTTON_FONT_SIZE) + { + updateFontSize(buttonFontSize + 2, setButtonFontSize, 'buttonFontSize'); + } + }; + + const decreaseFontSize = () => { + if (titleFontSize > MIN_TITLE_FONT_SIZE) + { + updateFontSize(titleFontSize - 2, setTitleFontSize, 'titleFontSize'); + } + + if (textFontSize > MIN_TEXT_FONT_SIZE) + { + updateFontSize(textFontSize - 2, setTextFontSize, 'textFontSize'); + } + + if (buttonFontSize > MIN_BUTTON_FONT_SIZE) + { + updateFontSize(buttonFontSize - 2, setButtonFontSize, 'buttonFontSize'); + } + }; + + const resetFontSize = () => { + setTitleFontSize(defaultTitleFontSize); + setTextFontSize(defaultTextFontSize); + setButtonFontSize(defaultButtonFontSize); + localStorage.removeItem('titleFontSize'); + localStorage.removeItem('textFontSize'); + localStorage.removeItem('buttonFontSize'); + }; + + useEffect(() => { + localStorage.setItem('titleFontSize', titleFontSize.toString()); + }, [titleFontSize]); + + useEffect(() => { + localStorage.setItem('textFontSize', textFontSize.toString()); + }, [textFontSize]); + + useEffect(() => { + localStorage.setItem('buttonFontSize', buttonFontSize.toString()); + }, [buttonFontSize]); + + useEffect(() => { + document.documentElement.style.setProperty('--title-font-size', `${titleFontSize}px`); + document.documentElement.style.setProperty('--text-font-size', `${textFontSize}px`); + document.documentElement.style.setProperty('--button-font-size', `${buttonFontSize}px`); + }, [titleFontSize, textFontSize, buttonFontSize]); + + return ( + + {children} + + ); +}; diff --git a/app/src/global.css b/app/src/global.css old mode 100644 new mode 100755 index 0566a41e..b2938639 --- a/app/src/global.css +++ b/app/src/global.css @@ -2,12 +2,22 @@ body { margin: 0; line-height: normal; + font-size: var(--dynamic-font-size); } :root { /* fonts */ --font-roboto: Roboto; + /* default font size */ + --title-font-size: 24px; + --text-font-size: 18px; + --button-font-size: 16px; + /* Colors */ --color-black: #000; --color-gainsboro: rgba(217, 217, 217, 0.5); + --background-color-light: #ffffff; /* Light mode background color */ + --text-color-light: #000000; /* Light mode text color */ + --background-color-dark: #333333; /* Dark mode background color */ + --text-color-dark: #ffffff; /* Dark mode text color */ } diff --git a/app/src/pages/SettingsPage.js b/app/src/pages/SettingsPage.js deleted file mode 100644 index 4a898466..00000000 --- a/app/src/pages/SettingsPage.js +++ /dev/null @@ -1,31 +0,0 @@ -import NavigationPanel from "../components/NavigationPanel"; -import Frame from "../components/TopPanel"; -import PageContent from "../components/PageContent"; -import styles from "./SettingsPage.module.css"; - -const SettingsPage = () => { - const handleButtonClick = () => { - window.location.href = "https://wikipedia.com"; // Redirects to Wikipedia - }; - - return ( -
- - - - - -
- ); -}; - -export default SettingsPage; \ No newline at end of file diff --git a/app/src/pages/SettingsPage.module.css b/app/src/pages/SettingsPage.module.css deleted file mode 100644 index 52b67160..00000000 --- a/app/src/pages/SettingsPage.module.css +++ /dev/null @@ -1,53 +0,0 @@ -.settingsPagePage { - align-self: stretch; - position: relative; - font-weight: 900; - text-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); -} -.pageLabel { - cursor: pointer; - position: absolute; - top: 128px; - left: 17px; - width: 366px; - overflow: hidden; - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; -} -.settingsPage { - width: 100%; - height: 852px; - position: relative; - border: 2px solid var(--color-black); - box-sizing: border-box; - overflow: hidden; - min-width: 393px; - max-width: 393px; - min-height: 852px; - max-height: 852px; - text-align: center; - font-size: 32px; - color: var(--color-black); - font-family: var(--font-roboto); -} -@media screen and (max-width: 1200px) { - .settingsPage { - height: 852px; - min-width: 393px; - max-width: 393px; - min-height: 852px; - max-height: 852px; - } -} -.button { - background-color: #007bff; - color: white; - padding: 10px 20px; - border: none; - border-radius: 5px; - cursor: pointer; - font-size: 18px; - margin-top: 20px; -} \ No newline at end of file diff --git a/app/src/pages/Skeleton.js b/app/src/pages/Skeleton.js deleted file mode 100644 index a61c051f..00000000 --- a/app/src/pages/Skeleton.js +++ /dev/null @@ -1,24 +0,0 @@ -import NavigationPanel from "../components/NavigationPanel"; -import Frame from "../components/TopPanel"; -import PageContent from "../components/PageContent"; -import styles from "./Skeleton.module.css"; - -const Skeleton = () => { - return ( -
- - - - -
- ); -}; - -export default Skeleton; diff --git a/app/src/pages/home/Home.module.css b/app/src/pages/home/Home.module.css old mode 100644 new mode 100755 index 6119a758..fc4222da --- a/app/src/pages/home/Home.module.css +++ b/app/src/pages/home/Home.module.css @@ -3,6 +3,7 @@ position: relative; font-weight: 900; text-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); + font-size: var(--title-font-size); } .pageLabel { cursor: pointer; diff --git a/app/src/pages/Login.css b/app/src/pages/login/Login.css similarity index 100% rename from app/src/pages/Login.css rename to app/src/pages/login/Login.css diff --git a/app/src/pages/Login.js b/app/src/pages/login/Login.js similarity index 100% rename from app/src/pages/Login.js rename to app/src/pages/login/Login.js diff --git a/app/src/pages/QuestsPage.js b/app/src/pages/quests/QuestsPage.js old mode 100644 new mode 100755 similarity index 87% rename from app/src/pages/QuestsPage.js rename to app/src/pages/quests/QuestsPage.js index 9b7dccf3..b0707188 --- a/app/src/pages/QuestsPage.js +++ b/app/src/pages/quests/QuestsPage.js @@ -1,10 +1,14 @@ import React, { useState } from "react"; -import NavigationPanel from "../components/NavigationPanel"; -import Frame from "../components/TopPanel"; -import PageContent from "../components/PageContent"; +import NavigationPanel from "../../components/NavigationPanel"; +import Frame from "../../components/TopPanel"; +import PageContent from "../../components/PageContent"; import styles from "./QuestsPage.module.css"; +import { useFontSize } from '../../contexts/FontSizeContext'; const QuestsPage = () => { + const { fontSize, darkMode } = useFontSize(); + const pageClassName = darkMode ? `${styles.QuestsPage} ${styles.darkMode}` : styles.QuestsPage; + // State to manage all quests const [quests, setQuests] = useState([{ title: "Sample Title", text: "Sample Text" }]); // State to manage quests in progress @@ -40,7 +44,7 @@ const QuestsPage = () => { }; return ( -
+