FastAPI - Beginner to Pro / Project 5 - Full Stack Application

FastAPI Full Stack - Add Todo Page

📋 Setting Up the To-Do Page in Our Full-Stack FastAPI App

In this step, we’re creating the main dashboard of our application: the To-Do page. This page will display all tasks for a logged-in user and allow them to add, edit, delete, and mark tasks as complete.


1️⃣ Update todos.py Router

Imports

At the top of todos.py, make sure to import:

from fastapi import Request, Depends, status
from fastapi.templating import Jinja2Templates
from starlette.responses import RedirectResponse

Templates Variable

templates = Jinja2Templates(directory="TodoApp/templates")

2️⃣ Redirect Function

We need a helper function to redirect unauthenticated users to the login page:

def redirect_to_login():
			redirect_response = RedirectResponse(url="/auth/login-page", status_code=status.HTTP_302_FOUND)
			redirect_response.delete_cookie(key="access_token")  # Remove token if it exists
			return redirect_response

3️⃣ To-Do Page Endpoint

@router.get("/todo-page")
async def render_todo_page(request: Request, db=Depends(get_db)):
    try:
        # Get current user using JWT from cookies
        user = await get_current_user(request.cookies.get("access_token"))
        if not user:
            return redirect_to_login()

        # Fetch all todos for this user
        todos = db.query(Todos).filter(Todos.owner_id == user.id).all()

        return templates.TemplateResponse(
            "todo.html",
            {"request": request, "todos": todos, "user": user}
        )
    except:
        return redirect_to_login()

✅ Notes:

  • get_current_user uses the JWT in cookies to verify identity.

  • If the JWT is invalid or missing, the user is redirected to login.

  • todos contains all tasks for the logged-in user.


4️⃣ Create todo.html Template

Inside templates, create todo.html and paste the code below inside.

{% include "layout.html" %}

<div class="container">
    <div class="card text-center">
        <div class="card-header">Your To-Dos</div>
        <div class="card-body">
            <h5 class="card-title">List of Your To-Dos</h5>
            <p class="card-text">Information regarding tasks that need completion</p>

            <table class="table table-hover">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Info</th>
                        <th scope="col">Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {% for todo in todos %}
                        {% if not todo.complete %}
                        <tr class="pointer">
                            <td>{{ loop.index }}</td>
                            <td>{{ todo.title }}</td>
                            <td>
                                <button type="button" class="btn btn-info"
                                    onclick="window.location.href='/edit-todo-page/{{ todo.id }}'">
                                    Edit
                                </button>
                            </td>
                        </tr>
                        {% else %}
                        <tr class="pointer alert alert-success">
                            <td>{{ loop.index }}</td>
                            <td class="strikethrough">{{ todo.title }}</td>
                            <td>
                                <button type="button" class="btn btn-info"
                                    onclick="window.location.href='/edit-todo-page/{{ todo.id }}'">
                                    Edit
                                </button>
                            </td>
                        </tr>
                        {% endif %}
                    {% endfor %}
                </tbody>
            </table>
            <a href="/add-todo-page" class="btn btn-primary">Add a New To-Do</a>
        </div>
    </div>
</div>

✅ Features:

  • Table view for all user’s todos.

  • Strikethrough completed tasks (todo.complete == True).

  • Edit buttons redirect to the edit page for each task.

  • Add button to create a new to-do.


5️⃣ Testing the Page

Start the application:

uvicorn TodoApp.main:app --reload
  1. Go to: /auth/login-page and log in.

  2. You’ll see your to-dos listed.

  1. If there are no to-dos yet, you can create some via /docs or future add-todo page.

  2. Completed tasks appear with a green alert and strikethrough.

  3. Unauthenticated access redirects to login.


✅ Summary

  • We added a To-Do page template (todo.html).

  • Connected it with FastAPI endpoint /todo-page.

  • Implemented user-based filtering using JWT in cookies.

  • Displayed todos in a table with conditional formatting.

  • Redirects unauthenticated users to login.

Next up: implementing logout functionality to safely remove cookies and log out users.