Skip to content

Commit

Permalink
Merge branch 'icssc:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
pinapelz authored May 24, 2024
2 parents ffde256 + 6118556 commit 40cca5e
Show file tree
Hide file tree
Showing 60 changed files with 2,004 additions and 1,466 deletions.
41 changes: 37 additions & 4 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,49 @@ const config = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
project: ['tsconfig.json'],
sourceType: 'module',
},
plugins: ['import', '@typescript-eslint/eslint-plugin'],
extends: [
'eslint:recommended',
'plugin:import/recommended',
'plugin:import/typescript',
'plugin:@typescript-eslint/recommended',
'prettier',
],
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
},
'newlines-between': 'always',
},
],
},
settings: {
'import/resolver': {
typescript: {
project: ['tsconfig.json', 'apps/*/tsconfig.json'],
},
},
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
env: {
browser: true,
es6: true,
node: true,
},
ignorePatterns: ['*.config.*', '*.cjs'],
ignorePatterns: ['*.config.*', '*rc.cjs'],
};

module.exports = config;
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/iron
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ Since then, the project has continued to evolve and grow with successive generat
| 2018 - 2019 | @the-rango (founder) |
| 2019 - 2021 | @devsdevsdevs |
| 2021 - 2022 | @ChaseC99 |
| 2022 - Present | @EricPedley |
| 2022 - 2024 | @EricPedley |
| 2023 - Present | @ap0nia |
| 2024 - Present | @MinhxNguyen7 |


# Contributing
Expand Down
66 changes: 25 additions & 41 deletions apps/antalmanac/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,43 +1,27 @@
/** @type {import('eslint').Linter.Config} */
// @ts-check

/**
* @type {import('eslint').Linter.Config}
*/
const config = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
},
plugins: [
'react',
'react-hooks',
'import',
'jsx-a11y',
'@typescript-eslint/eslint-plugin',
],
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:react/jsx-runtime',
'plugin:jsx-a11y/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
rules: {
'import/order': 'error',
},
env: {
browser: true,
es6: true,
},
globals: {
React: true,
},
settings: {
react: {
version: 'detect',
}
},
ignorePatterns: ['vite.config.ts'],
}
parserOptions: {
project: ['tsconfig.json'],
},
plugins: ['react', 'react-hooks', 'jsx-a11y'],
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:react/jsx-runtime',
'plugin:jsx-a11y/recommended',
],
globals: {
React: true,
},
settings: {
react: {
version: 'detect',
},
},
};

module.exports = config
module.exports = config;
22 changes: 4 additions & 18 deletions apps/antalmanac/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "antalmanac",
"version": "1.0.0",
"private": true,
"type": "module",
"homepage": "https://antalmanac.com",
"description": "A course exploration and scheduling tool for UCI Anteaters",
"bugs": {
Expand Down Expand Up @@ -31,7 +32,7 @@
"@mui/icons-material": "^5.11.0",
"@mui/lab": "^5.0.0-alpha.118",
"@mui/material": "^5.11.7",
"@packages/antalmanac-types": "*",
"@packages/antalmanac-types": "workspace:^",
"@react-leaflet/core": "^2.1.0",
"@reactour/tour": "^3.6.1",
"@tanstack/react-query": "^4.24.4",
Expand Down Expand Up @@ -65,13 +66,15 @@
"react-split": "^2.0.14",
"recharts": "^2.4.2",
"superjson": "^1.12.3",
"ua-parser-js": "^1.0.37",
"websoc-fuzzy-search": "^1.0.1",
"zustand": "^4.3.2"
},
"devDependencies": {
"@babel/core": "^7.20.12",
"@packages/antalmanac-types": "workspace:^",
"@testing-library/react": "^14.0.0",
"@types/eslint": "^8.56.5",
"@types/file-saver": "^2.0.5",
"@types/leaflet": "^1.9.0",
"@types/leaflet-routing-machine": "^3.2.4",
Expand All @@ -85,8 +88,6 @@
"@types/react-lazyload": "^3.2.0",
"@types/reactour": "^1.18.5",
"@types/ua-parser-js": "^0.7.39",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1",
"@vitejs/plugin-react": "^4.0.4",
"aws-sdk": "^2.1550.0",
"eslint": "^8.36.0",
Expand All @@ -95,25 +96,10 @@
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"gh-pages": "^5.0.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.1",
"peterportal-api-next-types": "1.0.0-rc.2.68.0",
"prettier": "^2.8.4",
"typescript": "^4.9.5",
"vite": "^4.4.9",
"vite-plugin-svgr": "^2.4.0"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
165 changes: 165 additions & 0 deletions apps/antalmanac/src/actions/ActionTypesStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { EventEmitter } from 'events';

import { RepeatingCustomEvent, ScheduleCourse } from '@packages/antalmanac-types';

import { autoSaveSchedule } from '$actions/AppStoreActions';
import AppStore from '$stores/AppStore';

const MAX_UNSAVED_ACTIONS = 1000;

export interface UndoAction {
type: 'undoAction';
}

export interface AddCourseAction {
type: 'addCourse';
course: ScheduleCourse;
scheduleIndex: number;
}

export interface DeleteCourseAction {
type: 'deleteCourse';
sectionCode: string;
term: string;
}

export interface AddCustomEventAction {
type: 'addCustomEvent';
customEvent: RepeatingCustomEvent;
scheduleIndices: number[];
}

export interface DeleteCustomEventAction {
type: 'deleteCustomEvent';
customEventId: number;
}

export interface EditCustomEventAction {
type: 'editCustomEvent';
editedCustomEvent: RepeatingCustomEvent;
newScheduleIndices: number[];
}

export interface ChangeCustomEventColorAction {
type: 'changeCustomEventColor';
customEventId: number;
newColor: string;
}

export interface ClearScheduleAction {
type: 'clearSchedule';
}

export interface CopyScheduleAction {
type: 'copySchedule';
to: number;
}

export interface ChangeCourseColorAction {
type: 'changeCourseColor';
sectionCode: string;
term: string;
newColor: string;
}

export type ActionType =
| AddCourseAction
| DeleteCourseAction
| AddCustomEventAction
| DeleteCustomEventAction
| EditCustomEventAction
| ChangeCustomEventColorAction
| ClearScheduleAction
| CopyScheduleAction
| ChangeCourseColorAction
| UndoAction;

function parseUnsavedActionsString(unsavedActionsString: string): ActionType[] {
try {
return JSON.parse(unsavedActionsString);
} catch {
return [];
}
}

class ActionTypesStore extends EventEmitter {
constructor() {
super();
}

async autoSaveSchedule(action: ActionType) {
const autoSave = typeof Storage !== 'undefined' && window.localStorage.getItem('autoSave') == 'true';
if (autoSave) {
const savedUserID = window.localStorage.getItem('userID');

if (savedUserID) {
this.emit('autoSaveStart');
await autoSaveSchedule(savedUserID);
AppStore.unsavedChanges = false;
this.emit('autoSaveEnd');
}
} else {
const unsavedActionsString = window.localStorage.getItem('unsavedActions');
if (unsavedActionsString == null) {
const unsavedActions = [action];
localStorage.setItem('unsavedActions', JSON.stringify(unsavedActions));
} else {
let unsavedActions = parseUnsavedActionsString(unsavedActionsString);
if (unsavedActions.length > MAX_UNSAVED_ACTIONS) {
unsavedActions = unsavedActions.slice(100);
}
unsavedActions.push(action);
localStorage.setItem('unsavedActions', JSON.stringify(unsavedActions));
}
}
}

async loadScheduleFromLocalSave() {
const unsavedActionsString = window.localStorage.getItem('unsavedActions');

if (unsavedActionsString == null) return;
if (!confirm('You have unsaved changes. Would you like to load them?')) {
window.localStorage.removeItem('unsavedActions');
return;
}

const actions = parseUnsavedActionsString(unsavedActionsString);

actions.forEach((action) => {
switch (action.type) {
case 'addCourse':
AppStore.schedule.addCourse(action.course, action.scheduleIndex);
break;
case 'deleteCourse':
AppStore.schedule.deleteCourse(action.sectionCode, action.term);
break;
case 'addCustomEvent':
AppStore.schedule.addCustomEvent(action.customEvent, action.scheduleIndices);
break;
case 'deleteCustomEvent':
AppStore.schedule.deleteCustomEvent(action.customEventId);
break;
case 'editCustomEvent':
AppStore.schedule.editCustomEvent(action.editedCustomEvent, action.newScheduleIndices);
break;
case 'changeCustomEventColor':
AppStore.schedule.changeCustomEventColor(action.customEventId, action.newColor);
break;
case 'changeCourseColor':
AppStore.schedule.changeCourseColor(action.sectionCode, action.term, action.newColor);
break;
case 'clearSchedule':
AppStore.schedule.clearCurrentSchedule();
break;
case 'copySchedule':
AppStore.schedule.copySchedule(action.to);
break;
default:
break;
}
});
}
}

const actionTypesStore = new ActionTypesStore();
export default actionTypesStore;
Loading

0 comments on commit 40cca5e

Please sign in to comment.