A task management application built with React, TypeScript, and Vite, using the Context API for global state and Auth0 for authentication. Users can register, log in, and create, view, edit, and delete tasks through a protected dashboard.
- Task Dashboard — view all tasks at a glance, with status and priority badges
- Task Details — dedicated view for a single task's full information
- Create / Edit Tasks — forms with inline validation (required title, valid due date)
- Delete Tasks — remove tasks directly from the dashboard or the details page
- Registration & Login — dedicated
/registerand/loginpages, backed by Auth0's Universal Login - Protected routes — unauthenticated visitors are redirected to
/loginand returned to the page they originally requested after signing in - Fully typed — task shapes, form inputs/errors, reducer actions, and the mapped Auth0 user are all defined as TypeScript types/interfaces
- React 19 + Vite
- TypeScript
- React Router DOM for routing
- React Bootstrap + Bootstrap 5 for UI
- Auth0 React SDK for authentication
- Axios (installed, available for future API integration)
task.ts—Task,TaskStatus,TaskPriority,TaskFormInput,TaskUpdateInput, andTaskFormErrorsuser.ts—AppUser, a normalized shape for the authenticated user
context.ts— theTaskContextobject and theTaskContextValueinterfaceTaskReducer.ts— ataskReducerhandlingSET_TASKS,ADD_TASK,UPDATE_TASK,DELETE_TASK,SET_LOADING, andSET_ERRORTaskActions.ts— a discriminated union of all reducer actions for exhaustive type checkingTaskContext.tsx— wraps the reducer in aTaskProvidercomponentUseTasks.ts— auseTasks()hook for consuming the context, kept in its own file soTaskContext.tsxonly exports a component (this keeps React Fast Refresh happy)
Task state currently lives in memory (via useReducer) and is not yet persisted to a backend or local storage.
Auth0ProviderWithNavigate.tsx— wraps the app in Auth0's provider and, on successful login, navigates the user back to whichever page they originally tried to visitMapAuthUser.ts— maps the raw Auth0Userobject into the app's typedAppUserUseAppUser.ts— a custom hook combininguseAuth0()withmapAuthUserAuthButton.tsx— nav bar control: shows "Log In"/"Sign Up" links when signed out, or the user's name and a "Log Out" button when signed inProtectedRoute.tsx— redirects unauthenticated users to/login, preserving the page they were headed toLogin.tsx/Register.tsx— dedicated pages that trigger Auth0's hosted Universal Login (registration opens directly on the sign-up screen viascreen_hint: 'signup'), then return the user to wherever they started
Dashboard.tsx— lists all tasks with links to view, edit, or deleteTaskCreate.tsx— creates a new task tied to the authenticated user's IDTaskDetails.tsx— shows a single task's full details with edit/delete actionsTaskEdit.tsx— pre-fills the task form for updating an existing taskLogin.tsx/Register.tsx— authentication entry points
| Path | Page | Protected? |
|---|---|---|
/login |
Login | No |
/register |
Register | No |
/ |
Dashboard | Yes |
/tasks/new |
Create Task | Yes |
/tasks/:id |
Task Details | Yes |
/tasks/:id/edit |
Edit Task | Yes |
- Node.js and npm
- An Auth0 account with an application configured for this project
git clone https://github.com/coding-cryptid/task-management-app.git
cd task-management-app
npm installCreate a .env file in the project root with your Auth0 application credentials:
VITE_AUTH0_DOMAIN=your-auth0-domain
VITE_AUTH0_CLIENT_ID=your-auth0-client-id
In your Auth0 application settings, add your local dev URL(s) to Allowed Callback URLs, Allowed Logout URLs, and Allowed Web Origins — for example:
http://localhost:5173, http://localhost:5174
(Vite will pick a different port if 5173 is already in use, so listing a couple of fallback ports avoids callback URL mismatches during local development.)
npm run devnpm run build # type-check and build for production
npm run lint # run ESLint
npm run preview # preview the production build locally- Tasks are stored only in memory for the current session and are lost on page refresh; there is no backend or persistence layer yet. I plan on adding it in the future, so stay tuned! :)