diff --git a/greenscoutjs/public/themes/dark.css b/greenscoutjs/public/themes/dark.css new file mode 100644 index 00000000..8dcda3a7 --- /dev/null +++ b/greenscoutjs/public/themes/dark.css @@ -0,0 +1,34 @@ +html { + scrollbar-color: var(--font-color-prompt-title) var(--background-color); +} + +:root { + /* Color Variables */ + --background-color: #3c3c3c; + --accent-color: #9bcbfb; + --accent-color2: #8fbdeb; + --accent-color3: #cee5ff; + + --matchform-sectionbox-background-color: rgba(0, 0, 0, 0.1); + + --blue-color: #9bcbfb; + --error-color: var(--disabled-color); + --disabled-color: #717172; + + --font-color: black; + --font-color-prompt-title: white; + --font-color-header: white; + + --drop-shadow-color: #626263; + --sidenav-hover-color: var(--accent-color); + --faded-text-color: #5f6167; + + --kelly-green: #4cbb17; + --error-message-color: var(--disabled-color); + --check-background-color: #4cbb17; + --checkbox-default-color: #eee; + --checkbox-hover-color: #ccc; + --border-color-faded: #d9d9db; + --border-color-active: #417096; + --sidenav-button-color: #dfdfdf; +} diff --git a/greenscoutjs/public/themes/green.css b/greenscoutjs/public/themes/green.css new file mode 100644 index 00000000..d6a7d6b4 --- /dev/null +++ b/greenscoutjs/public/themes/green.css @@ -0,0 +1,34 @@ +html { + scrollbar-color: var(--font-color-prompt-title) var(--background-color); +} + +:root { + /* Color Variables */ + --background-color: #3c3c3c; + --accent-color: linear-gradient(0deg, #3aea3a 0%, #59eb5a 100%); + --accent-color2: linear-gradient(0deg, #3aea3a 0%, #59eb5a 100%); + --accent-color3: linear-gradient(0deg, #3db43d 0%, #43c343 100%); + + --matchform-sectionbox-background-color: rgba(0, 0, 0, 0.1); + + --blue-color: #9bcbfb; + --error-color: var(--disabled-color); + --disabled-color: #717172; + + --font-color: black; + --font-color-prompt-title: white; + --font-color-header: white; + + --drop-shadow-color: #626263; + --sidenav-hover-color: linear-gradient(0deg, #3aea3a 0%, #59eb5a 100%); + --faded-text-color: #5f6167; + + --kelly-green: #4cbb17; + --error-message-color: var(--disabled-color); + --check-background-color: #4cbb17; + --checkbox-default-color: #eee; + --checkbox-hover-color: #ccc; + --border-color-faded: #d9d9db; + --border-color-active: #4cbb17; + --sidenav-button-color: #dfdfdf; +} diff --git a/greenscoutjs/public/themes/light.css b/greenscoutjs/public/themes/light.css new file mode 100644 index 00000000..ebb26fc7 --- /dev/null +++ b/greenscoutjs/public/themes/light.css @@ -0,0 +1,34 @@ +html { + scrollbar-color: var(--font-color-prompt-title) var(--background-color); +} + +:root { + /* Color Variables */ + --background-color: white; + --accent-color: #9bcbfb; + --accent-color2: #8fbdeb; + --accent-color3: #cee5ff; + + --matchform-sectionbox-background-color: rgba(0, 0, 0, 0.1); + + --blue-color: #9bcbfb; + --error-color: var(--disabled-color); + --disabled-color: #717172; + + --font-color: black; + --font-color-prompt-title: black; + --font-color-header: black; + + --drop-shadow-color: #626263; + --sidenav-hover-color: var(--accent-color); + --faded-text-color: #5f6167; + + --kelly-green: #4cbb17; + --error-message-color: var(--disabled-color); + --check-background-color: #4cbb17; + --checkbox-default-color: #eee; + --checkbox-hover-color: #ccc; + --border-color-faded: #d9d9db; + --border-color-active: #417096; + --sidenav-button-color: #dfdfdf; +} diff --git a/greenscoutjs/src/App.jsx b/greenscoutjs/src/App.jsx index 6f114ab7..36387561 100644 --- a/greenscoutjs/src/App.jsx +++ b/greenscoutjs/src/App.jsx @@ -19,6 +19,34 @@ import SettingsThemes from "./components/settings-sub-pages/themes/SettingsTheme import { useState, useEffect } from "react"; function App() { + useEffect(() => { + const updateStylesheet = () => { + const rawTheme = localStorage.getItem("app-theme") || "light"; + const savedTheme = rawTheme.toLowerCase(); + + let link = document.getElementById("dynamic-theme-link"); + if (!link) { + link = document.createElement("link"); + link.id = "dynamic-theme-link"; + link.rel = "stylesheet"; + document.head.appendChild(link); + } + + const base = import.meta.env.BASE_URL.endsWith("/") + ? import.meta.env.BASE_URL + : `${import.meta.env.BASE_URL}/`; + + const newHref = `${base}themes/${savedTheme}.css`; + + console.log("Loading CSS from:", newHref); + link.href = newHref; + }; + + updateStylesheet(); + window.addEventListener("storage", updateStylesheet); + return () => window.removeEventListener("storage", updateStylesheet); + }, []); + const getIpAddress = async () => { try { const response = await fetch("https://api.ipify.org?format=json"); diff --git a/greenscoutjs/src/components/NavComponent.css b/greenscoutjs/src/components/NavComponent.css index b9a43623..98cbdaa5 100644 --- a/greenscoutjs/src/components/NavComponent.css +++ b/greenscoutjs/src/components/NavComponent.css @@ -19,7 +19,7 @@ body { padding: 0; height: var(--navbar-height); width: 100%; - background-color: var(--accent-color); + background: var(--sidenav-hover-color); z-index: 999999; } @@ -36,7 +36,7 @@ body { margin-left: calc(0.1 * var(--navbar-height)); height: calc(0.5 * var(--navbar-height)); width: calc(0.5 * var(--navbar-height)); - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../assets/bars-solid-full.svg"); mask-image: url("../assets/bars-solid-full.svg"); mask-repeat: no-repeat; @@ -57,7 +57,7 @@ body { margin-left: calc(0.1 * var(--navbar-height)); height: calc(0.5 * var(--navbar-height)); width: calc(0.5 * var(--navbar-height)); - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../assets/arrow-left-solid-full.svg"); mask-image: url("../assets/arrow-left-solid-full.svg"); mask-repeat: no-repeat; @@ -150,9 +150,13 @@ body { text-decoration: none; } +.side-nav button { + background: var(--accent-color); +} + .side-nav button:hover { - background-color: var(--sidenav-hover-color); - color: var(--background-color); + background: var(--sidenav-hover-color); + /* color: var(--background-color); */ cursor: pointer; } @@ -172,8 +176,12 @@ body { left: var(--sidenav-width); } +#nav-toggle:checked ~ .hamburger { + background: var(--accent-color); +} + .textp { - background-color: var(--sidenav-button-color); + background: var(--sidenav-button-color); font-family: Arial, Helvetica, sans-serif; font-weight: bold; color: var(--font-color); diff --git a/greenscoutjs/src/components/Settings.jsx b/greenscoutjs/src/components/Settings.jsx index 770697bf..86107223 100644 --- a/greenscoutjs/src/components/Settings.jsx +++ b/greenscoutjs/src/components/Settings.jsx @@ -26,10 +26,10 @@ function Settings() {

Settings

- {/* */} + )} */} - - - -
-

Auto Mode

+
+
+

Match Info

+
+ + +
- - Robot Moves? - - - Does Auto Hang? - - - - - - - - Won Auto? - - -

 Went To:

+
+
+

Auto Mode

+
- Left Of Field + Robot Moves? - Right Of Field + Does Auto Hang? - - Middle Of Field - - + - Right Of Field - - + - Top Of Field - - + - Over Bump - - + - Under Trench - + nameText="Robot Accuracy:" + name="autoRobotAccuracy" + > - Didn't Cross + Won Auto? + +

 Went To:

+ + Left Of Field + + + Right Of Field + + + Middle Of Field + + + Right Of Field + + + Top Of Field + + + Over Bump + + + Under Trench + + + Didn't Cross + + + HP Station + + + Fuel Station + +
+
+
+
+

TeleOp Mode

+
+
+

Collection Ability

+
+ + + +
+

+ Hang +

+
+ +
+ +
+
+ +

 Went:

+ + Over Bump + + + Under Trench + +
+
+
+
+

End Game

+
+ - HP Station + Shot During Endgame? +
+
+
+

Misc.

+
+ + - Fuel Station + Was Their Robot Disconnected Or Disabled? - -
-

TeleOp Mode

-
- - - -
-

Collection Ability

-
- - - -
-

- Hang -

-
- -
- -
-
- -

 Went:

- Over Bump + Did You Lose Track At Any Point? - Under Trench + Were They Ever Beached? -
-
-

End Game

-
- - - Shot During Endgame? - -
-

Misc.

-
- - - - Was Their Robot Disconnected Or Disabled? - - - Did You Lose Track At Any Point? - - - Were They Ever Beached? - -
- -

 Auto Notes:

-
- -
-

 TeleOp Notes:

-
- -
-

 Performance Notes:

-
- +
+

 TeleOp Notes:

+
+ +
+

 Performance Notes:

+
+ -
-

 Special Events Notes:

-
- +
+

 Special Events Notes:

+
+ -
-

 Any Other Comments:

-
- -
-
+ value={formData.eventsNotes} + onChange={handleChange} + className="notesbox" + > +
+

 Any Other Comments:

+
+ +
+
+
- + type="number" + step="1" + >
); } diff --git a/greenscoutjs/src/components/matchform/auto/dropdown/Dropdown.css b/greenscoutjs/src/components/matchform/auto/dropdown/Dropdown.css index f46f47a3..fc55d278 100644 --- a/greenscoutjs/src/components/matchform/auto/dropdown/Dropdown.css +++ b/greenscoutjs/src/components/matchform/auto/dropdown/Dropdown.css @@ -1,6 +1,5 @@ .textDropdown, .textCollectDrop { - background-color: var(--background-color); font-family: Arial, Helvetica, sans-serif; font-weight: lighter; color: var(--font-color-prompt-title); @@ -16,6 +15,10 @@ cursor: default; } +.dropdown { + background: var(--background-color); +} + .dropdown, #collectdropdown { flex-shrink: 0; @@ -28,8 +31,8 @@ border-bottom: gray solid 1px; color: var(--font-color-prompt-title); font-size: var(--font-size-small); - background-color: var(--background-color); cursor: pointer; + background: var(--background-color); } .dropdown:focus, diff --git a/greenscoutjs/src/components/matchform/climbing-timer/TriggerButton.css b/greenscoutjs/src/components/matchform/climbing-timer/TriggerButton.css index 63686321..56736bda 100644 --- a/greenscoutjs/src/components/matchform/climbing-timer/TriggerButton.css +++ b/greenscoutjs/src/components/matchform/climbing-timer/TriggerButton.css @@ -24,12 +24,12 @@ } #sideButtonTrigger.active { - background-color: var(--error-color); + background: var(--error-color); border-color: var(--error-color); } #sideButtonTrigger.inactive { - background-color: var(--accent-color3); + background: var(--accent-color3); border-color: var(--accent-color3); } @@ -42,7 +42,7 @@ } .act { - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/square-solid-full.svg"); mask-image: url("../../../assets/square-solid-full.svg"); mask-repeat: no-repeat; @@ -54,7 +54,7 @@ } .inact { - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/stopwatch.svg"); mask-image: url("../../../assets/stopwatch.svg"); mask-repeat: no-repeat; @@ -66,7 +66,7 @@ } #resetbutton { - background-color: var(--accent-color3); + background: var(--accent-color3); border: 1px solid var(--accent-color3); border-radius: var(--border-radius); color: var(--faded-text-color); @@ -82,5 +82,5 @@ } #resetbutton:hover { - background-color: var(--accent-color2); + background: var(--accent-color2); } diff --git a/greenscoutjs/src/components/matchform/submitbuttons/ReplayButton.css b/greenscoutjs/src/components/matchform/submitbuttons/ReplayButton.css index 5823f93b..7a8afd55 100644 --- a/greenscoutjs/src/components/matchform/submitbuttons/ReplayButton.css +++ b/greenscoutjs/src/components/matchform/submitbuttons/ReplayButton.css @@ -21,14 +21,14 @@ align-items: center; width: 100%; height: 100%; - background-color: var(--accent-color); + background: var(--accent-color); gap: 0; font-size: var(--font-size-small); cursor: pointer; } .replayButton:hover { - background-color: var(--accent-color2); + background: var(--accent-color2); } .replayText { diff --git a/greenscoutjs/src/components/matchform/submitbuttons/SubmitButton.css b/greenscoutjs/src/components/matchform/submitbuttons/SubmitButton.css index c4dc6194..a55a2c40 100644 --- a/greenscoutjs/src/components/matchform/submitbuttons/SubmitButton.css +++ b/greenscoutjs/src/components/matchform/submitbuttons/SubmitButton.css @@ -22,13 +22,13 @@ justify-content: center; width: 100%; height: 100%; - background-color: var(--accent-color); + background: var(--accent-color); cursor: pointer; gap: 0.1rem; } .submitButton:hover { - background-color: var(--accent-color2); + background: var(--accent-color2); } .submitButton:disabled { @@ -46,7 +46,7 @@ } #submitImage { - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/floppy-disk-solid-full.svg"); mask-image: url("../../../assets/floppy-disk-solid-full.svg"); mask-repeat: no-repeat; diff --git a/greenscoutjs/src/components/matchform/teleopcycles/CycleButton.css b/greenscoutjs/src/components/matchform/teleopcycles/CycleButton.css index edbda436..2f8a32d5 100644 --- a/greenscoutjs/src/components/matchform/teleopcycles/CycleButton.css +++ b/greenscoutjs/src/components/matchform/teleopcycles/CycleButton.css @@ -26,12 +26,12 @@ } #sideButtonCycleTrigger.true { - background-color: var(--accent-color3); + background: var(--accent-color3); border-color: var(--accent-color3); } #sideButtonCycleTrigger.false { - background-color: var(--error-color); + background: var(--error-color); border-color: var(--error-color); } @@ -39,7 +39,7 @@ #stopImg { height: var(--cycle-image-height); width: 80%; - background-color: var(--font-color); + background: var(--font-color); mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; mask-position: center; diff --git a/greenscoutjs/src/components/matchform/teleopcycles/Cycles.jsx b/greenscoutjs/src/components/matchform/teleopcycles/Cycles.jsx index a0384b54..33653cd5 100644 --- a/greenscoutjs/src/components/matchform/teleopcycles/Cycles.jsx +++ b/greenscoutjs/src/components/matchform/teleopcycles/Cycles.jsx @@ -1,6 +1,22 @@ import "../Matchform.css"; import { useEffect, useRef } from "react"; +// Methods for handling cycles, in matchform.jsx +const updateCycleAccuracy = (index, newAccuracy) => { + setCycleList((prevList) => + prevList.map((item, i) => + i === index ? { ...item, accuracy: parseInt(newAccuracy) } : item, + ), + ); +}; + +const removeCycleEvent = (indexRemoval) => { + setCycleList((prevList) => [ + ...prevList.slice(0, indexRemoval), + ...prevList.slice(indexRemoval + 1), + ]); +}; + const Cycles = ({ list, runningBool, diff --git a/greenscoutjs/src/components/matchform/teleopcycles/ScoreButton.css b/greenscoutjs/src/components/matchform/teleopcycles/ScoreButton.css index f87f3fc8..0e8bf916 100644 --- a/greenscoutjs/src/components/matchform/teleopcycles/ScoreButton.css +++ b/greenscoutjs/src/components/matchform/teleopcycles/ScoreButton.css @@ -1,10 +1,10 @@ #scoreButton.false { - background-color: var(--accent-color3); + background: var(--accent-color3); border-color: var(--accent-color3); } #scoreButton.true { - background-color: var(--disabled-color); + background: var(--disabled-color); border-color: var(--disabled-color); } @@ -12,7 +12,7 @@ height: var(--score-image-height); width: 80%; flex-shrink: 0; - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/meteor-solid-full.svg"); mask-image: url("../../../assets/meteor-solid-full.svg"); mask-repeat: no-repeat; diff --git a/greenscoutjs/src/components/matchform/teleopcycles/ShuttleButton.css b/greenscoutjs/src/components/matchform/teleopcycles/ShuttleButton.css index 012b2875..0521522d 100644 --- a/greenscoutjs/src/components/matchform/teleopcycles/ShuttleButton.css +++ b/greenscoutjs/src/components/matchform/teleopcycles/ShuttleButton.css @@ -1,10 +1,10 @@ #shuttleButton.false { - background-color: var(--accent-color3); + background: var(--accent-color3); border-color: var(--accent-color3); } #shuttleButton.true { - background-color: var(--disabled-color); + background: var(--disabled-color); border-color: var(--disabled-color); } @@ -12,7 +12,7 @@ height: var(--cycle-image-height); width: 80%; flex-shrink: 0; - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/bus-side-solid-full.svg"); mask-image: url("../../../assets/bus-side-solid-full.svg"); mask-repeat: no-repeat; diff --git a/greenscoutjs/src/components/matchform/teleopcycles/hubSwitch.css b/greenscoutjs/src/components/matchform/teleopcycles/hubSwitch.css index d404944c..5922ce03 100644 --- a/greenscoutjs/src/components/matchform/teleopcycles/hubSwitch.css +++ b/greenscoutjs/src/components/matchform/teleopcycles/hubSwitch.css @@ -1,21 +1,21 @@ #hubSwitchButton { - background-color: var(--disabled-color); + background: var(--disabled-color); border-color: var(--accent-color3); } #hubSwitchButton.blue { - background-color: var(--blue-color); + background: var(--blue-color); } #hubSwitchButton.red { - background-color: var(--error-color); + background: var(--error-color); } #hubSwitchButtonImg { height: var(--cycle-image-height); width: 80%; flex-shrink: 0; - background-color: var(--font-color); + background: var(--font-color); -webkit-mask-image: url("../../../assets/arrow-right-arrow-left-solid-full.svg"); mask-image: url("../../../assets/arrow-right-arrow-left-solid-full.svg"); mask-repeat: no-repeat; diff --git a/greenscoutjs/src/components/settings-sub-pages/themes/ThemeDropdown.jsx b/greenscoutjs/src/components/settings-sub-pages/themes/ThemeDropdown.jsx index e7de54b0..e8f7184a 100644 --- a/greenscoutjs/src/components/settings-sub-pages/themes/ThemeDropdown.jsx +++ b/greenscoutjs/src/components/settings-sub-pages/themes/ThemeDropdown.jsx @@ -1,12 +1,33 @@ +import { useState } from "react"; import "../../settings.css"; -function ThemeDrop({ value, onChange, name }) { +function ThemeDrop({ name }) { + const [selectedTheme, setSelectedTheme] = useState( + localStorage.getItem("app-theme") || "Light", + ); + + const handleChange = (e) => { + const newTheme = e.target.value; + + setSelectedTheme(newTheme); + + localStorage.setItem("app-theme", newTheme); + + window.dispatchEvent(new Event("storage")); + }; + return (

Theme Palette

- + + +
); diff --git a/greenscoutjs/src/components/settings.css b/greenscoutjs/src/components/settings.css index 23bb6387..f190ee83 100644 --- a/greenscoutjs/src/components/settings.css +++ b/greenscoutjs/src/components/settings.css @@ -1,7 +1,7 @@ .settingsBody { font-size: var(--font-size-small); color: var(--font-color); - background-color: var(--background-color); + background: var(--background-color); height: var(--page-height); width: var(--page-width); } @@ -20,7 +20,7 @@ #settingsDebugBody { font-size: var(--font-size-small); color: var(--font-color-prompt-title); - background-color: var(--background-color); + background: var(--background-color); height: var(--page-height); width: var(--page-width); overflow: hidden; @@ -29,7 +29,7 @@ .settingsh1 { text-align: center; - background-color: transparent; + background: transparent; color: var(--font-color-prompt-title); margin: var(--settings-element-spacing); width: var(--settings-element-width); @@ -46,7 +46,7 @@ margin-left: calc((100% - var(--settings-element-width)) / 2); border-radius: var(--border-radius); border: var(--border-color-faded) 1px solid; - background-color: var(--sidenav-button-color); + background: var(--sidenav-button-color); display: flex; flex-direction: row; align-items: center; @@ -80,7 +80,7 @@ display: flex; flex-direction: row; align-items: center; - background-color: var(--background-color); + background: var(--background-color); border-radius: var(--border-radius); cursor: pointer; } @@ -101,7 +101,7 @@ .image.debug { flex-shrink: 0; - background-color: var(--font-color-prompt-title); + background: var(--font-color-prompt-title); width: calc(var(--settings-element-height) * 0.8); height: calc(var(--settings-element-height) * 0.8); mask-repeat: no-repeat; @@ -155,7 +155,7 @@ flex-direction: row; align-items: center; justify-content: center; - background-color: var(--background-color); + background: var(--background-color); border: var(--font-color-prompt-title) 1px solid; border-radius: var(--border-radius); } @@ -175,7 +175,7 @@ height: 80%; width: 20%; padding: 0; - background-color: var(--background-color); + background: var(--background-color); cursor: pointer; } @@ -204,7 +204,7 @@ border-bottom: gray solid 1px; font-size: var(--font-size-small); color: var(--font-color); - background-color: var(--background-color); + background: var(--background-color); cursor: pointer; } diff --git a/greenscoutjs/src/index.css b/greenscoutjs/src/index.css index 33e8bc8c..abb84deb 100644 --- a/greenscoutjs/src/index.css +++ b/greenscoutjs/src/index.css @@ -1,35 +1,4 @@ -html { - scrollbar-color: var(--font-color-prompt-title) var(--background-color); -} - :root { - /* Color Variables */ - --background-color: white; - --accent-color: #9bcbfb; - --accent-color2: #8fbdeb; - --accent-color3: #cee5ff; - - --blue-color: #9bcbfb; - --error-color: var(--disabled-color); - --disabled-color: #717172; - - --font-color: black; - --font-color-prompt-title: black; - --font-color-header: black; - - --drop-shadow-color: #626263; - --sidenav-hover-color: #444; - --faded-text-color: #5f6167; - - --kelly-green: #4cbb17; - --error-message-color: var(--disabled-color); - --check-background-color: #4cbb17; - --checkbox-default-color: #eee; - --checkbox-hover-color: #ccc; - --border-color-faded: #d9d9db; - --border-color-active: #417096; - --sidenav-button-color: #dfdfdf; - /* General Sizing Variables */ --font-size-large: 3vh; --font-size-small: 2.5vh; @@ -40,7 +9,7 @@ html { --page-width: 100vw; --content-height: calc(var(--page-height) - var(--navbar-height)); --content-width: var(--page-width); - --element-height: clamp(2.8rem, 6.2vh, 3.6rem); + --element-height: clamp(3.8rem, 20.2vh, 10rem); /* Navbar Sizing Variables */ --sidenav-width: min(70vw, 22rem); @@ -72,6 +41,8 @@ html { --login-button-height: clamp(2.5rem, 6vh, 4rem); /* Match Form Sizing Variables */ + --matchform-sectionbox-margin-vertical: clamp(1.5rem, 5.5vh, 2rem); + --matchform-sectionbox-padding-top: clamp(1.5rem, 7.5vh, 2rem); --matchform-side-panel-width: clamp(4rem, 8vh, 5.5rem); --matchform-grid-template: 1fr var(--matchform-side-panel-width); --matchform-child-margin-side: 7.5vw; @@ -162,7 +133,7 @@ html { --trigger-reset-height: clamp(2.2rem, 8vh, 4.5rem); /* Match Form Submit/Replay Sizing Variables */ - --submitreplay-div-height: clamp(3rem, 8vh, 5rem); + --submitreplay-div-height: var(--matchform-element-height); --submitreplay-div-margin-bottom: 1vh; --submitreplay-button-margin-top: 5.7vh; --submitreplay-button-margin-bottom: 4.4vh;