Skip to main content

Project: Task Management Dashboard

Overview

Build a complete task management application with projects, tasks, filtering, and local storage persistence.

Learning Objectives

  • Apply all fundamental React concepts
  • Component composition and reusability
  • Form handling and validation
  • List rendering and keys
  • State management
  • Local storage integration
  • Conditional rendering
  • Event handling

Project Requirements

Core Features

1. Project Management

  • Create, edit, delete projects
  • Each project has: name, color, description
  • Default "Inbox" project (cannot be deleted)
  • Active project selection

2. Task Management

  • Create, edit, delete tasks
  • Task properties:
    • Title (required)
    • Description (optional)
    • Due date
    • Priority (low, medium, high)
    • Status (todo, in-progress, done)
    • Project assignment
  • Drag to reorder tasks (bonus)

3. Filtering & Sorting

  • Filter by project
  • Filter by status
  • Filter by priority
  • Search tasks by title/description
  • Sort by: due date, priority, creation date, alphabetically

4. Views

  • Today: Tasks due today
  • Upcoming: Tasks due in next 7 days
  • All tasks
  • Completed tasks
  • Project-specific view

5. Data Persistence

  • Save to localStorage
  • Load on app start
  • Auto-save on changes

Bonus Features

  • Task tags/labels
  • Task notes/comments
  • Recurring tasks
  • Task time tracking
  • Statistics dashboard
  • Dark mode toggle
  • Export/import data
  • Keyboard shortcuts
  • Mobile responsive design

Technical Requirements

Tech Stack

  • React 18+ with TypeScript
  • Vite for build tooling
  • CSS Modules or Styled Components
  • Date handling: date-fns or dayjs
  • Icons: react-icons or heroicons

Project Structure

task-manager/
├── src/
│ ├── components/
│ │ ├── Layout/
│ │ │ ├── Header.tsx
│ │ │ ├── Sidebar.tsx
│ │ │ └── MainContent.tsx
│ │ ├── Project/
│ │ │ ├── ProjectList.tsx
│ │ │ ├── ProjectItem.tsx
│ │ │ └── ProjectForm.tsx
│ │ ├── Task/
│ │ │ ├── TaskList.tsx
│ │ │ ├── TaskItem.tsx
│ │ │ ├── TaskForm.tsx
│ │ │ └── TaskDetail.tsx
│ │ ├── Filters/
│ │ │ ├── SearchBar.tsx
│ │ │ ├── FilterPanel.tsx
│ │ │ └── SortDropdown.tsx
│ │ └── common/
│ │ ├── Button.tsx
│ │ ├── Modal.tsx
│ │ ├── Input.tsx
│ │ └── Select.tsx
│ ├── hooks/
│ │ ├── useLocalStorage.ts
│ │ ├── useTasks.ts
│ │ └── useProjects.ts
│ ├── types/
│ │ └── index.ts
│ ├── utils/
│ │ ├── localStorage.ts
│ │ ├── dateUtils.ts
│ │ └── taskFilters.ts
│ ├── App.tsx
│ ├── App.module.css
│ └── main.tsx
├── package.json
├── tsconfig.json
└── vite.config.ts

Data Models

TypeScript Interfaces

// types/index.ts

export type Priority = 'low' | 'medium' | 'high';
export type TaskStatus = 'todo' | 'in-progress' | 'done';

export interface Project {
id: string;
name: string;
color: string;
description?: string;
createdAt: Date;
isDefault?: boolean;
}

export interface Task {
id: string;
title: string;
description?: string;
projectId: string;
priority: Priority;
status: TaskStatus;
dueDate?: Date;
createdAt: Date;
completedAt?: Date;
tags?: string[];
}

export interface FilterState {
searchTerm: string;
projectId: string | null;
status: TaskStatus | null;
priority: Priority | null;
}

export type SortOption =
| 'dueDate-asc'
| 'dueDate-desc'
| 'priority-asc'
| 'priority-desc'
| 'createdAt-asc'
| 'createdAt-desc'
| 'title-asc'
| 'title-desc';

Implementation Guide

Step 1: Project Setup (30 min)

# Create Vite project
npm create vite@latest task-manager -- --template react-ts
cd task-manager
npm install

# Install dependencies
npm install date-fns react-icons

# Start dev server
npm run dev

Step 2: Basic Layout (1 hour)

Create the app shell:

  • Header with app title and actions
  • Sidebar for project navigation
  • Main content area for tasks

Step 3: Project Management (2 hours)

  • Create project list in sidebar
  • Add project form (modal or inline)
  • Edit/delete project functionality
  • Project selection

Step 4: Task Management (3 hours)

  • Task list component
  • Task item component with all fields
  • Add/edit task form
  • Delete task with confirmation
  • Mark task as complete

Step 5: Filtering & Sorting (2 hours)

  • Search bar for tasks
  • Filter panel (status, priority, project)
  • Sort dropdown
  • Implement filter/sort logic with useMemo

Step 6: Special Views (1 hour)

  • Today view
  • Upcoming view
  • Completed view
  • All tasks view

Step 7: Local Storage (1 hour)

  • Custom useLocalStorage hook
  • Save projects and tasks
  • Load on mount
  • Auto-save on changes

Step 8: Styling & Polish (2 hours)

  • Make it beautiful
  • Add transitions/animations
  • Responsive design
  • Dark mode (bonus)

Sample Code

useLocalStorage Hook

import { useState, useEffect } from 'react';

export function useLocalStorage\<T\>(key: string, initialValue: T) {
const [value, setValue] = useState\<T\>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});

useEffect(() => {
try {
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
}, [key, value]);

return [value, setValue] as const;
}

Task Filtering Logic

export function filterTasks(tasks: Task[], filters: FilterState): Task[] {
return tasks.filter(task => {
// Search term
if (filters.searchTerm) {
const term = filters.searchTerm.toLowerCase();
if (
!task.title.toLowerCase().includes(term) &&
!task.description?.toLowerCase().includes(term)
) {
return false;
}
}

// Project filter
if (filters.projectId && task.projectId !== filters.projectId) {
return false;
}

// Status filter
if (filters.status && task.status !== filters.status) {
return false;
}

// Priority filter
if (filters.priority && task.priority !== filters.priority) {
return false;
}

return true;
});
}

export function sortTasks(tasks: Task[], sortBy: SortOption): Task[] {
const sorted = [...tasks];

switch (sortBy) {
case 'dueDate-asc':
return sorted.sort(
(a, b) => (a.dueDate?.getTime() || 0) - (b.dueDate?.getTime() || 0)
);
case 'priority-asc':
const priorityMap = { low: 0, medium: 1, high: 2 };
return sorted.sort(
(a, b) => priorityMap[a.priority] - priorityMap[b.priority]
);
// Add more sort cases...
default:
return sorted;
}
}

Task Form Component

interface TaskFormProps {
task?: Task;
projectId?: string;
onSave: (task: Omit<Task, 'id' | 'createdAt'>) => void;
onCancel: () => void;
}

export function TaskForm({ task, projectId, onSave, onCancel }: TaskFormProps) {
const [title, setTitle] = useState(task?.title || '');
const [description, setDescription] = useState(task?.description || '');
const [priority, setPriority] = useState<Priority>(
task?.priority || 'medium'
);
const [dueDate, setDueDate] = useState(task?.dueDate || '');
const [selectedProject, setSelectedProject] = useState(
task?.projectId || projectId || ''
);

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();

if (!title.trim()) {
alert('Title is required');
return;
}

onSave({
title: title.trim(),
description: description.trim(),
projectId: selectedProject,
priority,
status: task?.status || 'todo',
dueDate: dueDate ? new Date(dueDate) : undefined,
});
};

return <form onSubmit={handleSubmit}>{/* Form fields... */}</form>;
}

Evaluation Criteria

Functionality (40%)

  • All core features work correctly
  • No bugs or errors
  • Smooth user experience
  • Data persists correctly

Code Quality (30%)

  • Clean, readable code
  • Proper component structure
  • Reusable components
  • Appropriate use of hooks
  • TypeScript types used correctly

UI/UX (20%)

  • Intuitive interface
  • Good visual design
  • Responsive layout
  • Loading states
  • Error handling

Best Practices (10%)

  • Proper key usage in lists
  • Optimized re-renders
  • Accessibility considerations
  • Performance optimizations

Submission

Create a GitHub repository with:

  • Complete source code
  • README with setup instructions
  • Screenshots or demo GIF
  • List of implemented features
  • Known issues (if any)

Time Estimate

12-15 hours over 3-5 days

Resources

Next Steps

After completing this project:

  1. Get code review from peers or mentor
  2. Deploy to Netlify/Vercel
  3. Add additional features from bonus list
  4. Move to Module 02: Hooks & State