Final Grade Calculator

Last updated: Fri Dec 30 2022

An app to calculate your final grade in a course.

Instead of studying for my finals like a reasonable student, I opted to stress over my final grade in each course and worry about whether I would be able to declare my major. And of course, to help cope with my stress, I decided to create a web app to calculate my grade in each course.

Development

For this project, I used React to create a single page application, and all user data was stored on the client in local storage, so a backend was not required. I initially considered storing all user data in a database, but I decided that the complexity that brought for both the user (by requiring them to sign in to access courses) and me (authentication and authorization, creating an API server, and a database) was not worth it for this app, since it is designed to just be a quick tool to check grades. However, I still wanted data to persist on reload, so I saved the data to local storage.

My initial prototype for the app had essentially no styling, and was mostly just a proof of concept. My biggest gripe with it (apart from how hideous it was) was the lack of persistant data. It was really annoying to enter data, and then accidentally reload the page or leave it for a few days and come back with all the data gone. Therefore, it was high on my list to fix. In addition, I wanted to find a seamless way to implement in-line editing for the title and assignments. I am pretty happy with the result, where the background color change signifies the option to edit, and two buttons for confirm and cancel unobtrusively in the right.

Context Menu

Surprisingly, the hardest part of this project for me was the right click context menu used to delete courses and assignments. The solution I settled on was to use a provider style implementation, where I wrapped the app with a context menu provider:

root.render( <React.StrictMode> <ContextMenuProvider> <App /> </ContextMenuProvider> </React.StrictMode> );

The Provider renders the context menu below the app on the DOM tree, and provides a function setContextMenu to open the menu through the useContext hook. Now, in any component, I could manipulate the context menu:

const ExampleComponent: FC = () => { const { setContextMenu } = useContext(ContextMenuContext); const menuItems: MenuItem[] = [ { text: "Context Menu Option", onClick() { alert("Context Menu Option Clicked"); }, }, ]; return ( <div onContextMenu={(e) => setContextMenu(e, menuItems)}> Try right clicking me! </div> ); };

This way, I abstracted away the complexity of the context menu, making it simple to implement in the app. In the future, I would consider making this an npm package that I can refer to in the future, since the logic is already separate from the rest of the app.

Conclusion

Although this was a simple project to help me get back into the groove of web development, I still learned a lot. Firstly, I appreciated the importance of an MVP to help understand what features are most important. Next, I learned about how to abstract away complex code to improve developer experience and code readability and reusability. Finally, I learned that I probably should have studied more instead of working on this project :/ Have a great 2023 everybody!

Deployed app: https://fgc.willma.me/

Source code: https://github.com/willmadev/final_grade_calculator