You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JDTodo is a web application designed for managing projects and tasks. It uses a React for the frontend and Python Flask for the backend to provide a user-friendly and efficient project/task management system.
Tech stack
Frontend
Backend
Database
Features
JDTodo is more than just a simple todo list application. With JDTodo, you can:
Create a project (e.g. "Final exam prep")
Update a project with a new name (e.g. "Final exam prep" -> "CIS 121 exam prep")
Delete a project
Create tasks for a given project (e.g. "Review ch.9 and do 20 exercises on pg. 257") with a deadline, status (Not started, In progress, Finished), and description
Update tasks (e.g. marking it as "Finished", changing the deadline, etc.)
Delete tasks
See which tasks are overdue
Installation and Setup
Fork this repository and clone it locally. Once completed, follow these steps:
Environment variables
Create a .env file at the root of the repository, then define the following 6 environment variables:
SQLALCHEMY_DATABASE_URI
URI used to connect to the database (e.g. sqlite:////tmp/test.db, mysql://username:password@server/db). You will first need to create your own.
JWT_SECRET_KEY
Secret key used for signing and verifying JWTs. A good rule of thumb is to use a secret key with a length of at least 256 bits (32 bytes) or longer and also a random, unique string generated cryptographically (e.g. secrets.token_hex(32)).
Once these have been set, then follow these steps to run the backend development server:
cd backend
pipenv shell
pipenv install
flask --app app run
Frontend
Follow these steps to run the frontend development server:
cd frontend
npm install
npm start
Pages
Below are some of the essential pages that underpin the core functionality and represent the backbone of the application. Presented here are detailed descriptions and accompanying screenshots of the Dashboard, Project Details, and Manage Account pages.
Dashboard
On the dasboard page, you can view and create/edit/delete projects, and also navigate to the project detail page by clicking on a project card:
Desktop
Mobile
Project Details
Once you click on one of your project cards, you will be on the project detail page, where you can view and create/edit/delete tasks. You can also click on each task to view its detail:
Desktop
Mobile
Manage Account
If you need to make changes to your profile, visit the account page, where you can modify your name, email, and password, and also delete your account:
Desktop
Mobile
Implementation Details/Technical Notes
API Documentation
NOTE: this represents the application's internal API and is not intended for use as an open API. It's important to note that documenting an internal API can pose certain security risks. However, in the context of showcasing my portfolio project, the purpose is solely to provide supplementary information.
Here are the Flask API endpoints for managing users, projects, and tasks (these can be found in modules in backend/routes):
User endpoints
POST/api/login
(authenticates the user given his/her log-in credentials)
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Email is not valid' }
401
{ 'error': 'Invalid credentials' }
500
{ 'error': 'Server error: please try again' }
POST/api/logout
(terminates the user's active session)
Parameters
None
Response
http code
response
200
{ 'message': 'Logout success' }
POST/api/signup
(creates the user given his/her registration information)
Parameters
name
type
data type
description
firstname
required
String
the first name of the user attempting to sign up
lastname
required
String
the last name of the user attempting to sign up
email
required
String
the email of the user attempting to sign up
password
required
String the password of the user attempting to sign up
passwordConfirm
required
String
the confirmed password of the user attempting to sign up
Response
http code
response
201
{ 'message': 'User successfully created' }
400
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Email is not valid' } OR { 'error': 'Password must match' } OR { 'error': 'Password must contain at least 8 characters, 1 uppercase letter, and 1 number' }
409
{ 'error': 'Email already exists' }
500
{ 'error': 'Server error: please try again' }
GET/api/user
(retrieves information about a logged-in user using his/her JSON Web Token(JWT))
PATCH/api/change_password/<user_id>
(modifies the user's password)
Parameters
name
type
data type
description
passwordCurrent
required
String
the current password of the user
passwordNew
required
String
the new password of the user
passwordConfirm
required
String
the confirmed new password of the user
Response
http code
response
200
{ 'message': 'Password successfully updated' }
400
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Email is not valid' } OR { 'error': 'Passwords must match' } OR { 'error': 'Password must contain at least 8 characters, 1 uppercase letter, and 1 number'} OR { 'error': 'New password must be different from your current one' }
POST/api/forgot_password
(sends to the user an email with a link to a page for resetting passwords)
Parameters
name
type
data type
description
email
required
String
the email of the user with forgotten password
Response
http code
response
200
{ 'message': 'Email successfully sent' }
400
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Email is not valid' }
404
{ 'error': 'User not found' }
500
{ 'error': 'Server error: please try again' }
PATCH/api/reset_password/<token>
(resets the password for the user identified by the token for resetting passwords)
Parameters
name
type
data type
description
password
required
String
the new password of the user
passwordConfirm
required
String
the confirmed new password of the user
Response
http code
response
200
{ 'message': 'Password successfully updated' }
400
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Passwords must match' } OR { 'error': 'Password must contain at least 8 characters, 1 uppercase letter, and 1 number'} OR { 'error': 'New password must be different from your original one' }
404
{ 'error': 'User not found' }
500
{ 'error': 'Server error: please try again' }
GET/api/verify_reset_password_token/<token>
(verifies if the token in the request URI is valid or not)
Parameters
None
Response
http code
response
200
{ 'message': 'Token found for {user.id}' }
403
{ 'error': 'Token expired' }
404
{ 'error': 'Token not found' }
500
{ 'error': 'Server error: please try again' }
GET/api/protected
(returns whether user has access to protected pages (i.e. whether user is logged-in or not))
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Project name must be less than 25 characters' }
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Project name must be less than 25 characters' }
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Task name must be less than 60 characters' } OR { 'error': 'Task deadline cannot be in the past' }
{ 'error': 'Missing request body' } OR { 'error': 'Please fill in all the required field(s)' } OR { 'error': 'Task name must be less than 60 characters' } OR { 'error': 'Task deadline cannot be in the past' } OR { 'error': 'Task description must be less than 300 characters' }
NOTE: much like the preceding discussion on API routes, the presentation of this database structure serves the purpose of showcasing a pivotal facet of my portfolio project. However, it is crucial to acknowledge that the exposure of such sensitive information introduces potential security vulnerabilities.
In backend/models, you will find 3 modules, user.py, project.py, task.py, each of which represents data for the 3 entities in this project: user, project, and task. Here is the Entry Relationship Diagram (ERD) that shows each field for each model, and how the 3 models work together:
Note on State Management
In this fullstack application, we need to manage both the client and server states. I have implemented Redux and React Redux for managing client state, and React-Query for managing server states. Each usage has been evaluated to ensure I am not duplicating state management between multiple tools whenever possible.
Get in Touch
If you have any questions or want to contribute, feel free to reach out to [email protected]!