The problem
Most to-do lists let tasks sit there forever. I wanted one where every task has a deadline, you can see the time running out, and missed tasks don't just pile up.
My approach
TaskFlow asks for a timeframe (from minutes up to a year) when you add a task, then shows a countdown on the card. When something goes overdue you can shift it to the same time tomorrow, or turn on auto-shift.
How it's built
- UI1
React + Vite
Landing, login, sign up, dashboard and admin pages
- State2
Redux Toolkit
Slices for auth, users, todos and filters
- Routing3
React Router
Protected routes, admin-only /admin
- Forms4
React Hook Form
Validation for login, sign up and task forms
- Storage5
localStorage
State saved in the browser so it survives a refresh
Deadlines
Pick a timeframe and priority, then watch the countdown and progress bar.
Shift to next day
Overdue tasks get a button to move them to tomorrow, plus a 'shift all' banner.
Filters
All / active / completed / overdue, priority, timeframe, search and sorting.
Admin panel
Stats, most repeated todo titles, timeframe breakdown and every user's list.
Challenges & decisions
Lots of timers
Instead of a setInterval per card, one shared useNow hook ticks and every countdown reads from it.
Saving state safely
Saves to localStorage with a small debounce and a versioned key so old saved data can't break the app.
More screens

Tech stack
- React
- Vite
- Redux Toolkit
- React Router
- React Hook Form
- Tailwind CSS
What I learned
- →Structuring Redux Toolkit slices for a real app
- →Protected and role-based routes with React Router
- →Date and deadline maths is harder than it looks
