diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..a69e7f65b7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "nusmods", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/website/src/reducers/index.ts b/website/src/reducers/index.ts index 4f789a7527..eed8d5dfbe 100644 --- a/website/src/reducers/index.ts +++ b/website/src/reducers/index.ts @@ -48,3 +48,7 @@ export default function reducers(state: State = defaultState, action: Actions): }; return undoReducer(state, newState, action); } + + + + diff --git a/website/src/utils/api.ts b/website/src/utils/api.ts new file mode 100644 index 0000000000..60289deea2 --- /dev/null +++ b/website/src/utils/api.ts @@ -0,0 +1,13 @@ +import axios from 'axios'; + +const BASE_URL = 'https://api.nusmods.com/v2/2023-2024'; + +export const fetchModules = async () => { + try { + const response = await axios.get(`${BASE_URL}/moduleList.json`); + return response.data; + } catch (error) { + console.error('Error fetching modules:', error); + return []; + } +}; diff --git a/website/src/utils/randomCoursePicker.ts b/website/src/utils/randomCoursePicker.ts new file mode 100644 index 0000000000..bb3b256891 --- /dev/null +++ b/website/src/utils/randomCoursePicker.ts @@ -0,0 +1,13 @@ +import { fetchModules } from './api'; + +export const getRandomCourse = async () => { + const courses = await fetchModules(); + if (!courses || courses.length === 0) { + console.log('No courses available'); + return null; + } + const randomIndex = Math.floor(Math.random() * courses.length); + const randomCourse = courses[randomIndex]; + console.log('Random Course:', randomCourse); + return randomCourse; +}; diff --git a/website/src/views/settings/SettingsContainer.tsx b/website/src/views/settings/SettingsContainer.tsx index adb3be4d22..079ab52ed1 100644 --- a/website/src/views/settings/SettingsContainer.tsx +++ b/website/src/views/settings/SettingsContainer.tsx @@ -1,6 +1,7 @@ import { Fragment, useCallback, useEffect, useState } from 'react'; -import { connect } from 'react-redux'; +import { connect, useSelector } from 'react-redux'; import classnames from 'classnames'; +import { useHistory } from 'react-router-dom'; import { isEqual } from 'lodash'; import { ColorSchemePreference, ThemeId } from 'types/settings'; @@ -39,6 +40,8 @@ import previewTimetable from './previewTimetable'; import BetaToggle from './BetaToggle'; import RefreshPrompt from './RefreshPrompt'; import styles from './SettingsContainer.scss'; +import { getRandomCourse } from 'utils/randomCoursePicker'; // Import the random course picker function + type Props = { currentThemeId: string; @@ -68,6 +71,8 @@ const SettingsContainer: React.FC = ({ ...props }) => { const [allowTracking, setAllowTracking] = useState(true); + const history = useHistory(); + const onToggleTracking = useCallback((isTrackingAllowed: boolean) => { withTracker((tracker: Tracker) => { @@ -89,6 +94,15 @@ const SettingsContainer: React.FC = ({ useScrollToTop(); + const handleRandomCourseClick = async () => { + const randomCourse = await getRandomCourse(); // Fetch random course from API + if (randomCourse && randomCourse.moduleCode) { + history.push(`/courses/${randomCourse.moduleCode}`); + } else { + console.error("No courses available or invalid course"); + } + }; + return (
Settings @@ -289,6 +303,12 @@ const SettingsContainer: React.FC = ({ />
+ {/* Add the Random Course Picker Button */} +
+

Random Course Picker

+ ); }; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..fb57ccd13a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +