diff --git a/src/controllers/task_controller.py b/src/controllers/task_controller.py deleted file mode 100644 index 6fdf9ce..0000000 --- a/src/controllers/task_controller.py +++ /dev/null @@ -1,21 +0,0 @@ -from flask import Blueprint, jsonify, request - -from src.models import SessionLocal -from src.repository.tasks_repository import TasksRespository - -task_blueprint = Blueprint("task", __name__) - - -@task_blueprint.route("/tasks/create", methods=["POST"]) -def create_task(): - json = request.json - title = request.title - description = request.description - user_id = request.user_id # TODO: How do I identify the user ID? - - if title is None or description is None: - return jsonify({"error": "Title and description are required."}), 400 - - with SessionLocal() as db: - task_repo = TasksRespository(db) - task_repo diff --git a/src/controllers/tasks_controller.py b/src/controllers/tasks_controller.py new file mode 100644 index 0000000..19606c4 --- /dev/null +++ b/src/controllers/tasks_controller.py @@ -0,0 +1,131 @@ +from flask import Blueprint, flash, jsonify, redirect, render_template, url_for +from flask_login import login_required, current_user +from src.forms.task_form import AddTaskForm, DeleteTaskForm, EditTaskForm +from src.models import SessionLocal, Tasks +from src.repository.tasks_repository import TasksRespository + +tasks_blueprint = Blueprint("tasks", __name__) + + +@tasks_blueprint.route("/", methods=["GET", "POST"]) +@login_required +def view_tasks(user_id): + session = SessionLocal() + task_repo = TasksRespository(session) + tasks = task_repo.find_tasks_by_user(user_id) + session.close() + return render_template("view_tasks.html", tasks=tasks) + + +@tasks_blueprint.route("/add/", methods=["GET", "POST"]) +@login_required +def add_task(user_id): + form = AddTaskForm() + + if form.validate_on_submit(): + title = form.title.data + description = form.description.data + status = form.status.data + + session = SessionLocal() + task_repo = TasksRespository(session) + + task = Tasks( + title=title, description=description, status=status, user_id=user_id + ) + task_repo.add_task(task) + session.close() + + flash("Task successfully created.", "success") + return redirect(url_for("tasks.view_tasks", user_id=user_id)) + + return render_template("add_task.html", form=form, user_id=user_id) + + +@tasks_blueprint.route("/edit/", methods=["GET", "POST"]) +@login_required +def edit_task(user_id): + form = EditTaskForm() + + if form.validate_on_submit(): + # gather data from the form + task_id = form.id.data + new_title = form.title.data or None # Convert blank to None + new_description = form.description.data or None # Convert blank to None + new_status = form.status.data or None # Convert blank to None + + # initiate DB and collect relevant data + session = SessionLocal() + task_repo = TasksRespository(session) + tasks = task_repo.find_tasks_by_user(user_id) + all_ids = [task.id for task in tasks] + + # Check is username has access to the selected task + if task_id not in all_ids: + flash( + f"Task # {task_id} is not associated with this user. Enter another task ID.", + "danger", + ) + session.close() + return redirect(url_for("tasks.edit_task", user_id=user_id)) + + # User is able to edit task + task_repo.edit_task( + task_id=task_id, + title=new_title, + description=new_description, + status=new_status, + ) + flash("Task successfully created.", "success") + return redirect(url_for("tasks.view_tasks", user_id=user_id)) + + return render_template("edit_task.html", form=form, user_id=user_id) + + +@tasks_blueprint.route("/delete/", methods=["GET", "POST"]) +@login_required +def delete_task(user_id): + form = DeleteTaskForm() + + if form.validate_on_submit(): + task_id = form.id.data + + # initiate DB and collect relevant data + session = SessionLocal() + task_repo = TasksRespository(session) + tasks = task_repo.find_tasks_by_user(user_id) + all_ids = [task.id for task in tasks] + + # Check if task belongs to the user + if task_id not in all_ids: + flash( + f"Task # {task_id} is not associated with this user. Enter another task ID.", + "danger", + ) + session.close() + return redirect(url_for("tasks.delete_task", user_id=user_id)) + + return render_template("delete_task.html", form=form, user_id=user_id) + + +@tasks_blueprint.route("/api/") +@login_required +def get_task_details(task_id): + session = SessionLocal() + task_repo = TasksRespository(session) + task = task_repo.find_task_by_id(task_id) + session.close() + + if task is not None: + return jsonify( + { + "title": task.title, + "description": task.description, + "status": task.status, + } + ) + else: + return ( + jsonify({"error": f"Task ID {task_id} does not exist for this user."}), + 404, + ) \ No newline at end of file diff --git a/src/main.py b/src/main.py index dc857d1..57ce202 100644 --- a/src/main.py +++ b/src/main.py @@ -1,12 +1,12 @@ -from flask import Flask, flash, jsonify, redirect, render_template, request, url_for +from flask import Flask, flash, redirect, render_template, url_for from flask_login import LoginManager, login_required, login_user, logout_user -from src.forms.task_form import AddTaskForm, DeleteTaskForm, EditTaskForm from src.forms.user_forms import LogInForm, RegisterForm from src.models import Base, SessionLocal, Tasks, Users, engine from src.repository.tasks_repository import TasksRespository from src.repository.users_repository import UsersRepository -from src.security import generate_password_hash + +from src.controllers.tasks_controller import tasks_blueprint app = Flask(__name__, static_folder="../static", template_folder="../templates") app.config["SECRET_KEY"] = "shhhh_dont_tell_anyone" @@ -20,6 +20,8 @@ # Ensure tables are created Base.metadata.create_all(bind=engine) +# Register blueprints to for tasks and users controllers +app.register_blueprint(tasks_blueprint, url_prefix="/tasks") @login_manager.user_loader def load_user(user_id): @@ -53,7 +55,7 @@ def login(): else: login_user(user) session.close() - return redirect(url_for("view_tasks", user_id=user.id)) + return redirect(url_for("tasks.view_tasks", user_id=user.id)) return render_template("login.html", form=form) @@ -66,12 +68,6 @@ def logout(): return redirect(url_for("login")) -@app.route("/dashboard") -@login_required -def dashboard(): - return "Welcome to your dashboard!" - - @app.route("/register", methods=["GET", "POST"]) def register(): form = RegisterForm() @@ -96,129 +92,5 @@ def register(): return render_template("register.html", form=form) -@app.route("/tasks/") -@login_required -def view_tasks(user_id): - session = SessionLocal() - task_repo = TasksRespository(session) - tasks = task_repo.find_tasks_by_user(user_id) - session.close() - return render_template("view_tasks.html", tasks=tasks) - - -@app.route("/add_task/", methods=["GET", "POST"]) -@login_required -def add_task(user_id): - form = AddTaskForm() - - if form.validate_on_submit(): - title = form.title.data - description = form.description.data - status = form.status.data - - session = SessionLocal() - task_repo = TasksRespository(session) - - task = Tasks( - title=title, description=description, status=status, user_id=user_id - ) - task_repo.add_task(task) - session.close() - - flash("Task successfully created.", "success") - return redirect(url_for("view_tasks", user_id=user_id)) - - return render_template("add_task.html", form=form, user_id=user_id) - - -@app.route("/edit_task/", methods=["GET", "POST"]) -@login_required -def edit_task(user_id): - form = EditTaskForm() - - if form.validate_on_submit(): - # gather data from the form - task_id = form.id.data - new_title = form.title.data or None # Convert blank to None - new_description = form.description.data or None # Convert blank to None - new_status = form.status.data or None # Convert blank to None - - # initiate DB and collect relevant data - session = SessionLocal() - task_repo = TasksRespository(session) - tasks = task_repo.find_tasks_by_user(user_id) - all_ids = [task.id for task in tasks] - - # Check is username has access to the selected task - if task_id not in all_ids: - flash( - f"Task # {task_id} is not associated with this user. Enter another task ID.", - "danger", - ) - session.close() - return redirect(url_for("edit_task", user_id=user_id)) - - # User is able to edit task - task_repo.edit_task( - task_id=task_id, - title=new_title, - description=new_description, - status=new_status, - ) - flash("Task successfully created.", "success") - return redirect(url_for("view_tasks", user_id=user_id)) - - return render_template("edit_task.html", form=form, user_id=user_id) - - -@app.route("/delete_task/", methods=["GET", "POST"]) -@login_required -def delete_task(user_id): - form = DeleteTaskForm() - - if form.validate_on_submit(): - task_id = form.id.data - - # initiate DB and collect relevant data - session = SessionLocal() - task_repo = TasksRespository(session) - tasks = task_repo.find_tasks_by_user(user_id) - all_ids = [task.id for task in tasks] - - # Check if task belongs to the user - if task_id not in all_ids: - flash( - f"Task # {task_id} is not associated with this user. Enter another task ID.", - "danger", - ) - session.close() - return redirect(url_for("delete_task", user_id=user_id)) - - return render_template("delete_task.html", form=form, user_id=user_id) - - -@app.route("/api/task/") -@login_required -def get_task_details(task_id): - session = SessionLocal() - task_repo = TasksRespository(session) - task = task_repo.find_task_by_id(task_id) - session.close() - - if task is not None: - return jsonify( - { - "title": task.title, - "description": task.description, - "status": task.status, - } - ) - else: - return ( - jsonify({"error": f"Task ID {task_id} does not exist for this user."}), - 404, - ) - - if __name__ == "__main__": app.run(debug=True, port=5001) diff --git a/templates/add_task.html b/templates/add_task.html index e22643f..20b7ebc 100644 --- a/templates/add_task.html +++ b/templates/add_task.html @@ -16,7 +16,7 @@

Add a Task to Your ToDo List

-
+ {{ form.hidden_tag() }}
{{ form.title.label }} diff --git a/templates/base.html b/templates/base.html index 5733124..a633fc1 100644 --- a/templates/base.html +++ b/templates/base.html @@ -18,10 +18,10 @@ Settings diff --git a/templates/delete_task.html b/templates/delete_task.html index 72fa472..eafa37c 100644 --- a/templates/delete_task.html +++ b/templates/delete_task.html @@ -20,7 +20,7 @@

then the selected task is not associated with the active user.

- + {{ form.hidden_tag() }}
{{ form.id.label }} @@ -50,7 +50,7 @@

const taskId = this.value; // Fetch task details via an API (adjust URL as needed) - fetch(`/api/task/${taskId}`) + fetch(`/tasks/api/${taskId}`) .then(response => response.json()) .then(data => { // Populate the fields with task details diff --git a/templates/edit_task.html b/templates/edit_task.html index 3862ab9..acf2ba9 100644 --- a/templates/edit_task.html +++ b/templates/edit_task.html @@ -16,7 +16,7 @@

Edit Your Task

- + {{ form.hidden_tag() }}
{{ form.id.label }}