Code Monkey home page Code Monkey logo

ffcsthingy2.0's Introduction

FFCSThingy2.0

FFCSThingy2.0 is a course scheduling helper built for FFCS in VIT, Vellore.

The framework is extensible and modular, allowing use with other timetable structures as well.

Built With

Setting Up:

  • Install Node, Mongo
  • Run mongod in a terminal somewhere (Not required if it's running as a service)
  • Google OAuth
  • Backend
    • run npm i
    • create a .env file
    • Add the ID and Secret you got from OAuth in the .env file
    • NODE_GOOGLE_CLIENT_ID=<Your Client ID>
      NODE_GOOGLE_CLIENT_SECRET=<Your Client Secret>
      
    • run node server.js
  • Client
    • run npm i
    • run npm start
    • Login using a Google Account (top-right corner)
  • Database
    • Add an admin scope to your user to be able to populate the details in the DB
    • Open a mongo shell with mongo
    • Choose the appropriate DB with use FFCS
    • Run db.users.update({}, { $set: { scopes: ['user', 'admin'] } })
      • This will add the admin scope to all existing users, so be careful
  • Navigate to:
    • http://localhost:3001/course/addCoursesToDB
    • http://localhost:3001/curriculum/updateCurriculums
    • These will populate the database with pre-existing data
  • You should be good to go!

Features

Frontend

  • Built with Redux and React
  • Uses custom components built on top of React Bootstrap
  • Uses TypeScript
  • Extensible
    • Timetable defines the layout of the timetable and values of cells
    • Clashmap defines the data structure used to check for clashes
      • This can be changed to define which slots clash with each other
      • It forms the base of a lot of interactions of the app
    • Courses defines the type of courses and slots available and utility functions to check types and convert them to standard types
      • The validSlots constant is used to search for courses by slot
    • Theming
      • Themes defines the themes in the app
      • Theme CSS defines the actual theme components
      • Uses SCSS and CSS Modules for a clean structure
      • Theming is based on CSS variables using a mixin

Backend

  • Built with Node and MongoDB
  • Uses Mongoose for stricter MongoDB usage
  • Uses Express for routing

ffcsthingy2.0's People

Contributors

2bit-hack avatar charukuls avatar coursesra avatar cyberquill avatar ffardeen avatar gsgupta11 avatar namsnath avatar roerohan avatar shiv10 avatar sudo-nan0-raysk avatar tanmayc07 avatar theprogrammerdavid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ffcsthingy2.0's Issues

Add gzip for heavy backend endpoints

  • Endpoints like allCourseLists and fullHeatmap return data along with a success message.
  • The data is memory cached, but the whole response isn't.
  • GZip can be enabled on the full response, which would lead to much lighter responses.
  • This would be more efficient than enabling gzip on nginx for the response, since it would probably have to process the whole thing on every response.

Will require restructuring of the routes

  • Move the logic to a function in the courseUtility file
  • Add zlib for gzipping
  • Keep a gzipped version of the success response
  • Send the gzipped response if available
  • Add a regardless parameter like in the existing queries to force an update
  • Run a forced update everytime the courses are updated

Update scrapers

  • Current scrapers are outdated and tend to break with changes
    • Scrapers have undocumented code
  • Rewrite scrapers, ideally with functions for each different year/format

Login (keep local data) seems to sync and return server data

Reproduction

  • Add courses without logging in
  • Login in keeping local data
  • On sync, local data is overwritten by server data

Expected

  • On sync, local data overwrites server data

Problem

req.user.timestamp seems to be updated on login

Suggested Solution

Add a property timetableTimestamp and use that to check for update time
OR
Figure out where the timestamp is being changed and fix it

Convert saved curriculum data to JSON

  • Data in backend/samples/curriculum could be converted to JSON.
  • Can keep a few from each year to test scrapers
    • Need to strip them and reduce size for HTMLs (Use Palash's script)

Add Screenshot/Save for timetable

There is no way to share/save timetables for now.

A useful feature would be to add a button that allows saving a screenshot of the timetable as a PNG/PDF or the course list as a CSV/TXT file.

Something like this could be used, provided it keeps the CSS on print.

Exporting to a downloadable CSV/TXT file should be trivial.

Fix iPad Layouts

The layout of the app does not look good on iPads in portrait mode (768x1024 px).
This could be fixed by making the CourseSelection component wider and the SlotTable narrower, and changing the column count for it.
The Navbar also needs editing. A possible solution would be to allow it to collapse into a hamburger menu like on mobile screens.
image

The Timetable component also overflows. It could be made to split into two parts like on Mobile Screens (eg: 360x740 px).
This should be a quick fix by changing the media query here:

<MediaQuery minDeviceWidth={768}>

The timetable component on mobile screens:
image

Add user scopes

Currently, protected routes use weird route names to attempt to obfuscate them.

Adding scopes to the user model should alleviate the need for this.

Add toasts for errors

  • reducer actions (add/remove/rename/copy timetable, etc)
  • timetable generator
  • syncing

USE CI/CD

Currently deployment is through a standard pull and restart method.

Can add docker and setup a CI/CD pipeline for seamless deployments.

Change auth process

Modify passport to accept sessions without auth
Allow linking a google account to session if data sync is preferred

Use classnames package for scss classes

classnames is a simpler way to interact with class names in React.

Allows for using an array or dict to defined classes, can make code a lot cleaner.

/* components/submit-button.js */
import { Component } from 'react';
import classNames from 'classnames/bind';
import styles from './submit-button.css';

let cx = classNames.bind(styles);

export default class SubmitButton extends Component {
  render () {
    let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';
    let className = cx({
      base: true,
      inProgress: this.props.store.submissionInProgress,
      error: this.props.store.errorOccurred,
      disabled: this.props.form.valid,
    });
    return <button className={className}>{text}</button>;
  }
};

Slot Clash doesn't update on course delete

When a course is deleted, clashing slots list on SlotCard doesn't update to reflect the new list until forced to re-render by changing selected course to something else and back.

Slot: L1+L2
Clash shows: A1, F1

A1 deleted
Clash show: A1, F1

Should Show: F1

Replace snake_casing with camelCasing

A lot of places in the codebase use snake_casing, which is not consistent with the rest of the code. These could be replaced with camelCased names to adhere to JS naming conventions.

Examples:
User Model
Course Model

Changes to these will require changes in places in the frontend as well as the backend.

This is a significant refactor spanning multiple files in both the frontend and the backend.

Refactor TS interface names

Prefix all interfaces with I to add consistency and reduce ambiguous naming.
Ex: ISomeComponent or IUser, IDashboardComponent, IDashboard

Deploying this Project

If I am allowed I can Help to deploy this Website on Heroku and the DB on MongoDB servers and make the project live .
I have made similar projects and can help you with it

Add copy button to timetable switcher

Allow copying the timetable with a new name

Had issues making it work previously. For some reason the array didn't get updated with a new timetableName for the copied values. Could be some logic bug. (pretty sure that map call is fucked up).

This code is old and will need to be refactored to work with hooks similar to how the other timetable actions are handled

    doTimetableCopy = (newName) => {
		if (this.state.timetableNames.includes(newName)) return;

		this.setState(prevState => ({
			timetableNames: [...prevState.timetableNames, newName],
			timetable: [...prevState.timetable, ...prevState.timetable.map(v => {
				if(v.timetableName === prevState.activeTimetable)
					v.timetableName = newName;
				return v;
			})]
		}), () => {
				this.changeActiveTimetable(newName);
		});
	} 

Email Setup

It would be really handy if the site Email setup and would notify users via Email.
I can work on it with Sendgrid and SMTP if given the right resources

Remove Date.now() calls from reducers

Lots of reducers call Date.now(). This is an anti-pattern and makes the reducer an impure function.

Solution

  • Pass a timestamp with the dispatch
  • Convert the timestamp to appropriate format inside the reducer

In terms of the implementation I had in mind, we could try passing a timestamp to the reducer (using Date.now()), which can then be processed to convert it to the ISOString that the reducer uses currently.
Essentially, the Date.now() component moves out of the reducers and to the place where the action is being dispatched. The reducers would not need any changes in logic.

Keep in mind, we will also have to modify the dispatches that happen from the components.

Add static data source to enable usage when hosted without a backend

Currently, a backend is required to get courses, curriculums. This dependency can be removed if a bare-bones app is required.

  • Setup a data source (like raw.github)
  • Add an env variable in frontend build, based on which
    • Disable login button
    • Fetch data from data source
    • Disable all sync actions

Content that would need to be hosted can be found in the response of:

  • /course/fullHeatmap
  • /course/allCourseLists
  • /curriculum/curriculumFromPrefix/<prefix>
  • /curriculum/prefixes

Add tests for reducers and components

Most components and reducers do not have tests as of now.
Tests are implemented for timetable and course reducers, but lack certain cases/tests.

Specific tests that need to be implemented:

  • Timetable reducer/slice
    • updateClashmap() utility function
    • syncTimetable Thunk call with redux-mock-store. rejected/pending/fulfilled reducer tests implemented.
  • Empty String Checks/Tests
    • Filter Controls -> setSelectedCategory
    • curriculumReducer/setSelectedCurriculum
    • themeReducer/changeTheme
    • timetableReducer/changeTimetable
  • Dashboard Component
    • Dispatches
    • Thunk calls with redux-mock-store
    • Snapshot Testing
    • Alerts

Add a recommendation thingy

Something like, since you chose this course, you might want to take this too. Or something like, Other people have taken B when they took A.

This is a major feature that would require leveraging the data in the DB and adding routes to provide the recommendations to the client.

There is no defined structure to this feature. Ideation and Suggestions on how to do this with Node and Mongo is welcomed.

Disable Zoom For Phone

On phones, it is possible to zoom in and out. This shouldn't be possible.

Fixing this should be possible with minor changes to the Index HTML

Fix multiple Modal renders on initial Load

If showModal is true
Initial Render renders the modal with the animation multiple times

Possibly due to multiple re-renders of the navbar
Maybe move the modal to Dashboard?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.