Commit 6abd3425 authored by David Haynes's avatar David Haynes 🙆

LOTS of code cleanup and comments

- you will not believe this diff
parent babfe66e
.vscode .vscode
\ No newline at end of file schedules.code-workspace
...@@ -4,6 +4,5 @@ ...@@ -4,6 +4,5 @@
"singleQuote": true, "singleQuote": true,
"useTabs": false, "useTabs": false,
"jsxBracketSameLine": true, "jsxBracketSameLine": true,
"stylelintIntegration": true,
"trailingComma": "es5" "trailingComma": "es5"
} }
export const ADD_SECTION = '[Schedule] ADD_SECTION'; export const ADD_SECTION: string = '[Schedule] ADD_SECTION';
export const REMOVE_SECTION = '[Schedule] REMOVE_SECTION'; export const REMOVE_SECTION: string = '[Schedule] REMOVE_SECTION';
import { Section } from '../../ts/section'; import { Section } from '../../util/section';
import { ADD_SECTION, REMOVE_SECTION } from './schedule.action-types'; import { ADD_SECTION, REMOVE_SECTION } from './schedule.action-types';
export interface ScheduleAction { export interface ScheduleAction {
type: string; type: string; // What action is to be performed
section: Section; section: Section; // The section that is being added/removed
} }
export const addSection = (section: Section): ScheduleAction => { /**
return { * Add a section to the Schedule
type: ADD_SECTION, * @param section The section that is to be added
section: section, */
}; export const addSection = (section: Section): ScheduleAction => ({
}; type: ADD_SECTION,
section: section,
});
export const removeSection = (section: Section): ScheduleAction => { /**
return { * Remove a section from the Schedule
type: REMOVE_SECTION, * @param section The section that is to be removed
section: section, */
}; export const removeSection = (section: Section): ScheduleAction => ({
}; type: REMOVE_SECTION,
section: section,
});
export const SET_SEARCH_SECTIONS = '[Search] SET_SECTIONS'; export const SET_SEARCH_SECTIONS: string = '[Search] SET_SECTIONS';
import { Section } from '../../ts/section'; import { Section } from '../../util/section';
import { SET_SEARCH_SECTIONS } from './search.action-types'; import { SET_SEARCH_SECTIONS } from './search.action-types';
export interface SearchAction { export interface SearchAction {
...@@ -10,20 +10,22 @@ export const searchSections = (crn: string) => async (dispatch: any) => { ...@@ -10,20 +10,22 @@ export const searchSections = (crn: string) => async (dispatch: any) => {
const response = await fetch(`http://localhost:3000/api/search?crn=${crn}`); const response = await fetch(`http://localhost:3000/api/search?crn=${crn}`);
const object = await response.json(); const object = await response.json();
const section: Section = { const section: Section[] = [
id: object.id, {
name: object.name, id: object.id,
title: object.title, name: object.name,
crn: object.crn, title: object.title,
instructor: object.instructor, crn: object.crn,
location: object.location, instructor: object.instructor,
days: object.days, location: object.location,
startTime: object.start_time, days: object.days,
endTime: object.end_time, startTime: object.start_time,
}; endTime: object.end_time,
},
];
dispatch({ dispatch({
type: SET_SEARCH_SECTIONS, type: SET_SEARCH_SECTIONS,
sections: [section], sections: section,
}); });
}; };
import * as React from 'react'; import * as React from 'react';
import { Section } from '../ts/section'; import { Section } from '../util/section';
interface Props { interface Props {
sections: Section[]; sections: Section[];
......
...@@ -3,8 +3,8 @@ import { connect } from 'react-redux'; ...@@ -3,8 +3,8 @@ import { connect } from 'react-redux';
import { removeSection } from '../actions/schedule/schedule.actions'; import { removeSection } from '../actions/schedule/schedule.actions';
import SectionList from '../components/SectionList'; import SectionList from '../components/SectionList';
import { State } from '../reducers'; import { State } from '../reducers';
import { Section } from '../ts/section'; import { Section } from '../util/section';
import { downloadCalendar, ENDPOINTS, postData } from '../ts/utilities'; import { downloadCalendar, ENDPOINTS, postData } from '../util/utilities';
import Search from './Search'; import Search from './Search';
interface AppProps { interface AppProps {
......
...@@ -5,7 +5,7 @@ import { searchSections } from '../actions/search/search.actions'; ...@@ -5,7 +5,7 @@ import { searchSections } from '../actions/search/search.actions';
import SearchBar from '../components/SearchBar'; import SearchBar from '../components/SearchBar';
import SectionList from '../components/SectionList'; import SectionList from '../components/SectionList';
import { State } from '../reducers'; import { State } from '../reducers';
import { Section } from '../ts/section'; import { Section } from '../util/section';
interface SearchProps { interface SearchProps {
searchedSections: Section[]; searchedSections: Section[];
......
...@@ -34,6 +34,7 @@ if (isProduction || !extension) { ...@@ -34,6 +34,7 @@ if (isProduction || !extension) {
); );
} }
// Attach all reducers + addOns to the Redux store
const store = createStore(allReducers, addOns); const store = createStore(allReducers, addOns);
ReactDOM.render( ReactDOM.render(
......
/**
* reducers/index.ts
*
* Wrap all reducers in a common object to be returned to the store.
*/
import { schedule, ScheduleState } from './schedule.reducer'; import { schedule, ScheduleState } from './schedule.reducer';
import { search, SearchState } from './search.reducer'; import { search, SearchState } from './search.reducer';
...@@ -16,6 +21,11 @@ const defaultState: State = { ...@@ -16,6 +21,11 @@ const defaultState: State = {
}, },
}; };
/**
* Combine all reducers into one object to attach to the store
* @param state The current state, initialized as nothing
* @param action The action to be applied to the reducers
*/
export const allReducers = (state: State = defaultState, action: any) => ({ export const allReducers = (state: State = defaultState, action: any) => ({
schedule: schedule(state.schedule, action), schedule: schedule(state.schedule, action),
search: search(state.search, action), search: search(state.search, action),
......
/**
* reducers/schedule.reducer.ts
*
* Perform operations on the current state of the "Schedule" list in the store
* and return a new definition of the state.
*/
import { ADD_SECTION, REMOVE_SECTION } from '../actions/schedule/schedule.action-types'; import { ADD_SECTION, REMOVE_SECTION } from '../actions/schedule/schedule.action-types';
import { ScheduleAction } from '../actions/schedule/schedule.actions'; import { ScheduleAction } from '../actions/schedule/schedule.actions';
import { Section } from '../ts/section'; import { Section } from '../util/section';
export type ScheduleState = Section[]; export type ScheduleState = Section[];
......
/**
* reducers/search.reducer.ts
*
* Perform operations on the current state of the "search.searchedSections"
* list in the store and return a new definition of the state.
*/
import { SET_SEARCH_SECTIONS } from '../actions/search/search.action-types'; import { SET_SEARCH_SECTIONS } from '../actions/search/search.action-types';
import { SearchAction } from './../actions/search/search.actions'; import { SearchAction } from '../actions/search/search.actions';
import { Section } from './../ts/section'; import { Section } from '../util/section';
export interface SearchState { export interface SearchState {
searchedSections: Section[]; searchedSections: Section[];
......
/**
* util/section.ts
*
* Common object interface for all "Section"s.
*/
export interface Section { export interface Section {
id: number; id: number;
name: string; name: string;
......
/**
* util/utilities.ts
*
* Reusable deterministic functions.
*/
import * as FileSaver from 'file-saver'; import * as FileSaver from 'file-saver';
export const ENDPOINTS = { export const ENDPOINTS = {
generateCalendar: 'http://localhost:3000/api/generate', generateCalendar: 'http://localhost:3000/api/generate',
}; };
export function postData(endpoint: string, data: any): Promise<Response> { export const postData = (endpoint: string, data: any): Promise<Response> =>
return fetch(endpoint, { fetch(endpoint, {
method: 'POST', method: 'POST',
body: JSON.stringify(data), body: JSON.stringify(data),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
}); });
}
export const downloadCalendar = (calendarText: string) => { export const downloadCalendar = (calendarText: string) =>
const blob = new Blob([calendarText], { type: 'text/plain;charset=utf-8' }); FileSaver.saveAs(new Blob([calendarText], { type: 'text/plain;charset=utf-8' }), 'GMU Fall 2018.ics');
FileSaver.saveAs(blob, 'GMU Fall 2018.ics');
};
...@@ -67,8 +67,6 @@ module.exports = { ...@@ -67,8 +67,6 @@ module.exports = {
test: /\.svg(\?.+)?$/, test: /\.svg(\?.+)?$/,
use: 'file-loader' use: 'file-loader'
}, },
{ {
test: /\.(js)$/, test: /\.(js)$/,
exclude: /(node_modules)/, exclude: /(node_modules)/,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment