Skip to content

tuantutanghuynh/todolistic-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TodoList

Full-stack task management app built with Laravel 12 & React 19

PHP Laravel React Vite TailwindCSS License


Dashboard Overview


Overview

TodoList is a full-stack SPA that lets you manage tasks with categories, priorities, and due dates. The backend exposes a RESTful JSON API secured by Laravel Sanctum (cookie-based SPA auth — no tokens in localStorage). The frontend is a React 19 SPA with optimistic updates, global search, dark/light theme, and a responsive sidebar.


Screenshots

Login — Dark Mode

Login page dark mode
Register — Validation Feedback

Register page with validation
Dashboard — Dark Mode

Dashboard dark mode
Dashboard — Light Mode

Dashboard light mode
New Task Modal

Create task modal
New Category Modal

Create category modal
Upcoming Tasks — with Categories, Dates & Priority Labels

Upcoming tasks view

Features

Feature Details
🔐 Authentication Register, login, logout — Sanctum SPA session (cookie-based)
Todos Create, edit, delete tasks with soft deletes
🏷️ Categories Group tasks with custom name, hex color & icon
🚦 Priority Levels Low / Medium / High with color-coded labels
📅 Due Dates Track today, upcoming, and overdue tasks
Optimistic Updates Instant UI feedback on toggle & delete — rolls back on error
🔍 Global Search Full-text search across all tasks (Ctrl+K)
📊 Stats Dashboard Live counts: Total, Pending, Completed, Overdue
🌙 Dark / Light Theme Persisted to localStorage, toggled from the header
📱 Responsive Sidebar Quick-access views: Dashboard, Today, Upcoming, Overdue, Completed

Tech Stack

Layer Technology
Backend PHP 8.2+, Laravel 12, Laravel Sanctum
Database MySQL (primary) · SQLite (fallback)
Frontend React 19, JavaScript ES Modules, Vite 7
Server State TanStack React Query 5
Routing React Router 7
HTTP Client Axios
Styling Tailwind CSS 4, CSS Modules

Project Structure

todolist/
├── backend/                        # Laravel 12 API
│   ├── app/
│   │   ├── Http/
│   │   │   ├── Controllers/Api/    # AuthController, TodoController, CategoryController
│   │   │   ├── Requests/           # Form request validators
│   │   │   └── Resources/          # API response transformers
│   │   ├── Models/                 # User, Todo, Category
│   │   └── Policies/               # Authorization policies
│   ├── database/
│   │   ├── migrations/             # DB schema
│   │   └── seeders/                # Demo data seeders
│   └── routes/api.php              # API route definitions
│
├── frontend/                       # React SPA
│   └── src/
│       ├── components/layout/      # MainLayout, Sidebar, Header, SearchBox, CategoryModal
│       ├── contexts/               # AuthContext
│       ├── hooks/                  # useDarkMode
│       ├── lib/                    # axios, queryClient, queryKeys, todoApi
│       ├── pages/
│       │   ├── auth/               # LoginPage, RegisterPage
│       │   └── todos/              # TodosPage, TodoItem, TodoModal, StatsCards
│       └── router/                 # index, ProtectedRoute, GuestRoute
│
├── photo/                          # App screenshots
└── documents/                      # Project guides & documentation

Getting Started

Prerequisites

  • PHP 8.2+
  • Composer
  • Node.js 18+
  • MySQL — or use the bundled SQLite for a quick start
  • XAMPP / Laravel Herd / any local web server

1 — Clone the repository

git clone <repo-url>
cd todolist

2 — Backend setup

cd backend

composer install

cp .env.example .env
php artisan key:generate

Configure backend/.env with your database:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todolist
DB_USERNAME=root
DB_PASSWORD=

SESSION_DRIVER=database
SESSION_DOMAIN=localhost

SANCTUM_STATEFUL_DOMAINS=localhost:5173,127.0.0.1:5173
FRONTEND_URL=http://localhost:5173
php artisan migrate

# Optional: seed demo data
php artisan db:seed

# Start dev server → http://127.0.0.1:8000
php artisan serve

3 — Frontend setup

cd ../frontend

npm install

cp .env.example .env

Configure frontend/.env:

VITE_API_URL=http://127.0.0.1:8000
# Start dev server → http://localhost:5173
npm run dev

Demo accounts (after seeding)

Name Email Password
Demo User demo@example.com Password1!
Test User test@example.com Password1!
Peter peter@gmail.com Peter123456!

Environment Variables

Backend (backend/.env)

Variable Description Example
APP_URL Backend URL http://127.0.0.1:8000
DB_CONNECTION Database driver mysql
DB_DATABASE Database name todolist
SESSION_DRIVER Session storage database
SESSION_DOMAIN Session cookie domain localhost
SANCTUM_STATEFUL_DOMAINS Allowed SPA origins localhost:5173
FRONTEND_URL Frontend URL for CORS http://localhost:5173

Frontend (frontend/.env)

Variable Description Example
VITE_API_URL Backend API base URL http://127.0.0.1:8000

API Reference

All endpoints are prefixed with /api. Protected routes require an active session cookie.

Authentication

Method Endpoint Auth Description
POST /api/register Register a new user
POST /api/login Login
POST /api/logout Logout
GET /api/user Get current user

Todos

Method Endpoint Description
GET /api/todos List todos (filter, search, paginate)
POST /api/todos Create a todo
GET /api/todos/{id} Get a single todo
PATCH /api/todos/{id} Update a todo
DELETE /api/todos/{id} Soft-delete a todo
PATCH /api/todos/{id}/toggle Toggle completion status
POST /api/todos/bulk-delete Bulk delete
POST /api/todos/bulk-complete Bulk complete

Query parameters — GET /api/todos

Parameter Values Description
status pending · completed · overdue · due_today Filter by status
category_id integer Filter by category
priority 1 · 2 · 3 Low / Medium / High
search string Search in title
sort_by created_at · due_date · priority · title Sort field
sort_dir asc · desc Sort direction
per_page integer (max 100) Items per page

Categories

Method Endpoint Description
GET /api/categories List all categories (with pending count)
POST /api/categories Create a category
GET /api/categories/{id} Get a category
PATCH /api/categories/{id} Update a category
DELETE /api/categories/{id} Delete a category

Response format

{
  "data": {},
  "message": "Created successfully"
}

Paginated response:

{
  "data": [],
  "links": { "first": "...", "last": "...", "prev": null, "next": "..." },
  "meta": { "current_page": 1, "last_page": 3, "per_page": 20, "total": 45 }
}

Data Models

Todo

Field Type Description
id integer Primary key
user_id integer Owner
category_id integer · null Optional category
title string Task title (max 255)
description text · null Optional details
priority 1 · 2 · 3 Low / Medium / High
due_date date · null Deadline
is_completed boolean Completion status
completed_at timestamp · null When completed

API also returns computed fields: priority_label, is_overdue, status.

Category

Field Type Description
id integer Primary key
user_id integer Owner
name string Unique per user (max 100)
color string Hex color (default #3B82F6)
icon string · null Icon identifier

API also returns computed field: pending_count.


Frontend Architecture

State management

Layer Tool Responsibility
Server state TanStack React Query Fetching, caching, background refetch
Auth state React Context Current user, login/logout
UI state useState Modals, filters, selected items

Query key conventions

queryKeys.todos.lists()       // All todo list queries
queryKeys.todos.list(params)  // Specific list with params
queryKeys.todos.stats()       // Dashboard statistics
queryKeys.categories.list()   // Category list

Authentication flow

  1. Frontend calls GET /sanctum/csrf-cookie to obtain a CSRF token
  2. User submits credentials → POST /api/login
  3. Laravel creates a session and sets session + XSRF-TOKEN cookies
  4. Axios reads XSRF-TOKEN automatically and sends it as X-XSRF-TOKEN on every mutating request
  5. On page reload, GET /api/user restores auth state
  6. POST /api/logout invalidates the session server-side

Available Scripts

Backend

php artisan serve           # Start dev server (port 8000)
php artisan migrate         # Run pending migrations
php artisan migrate:fresh   # Drop all tables and re-migrate
php artisan db:seed         # Seed demo data
php artisan tinker          # Interactive REPL

Frontend

npm run dev      # Start Vite dev server (port 5173)
npm run build    # Production build
npm run preview  # Preview production build locally
npm run lint     # Run ESLint

License

MIT

About

Todo app engineered beyond basics — Laravel + React with focus on query optimization, algorithmic thinking, and scalable architecture patterns. Used as a testbed for performance improvement techniques.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors