diff --git a/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx b/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx index 8883102ba..1d6365807 100644 --- a/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx +++ b/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx @@ -53,8 +53,8 @@ const AntAlmanacEvent = ({ event }: { event: CalendarEvent }) => { {event.showLocationInfo ? event.locations.map((location) => `${location.building} ${location.room}`).join(', ') : event.locations.length > 1 - ? `${event.locations.length} Locations` - : `${event.locations[0].building} ${event.locations[0].room}`} + ? `${event.locations.length} Locations` + : `${event.locations[0].building} ${event.locations[0].room}`} {event.sectionCode} @@ -85,8 +85,8 @@ export default function ScheduleCalendar(props: ScheduleCalendarProps) { return showFinalsSchedule ? finalsEventsInCalendar : hoveredCourseEvents - ? [...eventsInCalendar, ...hoveredCourseEvents] - : eventsInCalendar; + ? [...eventsInCalendar, ...hoveredCourseEvents] + : eventsInCalendar; }; const handleClosePopover = () => { diff --git a/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx b/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx index 67c066283..6cb7d5cc4 100644 --- a/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx +++ b/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx @@ -10,12 +10,12 @@ import CustomEventDialog from './Toolbar/CustomEventDialog/CustomEventDialog'; import { deleteCourse, deleteCustomEvent } from '$actions/AppStoreActions'; import ColorPicker from '$components/ColorPicker'; import analyticsEnum, { logAnalytics } from '$lib/analytics'; -import { clickToCopy, isDarkMode } from '$lib/helpers'; +import { clickToCopy } from '$lib/helpers'; import AppStore from '$stores/AppStore'; import locationIds from '$lib/location_ids'; import { useTabStore } from '$stores/TabStore'; import { formatTimes } from '$stores/calendarizeHelpers'; -import { useTimeFormatStore } from '$stores/SettingsStore'; +import { useTimeFormatStore, useThemeStore } from '$stores/SettingsStore'; import buildingCatalogue from '$lib/buildingCatalogue'; const styles: Styles = { @@ -74,7 +74,6 @@ const styles: Styles = { clickableLocation: { cursor: 'pointer', - color: isDarkMode() ? '#1cbeff' : 'blue', background: 'none !important', border: 'none', padding: '0 !important', @@ -177,6 +176,7 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => { const { setActiveTab } = useTabStore(); const { isMilitaryTime } = useTimeFormatStore(); + const isDark = useThemeStore((store) => store.isDark); const focusMap = useCallback(() => { setActiveTab(2); @@ -262,6 +262,7 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => { className={classes.clickableLocation} to={`/map?location=${locationIds[location.building] ?? 0}`} onClick={focusMap} + color={isDark ? '#1cbeff' : 'blue'} > {location.building} {location.room} diff --git a/apps/antalmanac/src/components/Calendar/Toolbar/CustomEventDialog/CustomEventDialog.tsx b/apps/antalmanac/src/components/Calendar/Toolbar/CustomEventDialog/CustomEventDialog.tsx index 37a159a63..4fd5978dd 100644 --- a/apps/antalmanac/src/components/Calendar/Toolbar/CustomEventDialog/CustomEventDialog.tsx +++ b/apps/antalmanac/src/components/Calendar/Toolbar/CustomEventDialog/CustomEventDialog.tsx @@ -19,7 +19,7 @@ import DaySelector from './DaySelector'; import ScheduleSelector from './ScheduleSelector'; import { addCustomEvent, editCustomEvent } from '$actions/AppStoreActions'; import analyticsEnum, { logAnalytics } from '$lib/analytics'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; import AppStore from '$stores/AppStore'; import { BuildingSelect, ExtendedBuilding } from '$components/inputs/building-select'; @@ -139,6 +139,7 @@ function CustomEventDialogs(props: CustomEventDialogProps) { }; }, []); + const isDark = useThemeStore.getState().isDark; return ( <> {props.customEvent ? ( @@ -218,15 +219,15 @@ function CustomEventDialogs(props: CustomEventDialogProps) { - diff --git a/apps/antalmanac/src/components/Calendar/Toolbar/EditSchedule/DeleteScheduleDialog.tsx b/apps/antalmanac/src/components/Calendar/Toolbar/EditSchedule/DeleteScheduleDialog.tsx index 7f919943c..1c6e33047 100644 --- a/apps/antalmanac/src/components/Calendar/Toolbar/EditSchedule/DeleteScheduleDialog.tsx +++ b/apps/antalmanac/src/components/Calendar/Toolbar/EditSchedule/DeleteScheduleDialog.tsx @@ -14,7 +14,7 @@ import { useState } from 'react'; import { Clear } from '@material-ui/icons'; import { deleteSchedule } from '$actions/AppStoreActions'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; import AppStore from '$stores/AppStore'; interface DeleteScheduleDialogProps { @@ -23,6 +23,8 @@ interface DeleteScheduleDialogProps { } const DeleteScheduleDialog = (props: DeleteScheduleDialogProps) => { + const isDark = useThemeStore((store) => store.isDark); + const { scheduleIndex } = props; const [isOpen, setIsOpen] = useState(false); @@ -58,7 +60,7 @@ const DeleteScheduleDialog = (props: DeleteScheduleDialogProps) => { - - @@ -143,6 +144,8 @@ class LoadSaveButtonBase extends PureComponent { + const isDark = useThemeStore((store) => store.isDark); + const [loading, setLoading] = useState(false); const [skeletonMode, setSkeletonMode] = useState(AppStore.getSkeletonMode()); @@ -181,8 +184,9 @@ const LoadSaveScheduleFunctionality = () => { id="save-button" actionName={'Save'} action={saveSchedule} - disabled={loading || skeletonMode} + disabled={loading} loading={false} + colorType={isDark ? 'primary' : 'secondary'} /> { action={loadScheduleAndSetLoading} disabled={skeletonMode} loading={loading} + colorType={isDark ? 'primary' : 'secondary'} /> ); diff --git a/apps/antalmanac/src/components/Header/SettingsMenu.tsx b/apps/antalmanac/src/components/Header/SettingsMenu.tsx index d35dfae06..2090bbac9 100644 --- a/apps/antalmanac/src/components/Header/SettingsMenu.tsx +++ b/apps/antalmanac/src/components/Header/SettingsMenu.tsx @@ -18,14 +18,15 @@ const darkSelectedStyle: CSSProperties = { color: '#99CCF3', }; -function getSelectedStyle(buttonValue: string, themeSetting: string, appTheme: string) { - return themeSetting === buttonValue ? (appTheme == 'dark' ? darkSelectedStyle : lightSelectedStyle) : {}; +function getSelectedStyle(buttonValue: string, themeSetting: string, appTheme: string, isDark: boolean) { + return themeSetting === buttonValue ? (isDark ? darkSelectedStyle : lightSelectedStyle) : {}; } function ThemeMenu() { - const [themeSetting, appTheme, setTheme] = useThemeStore((store) => [ + const [themeSetting, appTheme, isDark, setTheme] = useThemeStore((store) => [ store.themeSetting, store.appTheme, + store.isDark, store.setAppTheme, ]); @@ -46,7 +47,7 @@ function ThemeMenu() { padding: '1rem 2rem', borderRadius: '12px 0px 0px 12px', width: '100%', - ...getSelectedStyle('light', themeSetting, appTheme), + ...getSelectedStyle('light', themeSetting, appTheme, isDark), }} value="light" onClick={handleThemeChange} @@ -58,7 +59,7 @@ function ThemeMenu() { style={{ padding: '1rem 2rem', width: '100%', - ...getSelectedStyle('system', themeSetting, appTheme), + ...getSelectedStyle('system', themeSetting, appTheme, isDark), }} value="system" onClick={handleThemeChange} @@ -71,7 +72,7 @@ function ThemeMenu() { padding: '1rem 2rem', borderRadius: '0px 12px 12px 0px', width: '100%', - ...getSelectedStyle('dark', themeSetting, appTheme), + ...getSelectedStyle('dark', themeSetting, appTheme, isDark), }} value="dark" onClick={handleThemeChange} @@ -85,6 +86,7 @@ function ThemeMenu() { function TimeMenu() { const [isMilitaryTime, setTimeFormat] = useTimeFormatStore((store) => [store.isMilitaryTime, store.setTimeFormat]); + const isDark = useThemeStore((store) => store.isDark); const theme = useThemeStore((store) => store.appTheme); const handleTimeFormatChange = (event: React.MouseEvent) => { @@ -110,7 +112,7 @@ function TimeMenu() { borderRadius: '12px 0px 0px 12px', width: '100%', fontSize: '12px', - ...getSelectedStyle('false', isMilitaryTime.toString(), theme), + ...getSelectedStyle('false', isMilitaryTime.toString(), theme, isDark), }} value="false" onClick={handleTimeFormatChange} @@ -124,7 +126,7 @@ function TimeMenu() { borderRadius: '0px 12px 12px 0px', width: '100%', fontSize: '12px', - ...getSelectedStyle('true', isMilitaryTime.toString(), theme), + ...getSelectedStyle('true', isMilitaryTime.toString(), theme, isDark), }} value="true" onClick={handleTimeFormatChange} diff --git a/apps/antalmanac/src/components/Map/Map.tsx b/apps/antalmanac/src/components/Map/Map.tsx index 43fb40963..f54462b0e 100644 --- a/apps/antalmanac/src/components/Map/Map.tsx +++ b/apps/antalmanac/src/components/Map/Map.tsx @@ -291,16 +291,13 @@ export default function CourseMap() { */ const startDestPairs = useMemo(() => { const allEvents = [...markersToDisplay, ...customEventMarkersToDisplay]; - return allEvents.reduce( - (acc, cur, index) => { - acc.push([cur]); - if (index > 0) { - acc[index - 1].push(cur); - } - return acc; - }, - [] as (typeof allEvents)[] - ); + return allEvents.reduce((acc, cur, index) => { + acc.push([cur]); + if (index > 0) { + acc[index - 1].push(cur); + } + return acc; + }, [] as (typeof allEvents)[]); }, [markersToDisplay, customEventMarkersToDisplay]); return ( diff --git a/apps/antalmanac/src/components/RightPane/AddedCourses/AddedCoursePane.tsx b/apps/antalmanac/src/components/RightPane/AddedCourses/AddedCoursePane.tsx index d443600af..e56f8f65c 100644 --- a/apps/antalmanac/src/components/RightPane/AddedCourses/AddedCoursePane.tsx +++ b/apps/antalmanac/src/components/RightPane/AddedCourses/AddedCoursePane.tsx @@ -303,14 +303,11 @@ function SkeletonSchedule() { }, []); const sectionsByTerm: [string, string[]][] = useMemo(() => { - const result = skeletonSchedule.courses.reduce( - (accumulated, course) => { - accumulated[course.term] ??= []; - accumulated[course.term].push(course.sectionCode); - return accumulated; - }, - {} as Record - ); + const result = skeletonSchedule.courses.reduce((accumulated, course) => { + accumulated[course.term] ??= []; + accumulated[course.term].push(course.sectionCode); + return accumulated; + }, {} as Record); return Object.entries(result); }, [skeletonSchedule.courses]); diff --git a/apps/antalmanac/src/components/RightPane/CoursePane/CourseRenderPane.tsx b/apps/antalmanac/src/components/RightPane/CoursePane/CourseRenderPane.tsx index 1150561a7..2fb68eec9 100644 --- a/apps/antalmanac/src/components/RightPane/CoursePane/CourseRenderPane.tsx +++ b/apps/antalmanac/src/components/RightPane/CoursePane/CourseRenderPane.tsx @@ -14,20 +14,17 @@ import loadingGif from './SearchForm/Gifs/loading.gif'; import darkNoNothing from './static/dark-no_results.png'; import noNothing from './static/no_results.png'; import AppStore from '$stores/AppStore'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; import Grades from '$lib/grades'; import analyticsEnum from '$lib/analytics'; import { openSnackbar } from '$actions/AppStoreActions'; import WebSOC from '$lib/websoc'; function getColors() { - const courseColors = AppStore.schedule.getCurrentCourses().reduce( - (accumulator, { section }) => { - accumulator[section.sectionCode] = section.color; - return accumulator; - }, - {} as { [key: string]: string } - ); + const courseColors = AppStore.schedule.getCurrentCourses().reduce((accumulator, { section }) => { + accumulator[section.sectionCode] = section.color; + return accumulator; + }, {} as { [key: string]: string }); return courseColors; } @@ -55,6 +52,8 @@ const flattenSOCObject = (SOCObject: WebsocAPIResponse): (WebsocSchool | WebsocD const RecruitmentBanner = () => { const [bannerVisibility, setBannerVisibility] = useState(true); + const isDark = useThemeStore((store) => store.isDark); + // Display recruitment banner if more than 11 weeks (in ms) has passed since last dismissal const recruitmentDismissalTime = window.localStorage.getItem('recruitmentDismissalTime'); const dismissedRecently = @@ -70,8 +69,8 @@ const RecruitmentBanner = () => { icon={false} severity="info" style={{ - color: isDarkMode() ? '#ece6e6' : '#2e2e2e', - backgroundColor: isDarkMode() ? '#2e2e2e' : '#ece6e6', + color: isDark ? '#ece6e6' : '#2e2e2e', + backgroundColor: isDark ? '#2e2e2e' : '#ece6e6', }} action={ { + const isDark = useThemeStore((store) => store.isDark); return ( - Loading courses + Loading courses ); }; const ErrorMessage = () => { + const isDark = useThemeStore((store) => store.isDark); return ( No Results Found diff --git a/apps/antalmanac/src/components/RightPane/RightPaneRoot.tsx b/apps/antalmanac/src/components/RightPane/RightPaneRoot.tsx index 0c8910ba5..0bde00518 100644 --- a/apps/antalmanac/src/components/RightPane/RightPaneRoot.tsx +++ b/apps/antalmanac/src/components/RightPane/RightPaneRoot.tsx @@ -8,7 +8,7 @@ import CoursePane from './CoursePane/CoursePaneRoot'; import darkModeLoadingGif from './CoursePane/SearchForm/Gifs/dark-loading.gif'; import loadingGif from './CoursePane/SearchForm/Gifs/loading.gif'; import { useTabStore } from '$stores/TabStore'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; const UCIMap = React.lazy(() => import('../Map')); @@ -56,6 +56,8 @@ const tabs: Array = [ export default function Desktop({ style }: DesktopTabsProps) { const { activeTab, setActiveTab } = useTabStore(); + const isDark = useThemeStore((store) => store.isDark); + return ( @@ -91,7 +93,7 @@ export default function Desktop({ style }: DesktopTabsProps) { - Loading map + Loading map } > diff --git a/apps/antalmanac/src/components/RightPane/SectionTable/EnrollmentHistoryPopup.tsx b/apps/antalmanac/src/components/RightPane/SectionTable/EnrollmentHistoryPopup.tsx index 4a475aac7..3394532ad 100644 --- a/apps/antalmanac/src/components/RightPane/SectionTable/EnrollmentHistoryPopup.tsx +++ b/apps/antalmanac/src/components/RightPane/SectionTable/EnrollmentHistoryPopup.tsx @@ -3,7 +3,7 @@ import { LineChart, Line, CartesianGrid, ResponsiveContainer, XAxis, YAxis, Tool import { Box, Link, Typography, Skeleton, useMediaQuery } from '@mui/material'; import { MOBILE_BREAKPOINT } from '../../../globals'; import { DepartmentEnrollmentHistory, EnrollmentHistory } from '$lib/enrollmentHistory'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; export interface EnrollmentHistoryPopupProps { department: string; @@ -28,9 +28,9 @@ export function EnrollmentHistoryPopup({ department, courseNumber }: EnrollmentH enrollmentHistory.quarter } | ${enrollmentHistory.instructors.join(', ')}`; }, [courseNumber, department, enrollmentHistory]); - + const isDarkMode = useThemeStore((state) => state.isDark); const encodedDept = useMemo(() => encodeURIComponent(department), [department]); - const axisColor = isDarkMode() ? '#fff' : '#111'; + const axisColor = isDarkMode ? '#fff' : '#111'; const tooltipDateColor = '#111'; useEffect(() => { diff --git a/apps/antalmanac/src/components/RightPane/SectionTable/GradesPopup.tsx b/apps/antalmanac/src/components/RightPane/SectionTable/GradesPopup.tsx index 01045f8d0..e2467e015 100644 --- a/apps/antalmanac/src/components/RightPane/SectionTable/GradesPopup.tsx +++ b/apps/antalmanac/src/components/RightPane/SectionTable/GradesPopup.tsx @@ -1,7 +1,7 @@ import { useState, useEffect, useMemo } from 'react'; import { Bar, BarChart, CartesianGrid, ResponsiveContainer, XAxis, YAxis } from 'recharts'; import { Box, Link, Typography, Skeleton } from '@mui/material'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; import GradesHelper, { type Grades } from '$lib/grades'; export interface GradeData { @@ -51,6 +51,8 @@ export interface GradesPopupProps { } function GradesPopup(props: GradesPopupProps) { + const appTheme = useThemeStore((store) => store.appTheme); + const { deptCode, courseNumber, instructor = '', isMobileScreen } = props; const [loading, setLoading] = useState(true); @@ -106,7 +108,7 @@ function GradesPopup(props: GradesPopupProps) { } const encodedDept = encodeURIComponent(deptCode); - const axisColor = isDarkMode() ? '#fff' : '#111'; + const axisColor = isDark ? '#fff' : '#111'; return ( diff --git a/apps/antalmanac/src/components/RightPane/SectionTable/PrereqTree.tsx b/apps/antalmanac/src/components/RightPane/SectionTable/PrereqTree.tsx index 1bc339d09..90e3ee0d4 100644 --- a/apps/antalmanac/src/components/RightPane/SectionTable/PrereqTree.tsx +++ b/apps/antalmanac/src/components/RightPane/SectionTable/PrereqTree.tsx @@ -4,7 +4,7 @@ import { FC, useState } from 'react'; import { Button, Modal, Popover } from '@material-ui/core'; import { CourseInfo } from './CourseInfoBar'; -import { isDarkMode } from '$lib/helpers'; +import { useThemeStore } from '$stores/SettingsStore'; import './PrereqTree.css'; @@ -23,13 +23,14 @@ interface NodeProps { } const Node: FC = (props) => { + const appTheme = useThemeStore((store) => store.appTheme); return (
{props.label} diff --git a/apps/antalmanac/src/components/RightPane/SectionTable/SectionTableBody.tsx b/apps/antalmanac/src/components/RightPane/SectionTable/SectionTableBody.tsx index 79cc5f140..d1d1b1dce 100644 --- a/apps/antalmanac/src/components/RightPane/SectionTable/SectionTableBody.tsx +++ b/apps/antalmanac/src/components/RightPane/SectionTable/SectionTableBody.tsx @@ -25,7 +25,7 @@ import { ColorAndDelete, ScheduleAddCell } from './SectionTableButtons'; import restrictionsMapping from './static/restrictionsMapping.json'; import GradesPopup from './GradesPopup'; import analyticsEnum, { logAnalytics } from '$lib/analytics'; -import { clickToCopy, isDarkMode } from '$lib/helpers'; +import { clickToCopy } from '$lib/helpers'; import { CourseDetails } from '$lib/course_data.types'; import Grades from '$lib/grades'; import AppStore from '$stores/AppStore'; @@ -33,7 +33,7 @@ import { useTabStore } from '$stores/TabStore'; import locationIds from '$lib/location_ids'; import { normalizeTime, parseDaysString, formatTimes } from '$stores/calendarizeHelpers'; import useColumnStore, { type SectionTableColumn } from '$stores/ColumnStore'; -import { usePreviewStore, useTimeFormatStore } from '$stores/SettingsStore'; +import { usePreviewStore, useTimeFormatStore, useThemeStore } from '$stores/SettingsStore'; import { useHoveredStore } from '$stores/HoveredStore'; const styles: Styles = (theme) => ({ @@ -41,7 +41,6 @@ const styles: Styles = (theme) => ({ display: 'inline-flex', cursor: 'pointer', '&:hover': { - color: isDarkMode() ? 'gold' : 'blueviolet', cursor: 'pointer', }, alignSelf: 'center', @@ -51,23 +50,12 @@ const styles: Styles = (theme) => ({ backgroundColor: theme.palette.action.hover, }, }, - tr: { - '&.addedCourse': { - background: isDarkMode() ? '#b0b04f' : '#fcfc97', - }, - '&.scheduleConflict': { - background: isDarkMode() ? '#121212' : '#a0a0a0', - opacity: isDarkMode() ? 0.6 : 1, - }, - }, cell: {}, link: { textDecoration: 'underline', - color: isDarkMode() ? 'dodgerblue' : 'blue', cursor: 'pointer', }, mapLink: { - color: isDarkMode() ? 'dodgerblue' : 'blue', cursor: 'pointer', background: 'none !important', border: 'none', @@ -101,7 +89,6 @@ const styles: Styles = (theme) => ({ Tap: { color: '#8d2df0' }, Tut: { color: '#ffc705' }, popoverText: { - color: isDarkMode() ? 'dodgerblue' : 'blue', cursor: 'pointer', }, codeCell: { @@ -122,8 +109,20 @@ interface CourseCodeCellProps { } const CourseCodeCell = withStyles(styles)((props: CourseCodeCellProps) => { + const isDark = useThemeStore((store) => store.isDark); + const { classes, sectionCode } = props; + const [isHovered, setIsHovered] = useState(false); + + const handleMouseEnter = () => { + setIsHovered(true); + }; + + const handleMouseLeave = () => { + setIsHovered(false); + }; + return ( @@ -137,6 +136,11 @@ const CourseCodeCell = withStyles(styles)((props: CourseCodeCellProps) => { }} className={classes.sectionCode} label={sectionCode} + onMouseEnter={handleMouseEnter} + onMouseLeave={handleMouseLeave} + style={{ + color: isHovered ? (isDark ? 'gold' : 'blueviolet') : '', + }} size="small" /> @@ -233,6 +237,8 @@ interface GPACellProps { } function GPACell(props: GPACellProps) { + const isDark = useThemeStore((store) => store.isDark); + const { deptCode, courseNumber, instructors } = props; const [gpa, setGpa] = useState(''); @@ -264,7 +270,7 @@ function GPACell(props: GPACellProps) {