EveryNote, an Evernote clone, is a website for users to jot down notes and tasks and organize them according to tags and notebooks. Feel free to visit the live site here
- MVP Feature List
- Database Schema
- User Stories
- React Components
- Routes
- React Store
- Original Flask Starter Documentation
-
Start out by cloning the repository
-
Install the dependencies
pipenv install -r requirements.txt
-
Create .env file, for example:
SECRET_KEY= super_secret_key_name DATABASE_URL=sqlite:///dev.db SCHEMA= schema_name_here
-
Make sure the SQLite3 database connection URL is in the .env file
-
In a terminal in the app directory, set up into your pipenv, migrate your database, seed your database, and run your Flask app:
pipenv shell flask db upgrade flask seed all flask run
-
To run the React App in development, checkout the README inside the
react-app
directory.- Essentially, in a terminal in the react-app folder:
npm install npm start
- Essentially, in a terminal in the react-app folder:
-
Now you can either set up an account or use the demo user option to explore EveryNote
- Users can sign up, log in, and log out.
- Users can use a demo log in to try the site.
- Users can't use certain features without logging in (like notes and sharing).
- Logged in users are directed to their profile page which displays a navigation bar, their notes, tasks, and a scratch pad.
- Logged out users are directed to the login page.
- Logged in users can select their notebooks, which provides them with a brief list of the notes contained therein.
- Logged in users can also write, edit, or delete notebooks.
- Logged in users can select and read their notes.
- Logged in users can also write, edit, or delete notes.
- Users can share notebooks with other users and determine if they have write capabilities.
- Logged in users can select and view tasks they have created.
- Logged in users can also write, edit, or delete tasks.
- Logged in users can view tags to notes.
- Logged in users can assign tags and delete them from notes.
request | purpose | value |
---|---|---|
GET /api/auth/ | When the app first loads, it checks to see if there is a a logged in user. It returns an object of the current user. | { 'id': INT, 'username':STRING, 'email': STRING } |
POST /api/auth/signup | With valid inputs, a user can sign up for an account, and it logs in the user. It returns the object of the newly-created in user. | { 'id': INT, 'username':STRING, 'email': STRING } |
POST /api/auth/login | With valid credentials, a user can login. It returns an object of the logged in user. | { 'id': INT, 'username':STRING, 'email': STRING } |
GET /api/auth/logout | A user can logout and leave no trace of their data. It returns a confirmation message. | { 'message': 'User logged out' } |
Request | Purpose | Return Value |
---|---|---|
GET/api/notes | This fetch queries for all notes and returns them in a list of note dictionaries | [{ "id": INTEGER, "body": STRING, "title": STRING, "notebookId": INTEGER, "ownerId": INTEGER, "trash": BOOLEAN, "created_at": DATETIME, "updated_at": DATETIME }] |
POST/api/notes | This fetch creates a new note and returns it as a dictionary | { "id": INTEGER, "body": STRING, "title": STRING, "notebookId": INTEGER, "ownerId": INTEGER, "trash": BOOLEAN, "created_at": DATETIME, "updated_at": DATETIME } |
GET/api/notes/:id | This fetch queries for a note by id and returns that note as a dictionary | { "id": INTEGER, "body": STRING, "title": STRING, "notebookId": INTEGER, "ownerId": INTEGER, "trash": BOOLEAN, "created_at": DATETIME, "updated_at": DATETIME } |
PUT/api/notes/:id | This fetch queries for a note by id and returns an updated note as a dictionary | { "id": INTEGER, "body": STRING, "title": STRING, "notebookId": INTEGER, "ownerId": INTEGER, "trash": BOOLEAN, "created_at": DATETIME, "updated_at": DATETIME } |
DELETE/api/notes/:id | This fetch queries for a note by id and deletes the note | {"message": "Successfully deleted"} |
Request | Purpose | Return Value |
---|---|---|
GET /api/tasks/ | A logged in user can view their tasks as a list. It returns an an array of tasks. | { 'id': INT, 'ownerId':INT, 'title': STRING, 'description': STRING, 'completed': BOOLEAN, 'due_date': STRING, 'created_at': STRING, 'created_at': STRING } |
GET /api/tasks/ | A logged in user can view their tasks as a list. It returns an an array of tasks. | { 'id': INT, 'ownerId':INT, 'title': STRING, 'description': STRING, 'completed': BOOLEAN, 'due_date': STRING, 'created_at': STRING, 'created_at': STRING } |
GET /api/tasks/taskId | A logged in user can view the details of a single task. It returns the specific information of the task. | { 'id': INT, 'ownerId':INT, 'title': STRING, 'description': STRING, 'completed': BOOLEAN, 'due_date': STRING, 'created_at': STRING, 'created_at': STRING } |
POST /api/tasks/new | A logged in user can add a new task to their tasks list. It returns the new task information. | { 'id': INT, 'ownerId':INT, 'title': STRING, 'description': STRING, 'completed': BOOLEAN, 'due_date': STRING, 'created_at': STRING, 'created_at': STRING } |
PUT /api/tasks/taskId | A logged in user can edit a specific task. It returns the edited task with the new information. | { 'id': INT, 'ownerId':INT, 'title': STRING, 'description': STRING, 'completed': BOOLEAN, 'due_date': STRING, 'created_at': STRING, 'created_at': STRING } |
DELETE /api/tasks/taskId/delete | A logged in user can delete a specific task. It returns a confirmation that the task was deleted successfully. | { 'message': "successful deletion" } |
request | purpose | value |
---|---|---|
GET /api/notebooks/ | Gets all Notebooks,Formats into a nested object. | { 'Notebooks':[ { 'id': INT, 'title':STRING, 'is_default': STRING 'ownerId': STRING } ] } |
GET /api/notebooks/:notebookId | Gets a single notebooks by its Id ,Formats into a nested object. | { 'id': INT, 'title':STRING, 'is_default': STRING 'ownerId': STRING } |
POST /api/notebooks/new/ | Creates a new notebook,Returns a formatted object. | { 'id': INT, 'title':STRING, 'is_default': STRING 'ownerId': STRING 'created_at': 'Thu, 01 Jan 2023 00:00:00 GMT', 'updated_at': 'Thu, 01 Jan 2023 00:00:00 GMT' } |
PUT /api/notebooks/:notebookId/edit/ | Updates the associated notebook by its Id,returns a formatted object. | { 'id': INT, 'title':STRING, 'is_default': STRING 'ownerId': STRING 'created_at': 'Thu, 01 Jan 2023 00:00:00 GMT', 'updated_at': 'Thu, 01 Jan 2023 00:00:00 GMT' } |
DELETE /api/notebooks/:notebook/delete | Deletes a notebook by its associated notebook,Returns a message. | { 'message': 'Notebook successfully deleted' } |
Request | Purpose | Return Value |
---|---|---|
GET /api/tags/ | Gets all Tags, formats into nested object | {'tags': [ { 'id': 1 'name': Joseph, 'num_notes': 5, 'created_at': 'Thu, 01 Jan 2023 00:00:00 GMT', 'updated_at': 'Thu, 01 Jan 2023 00:00:00 GMT' } ] } |
POST /api/tags/ | Creates new tag, returns formatted object | { 'id': 1 'name': Joseph, 'num_notes': 5, 'created_at': 'Thu, 01 Jan 2023 00:00:00 GMT', 'updated_at': 'Thu, 01 Jan 2023 00:00:00 GMT' } |
POST /api/tags/:tagId | Updates Tag of :tagId, returns updated tag in Object form | { 'id': 1 'name': Joseph, 'num_notes': 5, 'created_at': 'Thu, 01 Jan 2023 00:00:00 GMT', 'updated_at': 'Thu, 01 Jan 2023 00:00:00 GMT' } {"Error": "end of update route" } |
DELETE /api/tags/:tagId | Deletes Tag of :tagId | {"message": f'Tag {tagId} successfully deleted'} |
GET /api/tags/notetags/ | Fetches and formats nested objects of all ids of tags associated with each object (note_to_tags), and all notes associated with each tag (tag_to_notes) | {"note_to_tags": { 1: [2]}, "tag_to_notes": { 2: [1]}} |
POST /api/tags/notetags/int:noteId/int:tagId | Sends SQL query to add tag to note, returns message in object | { "message": f"Tag {tagId} successfully added to Note {noteId}"} { "error": f"Unable to add tag {tagId} to Note {noteId}; note {noteId} not found" } { "error": f"Unable to add tag {tagId} to Note {noteId}; tag {tagId} not found" } { "message" :f"Tag {tagId} is already in Note {noteId}??"} { "error": f"Unable to add tag {tagId} to Note {noteId}"} |
DELETE /api/tags/notetags/int:noteId/int:tagId | Removes tag from note, returns message in object | { "message": f"Tag {tagId} successfully removed from Note {noteId}"} { "error": f"Either unable to locate tag {tagId}, or notetag with note {noteId}"} |