πŸš€ Module 10 Capstone Project: Full-Stack SaaS Platform

Build a production-ready Software-as-a-Service platform that showcases everything you've learned throughout this course. This comprehensive project integrates TypeScript, React, state management, routing, forms, testing, and deploymentβ€”culminating in a portfolio-worthy application!

🎯 Project Overview

You'll build TaskFlow Proβ€”a collaborative project management SaaS platform with team workspaces, real-time updates, advanced analytics, and subscription tiers. This project demonstrates your ability to architect and deploy a complete production application.

Estimated Time: 30-40 hours over 2-3 weeks

Difficulty: Advanced ⭐⭐⭐⭐⭐

πŸŽ“ Skills You'll Demonstrate

This capstone project showcases mastery of:

  • TypeScript advanced patterns and type safety across a large codebase
  • Complex component architecture with reusable patterns
  • Global state management with Redux Toolkit or Zustand
  • Authentication and authorization flows
  • Real-time data synchronization (WebSocket or polling)
  • Advanced routing with protected routes and role-based access
  • Complex form handling with multi-step wizards and validation
  • Data visualization with charts and analytics dashboards
  • Performance optimization for production
  • Comprehensive testing strategy
  • Accessibility (WCAG 2.1 AA compliance)
  • Production deployment with CI/CD

πŸ“‘ Project Guide

πŸ“‹ Project Requirements

TaskFlow Pro is a modern project management platform designed to help teams organize work, track progress, and collaborate effectively. Think of it as a blend of Trello, Asana, and Linear with your own unique touches.

🎯 What You're Building

πŸ’‘ Project Description

TaskFlow Pro is a collaborative workspace where teams can:

  • Create and manage projects with customizable workflows
  • Organize tasks with boards, lists, and cards (Kanban-style)
  • Assign tasks to team members with due dates and priorities
  • Track project progress with real-time analytics and charts
  • Collaborate with comments, mentions, and notifications
  • Manage team workspaces with role-based permissions
  • Access the platform from any device (fully responsive)

βœ… Minimum Viable Product (MVP) Requirements

⚠️ Must-Have Features

Your application MUST include these core features:

  1. Authentication System
    • User registration with email verification
    • Login/logout functionality
    • Password reset flow
    • Protected routes and authentication guards
  2. Workspace Management
    • Create and manage workspaces
    • Invite team members via email
    • Role-based access control (Owner, Admin, Member, Viewer)
  3. Project & Task Management
    • Create projects within workspaces
    • Kanban board with drag-and-drop task cards
    • Task creation with title, description, assignee, due date, priority
    • Task status management (To Do, In Progress, Done, etc.)
    • Task filtering and search functionality
  4. Real-Time Updates
    • Live task updates when team members make changes
    • Real-time notifications for mentions and assignments
    • Optimistic UI updates for smooth user experience
  5. Analytics Dashboard
    • Project completion rate visualization
    • Team productivity charts
    • Task distribution by status
    • Time tracking and burndown charts
  6. Responsive Design
    • Mobile-first responsive layout
    • Touch-optimized interactions for mobile devices
    • Adaptive navigation for different screen sizes

🌟 Bonus Features (Choose 2-3)

βœ… Nice-to-Have Enhancements

Implement at least 2-3 of these advanced features to showcase your skills:

  • File Attachments: Upload and attach files to tasks (images, documents, etc.)
  • Activity Feed: Timeline showing all workspace activity and changes
  • Custom Labels/Tags: Color-coded labels for task categorization
  • Time Tracking: Track time spent on tasks with start/stop timers
  • Recurring Tasks: Automatically create tasks on a schedule
  • Dark Mode: Complete dark theme implementation with persistence
  • Keyboard Shortcuts: Power-user keyboard navigation (like Linear)
  • Calendar View: Alternative view showing tasks in calendar format
  • Email Integration: Create tasks via email, send digests
  • Export Features: Export projects to CSV/PDF for reporting
  • Advanced Search: Full-text search with filters and autocomplete
  • Webhooks: Integrate with external services (Slack, Discord, etc.)

🚫 What NOT to Build (Keep It Focused)

❌ Out of Scope

To keep the project manageable, do NOT include:

  • Payment processing or subscription billing (you can mock this)
  • Video/audio chat features
  • Advanced AI or machine learning features
  • Mobile native apps (web-only is fine)
  • Backend infrastructure (use Firebase, Supabase, or mock API)

Focus on frontend excellence! Use existing backend services rather than building your own API.

🎨 Core Features Overview

Let's break down each major feature area and what it should include.

πŸ” Authentication & User Management

// Types for authentication
interface User {
  id: string;
  email: string;
  name: string;
  avatar?: string;
  createdAt: Date;
  emailVerified: boolean;
}

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
}

// Features to implement:
// - Registration form with validation
// - Email verification flow
// - Login with remember me option
// - Password reset via email
// - Profile management page
// - Avatar upload
// - Account settings

πŸ‘₯ Workspace & Team Management

interface Workspace {
  id: string;
  name: string;
  description?: string;
  ownerId: string;
  members: WorkspaceMember[];
  createdAt: Date;
  updatedAt: Date;
}

interface WorkspaceMember {
  userId: string;
  role: 'owner' | 'admin' | 'member' | 'viewer';
  joinedAt: Date;
}

// Features to implement:
// - Create workspace wizard
// - Workspace settings page
// - Invite members via email
// - Member management table
// - Role-based permissions system
// - Leave/delete workspace functionality

πŸ“Š Project & Board Management

interface Project {
  id: string;
  workspaceId: string;
  name: string;
  description?: string;
  color?: string;
  status: 'active' | 'archived' | 'completed';
  lists: List[];
  createdAt: Date;
  updatedAt: Date;
}

interface List {
  id: string;
  projectId: string;
  title: string;
  position: number;
  tasks: Task[];
}

interface Task {
  id: string;
  listId: string;
  title: string;
  description?: string;
  assigneeId?: string;
  dueDate?: Date;
  priority: 'low' | 'medium' | 'high' | 'urgent';
  status: 'todo' | 'in-progress' | 'review' | 'done';
  labels?: string[];
  position: number;
  createdAt: Date;
  updatedAt: Date;
}

// Features to implement:
// - Kanban board with drag-and-drop
// - Quick task creation
// - Task detail modal/sidebar
// - Task assignment dropdown
// - Due date picker with calendar
// - Priority indicators
// - Progress tracking

πŸ’¬ Comments & Activity

interface Comment {
  id: string;
  taskId: string;
  authorId: string;
  content: string;
  mentions?: string[];  // User IDs mentioned
  createdAt: Date;
  updatedAt: Date;
}

interface Activity {
  id: string;
  workspaceId: string;
  userId: string;
  type: 'task_created' | 'task_updated' | 'comment_added' | 'member_added';
  entityId: string;
  metadata: Record;
  createdAt: Date;
}

// Features to implement:
// - Comment thread on tasks
// - @mention functionality
// - Activity feed timeline
// - Notification system
// - Real-time updates

πŸ“ˆ Analytics & Reporting

interface Analytics {
  projectId: string;
  completionRate: number;
  totalTasks: number;
  completedTasks: number;
  overdueTasks: number;
  tasksByStatus: Record;
  tasksByPriority: Record;
  memberProductivity: {
    userId: string;
    tasksCompleted: number;
    tasksInProgress: number;
  }[];
}

// Features to implement:
// - Dashboard with key metrics cards
// - Completion rate chart (line/area)
// - Task distribution pie/donut chart
// - Team productivity bar chart
// - Filter by date range
// - Export to CSV
graph TB A[User Lands on App] --> B{Authenticated?} B -->|No| C[Landing Page] C --> D[Sign Up / Login] D --> E[Email Verification] E --> F[Create/Join Workspace] B -->|Yes| F F --> G[Workspace Dashboard] G --> H[View Projects] H --> I[Kanban Board] I --> J[Manage Tasks] J --> K[View Analytics] I --> L[Add Comments] I --> M[Assign Members] I --> N[Set Due Dates] style A fill:#667eea,stroke:#764ba2,stroke-width:2px,color:#fff style F fill:#48bb78,stroke:#38a169,stroke-width:2px,color:#fff style I fill:#ed8936,stroke:#dd6b20,stroke-width:2px,color:#fff style K fill:#9f7aea,stroke:#805ad5,stroke-width:2px,color:#fff

πŸ—οΈ Technical Architecture

Let's design the technical foundation for your application.

πŸ“¦ Tech Stack Requirements

Category Required Alternatives
Core Framework React 18+ with TypeScript -
Build Tool Vite Create React App, Next.js
Routing React Router v6 TanStack Router
State Management Redux Toolkit or Zustand Context API + useReducer
Data Fetching TanStack Query (React Query) SWR, custom hooks
Forms React Hook Form + Zod Formik + Yup
UI Components Tailwind CSS + Headless UI Material-UI, Chakra UI, shadcn/ui
Drag & Drop dnd kit or react-beautiful-dnd -
Charts Recharts or Chart.js Victory, Nivo
Testing Vitest + React Testing Library Jest + RTL
Backend/Database Firebase or Supabase Mock API with MSW
Deployment Vercel or Netlify GitHub Pages, Railway

πŸ’‘ Backend Strategy

You have three options for handling backend functionality:

  1. Firebase/Supabase (Recommended): Use a BaaS platform for auth, database, and real-time features
  2. Mock API: Use MSW (Mock Service Worker) to simulate backend responses
  3. Build Your Own: Create a simple Express/Nest.js API (only if you have time)

Recommendation: Use Firebase or Supabase to focus on frontend skills!

πŸ—‚οΈ Folder Structure

taskflow-pro/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ assets/              # Images, icons, fonts
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ auth/           # Login, Register, ResetPassword
β”‚   β”‚   β”œβ”€β”€ board/          # Kanban board components
β”‚   β”‚   β”œβ”€β”€ common/         # Button, Modal, Input, etc.
β”‚   β”‚   β”œβ”€β”€ dashboard/      # Dashboard widgets
β”‚   β”‚   β”œβ”€β”€ layout/         # Header, Sidebar, Footer
β”‚   β”‚   β”œβ”€β”€ tasks/          # TaskCard, TaskDetail, TaskForm
β”‚   β”‚   └── workspace/      # Workspace components
β”‚   β”œβ”€β”€ features/           # Feature-based organization
β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”‚   β”œβ”€β”€ authSlice.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ authAPI.ts
β”‚   β”‚   β”‚   └── authHooks.ts
β”‚   β”‚   β”œβ”€β”€ projects/
β”‚   β”‚   β”œβ”€β”€ tasks/
β”‚   β”‚   └── workspaces/
β”‚   β”œβ”€β”€ hooks/              # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ useAuth.ts
β”‚   β”‚   β”œβ”€β”€ useDebounce.ts
β”‚   β”‚   β”œβ”€β”€ useLocalStorage.ts
β”‚   β”‚   └── useRealtime.ts
β”‚   β”œβ”€β”€ lib/                # Third-party configs
β”‚   β”‚   β”œβ”€β”€ firebase.ts
β”‚   β”‚   β”œβ”€β”€ queryClient.ts
β”‚   β”‚   └── store.ts
β”‚   β”œβ”€β”€ pages/              # Page components
β”‚   β”‚   β”œβ”€β”€ Dashboard.tsx
β”‚   β”‚   β”œβ”€β”€ Login.tsx
β”‚   β”‚   β”œβ”€β”€ Project.tsx
β”‚   β”‚   └── Workspace.tsx
β”‚   β”œβ”€β”€ services/           # API services
β”‚   β”‚   β”œβ”€β”€ api.ts
β”‚   β”‚   β”œβ”€β”€ auth.service.ts
β”‚   β”‚   β”œβ”€β”€ project.service.ts
β”‚   β”‚   └── task.service.ts
β”‚   β”œβ”€β”€ types/              # TypeScript types
β”‚   β”‚   β”œβ”€β”€ auth.types.ts
β”‚   β”‚   β”œβ”€β”€ project.types.ts
β”‚   β”‚   └── task.types.ts
β”‚   β”œβ”€β”€ utils/              # Utility functions
β”‚   β”‚   β”œβ”€β”€ date.ts
β”‚   β”‚   β”œβ”€β”€ validation.ts
β”‚   β”‚   └── formatters.ts
β”‚   β”œβ”€β”€ App.tsx
β”‚   β”œβ”€β”€ main.tsx
β”‚   └── router.tsx
β”œβ”€β”€ public/
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ integration/
β”‚   └── utils/
β”œβ”€β”€ .env.example
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ vite.config.ts
└── README.md

πŸ”„ Data Flow Architecture

graph LR A[UI Components] -->|User Actions| B[Redux Store / Zustand] B -->|State Updates| A A -->|API Calls| C[React Query] C -->|Fetch/Mutate| D[Backend Services] D -->|Real-time Events| E[WebSocket/Firebase] E -->|Updates| C C -->|Cache & State| B style A fill:#667eea,stroke:#764ba2,stroke-width:2px,color:#fff style B fill:#48bb78,stroke:#38a169,stroke-width:2px,color:#fff style C fill:#ed8936,stroke:#dd6b20,stroke-width:2px,color:#fff style D fill:#4299e1,stroke:#3182ce,stroke-width:2px,color:#fff style E fill:#9f7aea,stroke:#805ad5,stroke-width:2px,color:#fff

πŸ”’ Authentication Flow

sequenceDiagram participant U as User participant A as App participant Auth as Auth Service participant API as Backend U->>A: Visit protected route A->>Auth: Check authentication Auth-->>A: Not authenticated A->>U: Redirect to login U->>A: Submit credentials A->>Auth: Login request Auth->>API: Validate credentials API-->>Auth: Return token + user Auth->>A: Store token A->>U: Redirect to dashboard U->>A: Request data A->>API: Fetch with token API-->>A: Return data A->>U: Display data

πŸ—οΈ Phase 1: Foundation & Setup (4-6 hours)

Start by setting up your development environment and creating the basic project structure.

βœ… Phase 1 Checklist

Tasks to Complete

  1. Initialize project with Vite + React + TypeScript
  2. Set up Tailwind CSS and configure custom theme
  3. Install and configure all required dependencies
  4. Create folder structure following the architecture
  5. Set up React Router with route configuration
  6. Configure Redux Toolkit or Zustand for state management
  7. Set up TanStack Query (React Query)
  8. Create environment variables setup
  9. Initialize Git repository with .gitignore
  10. Set up ESLint and Prettier for code quality
  11. Create basic layout components (Header, Sidebar, Footer)
  12. Implement theme provider (light/dark mode foundation)

πŸ“ Step-by-Step Setup

Step 1: Create Project

# Create Vite project with React + TypeScript
npm create vite@latest taskflow-pro -- --template react-ts
cd taskflow-pro

# Install dependencies
npm install

# Install additional packages
npm install react-router-dom @tanstack/react-query
npm install @reduxjs/toolkit react-redux  # OR zustand
npm install react-hook-form zod @hookform/resolvers
npm install @dnd-kit/core @dnd-kit/sortable
npm install recharts date-fns
npm install firebase  # OR @supabase/supabase-js

# Install Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

# Install dev dependencies
npm install -D @types/node
npm install -D vitest @testing-library/react @testing-library/jest-dom
npm install -D msw  # for mocking APIs

Step 2: Configure Tailwind CSS

// tailwind.config.js
export default {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#f0f4ff',
          100: '#e0e9ff',
          200: '#c7d7fe',
          300: '#a5b8fc',
          400: '#8192f8',
          500: '#667eea',  // Main brand color
          600: '#5b6cd6',
          700: '#4f58b3',
          800: '#434990',
          900: '#3a3d76',
        },
        // Add more custom colors for your app
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
    },
  },
  plugins: [],
  darkMode: 'class',  // Enable dark mode
};

Step 3: Set Up Router

// src/router.tsx
import { createBrowserRouter, Navigate } from 'react-router-dom';
import { RootLayout } from './components/layout/RootLayout';
import { AuthLayout } from './components/layout/AuthLayout';
import { ProtectedRoute } from './components/auth/ProtectedRoute';

// Page imports
import { LandingPage } from './pages/Landing';
import { LoginPage } from './pages/Login';
import { RegisterPage } from './pages/Register';
import { DashboardPage } from './pages/Dashboard';
import { WorkspacePage } from './pages/Workspace';
import { ProjectPage } from './pages/Project';
import { AnalyticsPage } from './pages/Analytics';
import { SettingsPage } from './pages/Settings';
import { NotFoundPage } from './pages/NotFound';

export const router = createBrowserRouter([
  {
    path: '/',
    element: ,
    children: [
      {
        index: true,
        element: ,
      },
      {
        path: 'auth',
        element: ,
        children: [
          { path: 'login', element:  },
          { path: 'register', element:  },
          { path: 'reset-password', element:  },
        ],
      },
      {
        path: 'app',
        element: ,
        children: [
          { path: 'dashboard', element:  },
          { path: 'workspace/:workspaceId', element:  },
          { path: 'project/:projectId', element:  },
          { path: 'analytics', element:  },
          { path: 'settings', element:  },
        ],
      },
      {
        path: '*',
        element: ,
      },
    ],
  },
]);

Step 4: Create TypeScript Types

// src/types/index.ts

// User types
export interface User {
  id: string;
  email: string;
  name: string;
  avatar?: string;
  createdAt: Date;
  emailVerified: boolean;
}

// Workspace types
export interface Workspace {
  id: string;
  name: string;
  description?: string;
  ownerId: string;
  members: WorkspaceMember[];
  createdAt: Date;
  updatedAt: Date;
}

export interface WorkspaceMember {
  userId: string;
  role: WorkspaceRole;
  joinedAt: Date;
}

export type WorkspaceRole = 'owner' | 'admin' | 'member' | 'viewer';

// Project types
export interface Project {
  id: string;
  workspaceId: string;
  name: string;
  description?: string;
  color?: string;
  status: ProjectStatus;
  lists: List[];
  createdAt: Date;
  updatedAt: Date;
}

export type ProjectStatus = 'active' | 'archived' | 'completed';

// Task types
export interface Task {
  id: string;
  listId: string;
  title: string;
  description?: string;
  assigneeId?: string;
  dueDate?: Date;
  priority: TaskPriority;
  status: TaskStatus;
  labels?: string[];
  position: number;
  createdAt: Date;
  updatedAt: Date;
}

export type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';
export type TaskStatus = 'todo' | 'in-progress' | 'review' | 'done';

// List types
export interface List {
  id: string;
  projectId: string;
  title: string;
  position: number;
  tasks: Task[];
}

// Comment types
export interface Comment {
  id: string;
  taskId: string;
  authorId: string;
  content: string;
  mentions?: string[];
  createdAt: Date;
  updatedAt: Date;
}

// Activity types
export interface Activity {
  id: string;
  workspaceId: string;
  userId: string;
  type: ActivityType;
  entityId: string;
  metadata: Record;
  createdAt: Date;
}

export type ActivityType = 
  | 'task_created'
  | 'task_updated'
  | 'task_completed'
  | 'task_deleted'
  | 'comment_added'
  | 'member_added'
  | 'member_removed'
  | 'project_created';

πŸ’‘ Pro Tip: Environment Variables

Create a .env.example file with all required environment variables:

VITE_FIREBASE_API_KEY=your_api_key_here
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=123456789
VITE_FIREBASE_APP_ID=1:123456789:web:abc123

Create a real .env file with your actual credentials and add it to .gitignore!

βœ… Phase 1 Completion Criteria

⚠️ Before Moving to Phase 2

Ensure you have:

  • βœ… Project running locally without errors
  • βœ… Routing working (can navigate between pages)
  • βœ… Tailwind CSS styles applying correctly
  • βœ… TypeScript configured with no errors
  • βœ… All major dependencies installed
  • βœ… Basic layout components created (Header, Footer)
  • βœ… Environment variables configured
  • βœ… Git repository initialized with first commit

πŸ” Phase 2: Authentication & User Management (6-8 hours)

Build a complete authentication system with registration, login, password reset, and protected routes.

βœ… Phase 2 Checklist

Tasks to Complete

  1. Set up Firebase Authentication or Supabase Auth
  2. Create registration form with validation
  3. Create login form with validation
  4. Implement email verification flow
  5. Create password reset flow
  6. Build protected route component
  7. Implement auth state management
  8. Create user profile page
  9. Add avatar upload functionality
  10. Build account settings page
  11. Add logout functionality
  12. Write tests for auth flows

πŸ“ Implementation Guide

Authentication Service

// src/services/auth.service.ts
import { 
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
  sendEmailVerification,
  sendPasswordResetEmail,
  updateProfile,
  User as FirebaseUser
} from 'firebase/auth';
import { auth } from '../lib/firebase';
import type { User } from '../types';

class AuthService {
  async register(email: string, password: string, name: string): Promise {
    const userCredential = await createUserWithEmailAndPassword(
      auth,
      email,
      password
    );
    
    await updateProfile(userCredential.user, { displayName: name });
    await sendEmailVerification(userCredential.user);
    
    return this.mapFirebaseUser(userCredential.user);
  }

  async login(email: string, password: string): Promise {
    const userCredential = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );
    return this.mapFirebaseUser(userCredential.user);
  }

  async logout(): Promise {
    await signOut(auth);
  }

  async resetPassword(email: string): Promise {
    await sendPasswordResetEmail(auth, email);
  }

  async verifyEmail(): Promise {
    const user = auth.currentUser;
    if (user) {
      await sendEmailVerification(user);
    }
  }

  getCurrentUser(): User | null {
    const firebaseUser = auth.currentUser;
    return firebaseUser ? this.mapFirebaseUser(firebaseUser) : null;
  }

  private mapFirebaseUser(firebaseUser: FirebaseUser): User {
    return {
      id: firebaseUser.uid,
      email: firebaseUser.email!,
      name: firebaseUser.displayName || '',
      avatar: firebaseUser.photoURL || undefined,
      createdAt: new Date(firebaseUser.metadata.creationTime!),
      emailVerified: firebaseUser.emailVerified,
    };
  }
}

export const authService = new AuthService();

Registration Form Component

// src/components/auth/RegisterForm.tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useNavigate } from 'react-router-dom';
import { authService } from '../../services/auth.service';

const registerSchema = z.object({
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters')
    .regex(/[A-Z]/, 'Password must contain an uppercase letter')
    .regex(/[0-9]/, 'Password must contain a number'),
  confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
  message: "Passwords don't match",
  path: ['confirmPassword'],
});

type RegisterFormData = z.infer;

export function RegisterForm() {
  const navigate = useNavigate();
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
    setError,
  } = useForm({
    resolver: zodResolver(registerSchema),
  });

  const onSubmit = async (data: RegisterFormData) => {
    try {
      await authService.register(data.email, data.password, data.name);
      // Show success message about email verification
      navigate('/auth/verify-email');
    } catch (error: any) {
      setError('root', {
        message: error.message || 'Failed to create account',
      });
    }
  };

  return (
    
{errors.name && (

{errors.name.message}

)}
{errors.email && (

{errors.email.message}

)}
{errors.password && (

{errors.password.message}

)}
{errors.confirmPassword && (

{errors.confirmPassword.message}

)}
{errors.root && (

{errors.root.message}

)}
); }

Protected Route Component

// src/components/auth/ProtectedRoute.tsx
import { Navigate, Outlet } from 'react-router-dom';
import { useAuth } from '../../hooks/useAuth';
import { LoadingSpinner } from '../common/LoadingSpinner';

export function ProtectedRoute() {
  const { user, isLoading } = useAuth();

  if (isLoading) {
    return (
      
); } if (!user) { return ; } if (!user.emailVerified) { return ; } return ; }

⚠️ Security Best Practices

  • Never store passwords in plain text: Use Firebase/Supabase which handles this
  • Implement rate limiting: Prevent brute force attacks on login
  • Require email verification: Confirm users own the email address
  • Use HTTPS only: Ensure deployment uses SSL/TLS
  • Store tokens securely: Use httpOnly cookies when possible
  • Implement logout everywhere: Allow users to sign out of all devices

βœ… Phase 2 Completion Criteria

Before Moving to Phase 3

  • βœ… Users can register new accounts
  • βœ… Email verification is sent and checked
  • βœ… Users can log in with email/password
  • βœ… Password reset flow works end-to-end
  • βœ… Protected routes redirect unauthenticated users
  • βœ… User profile displays current user info
  • βœ… Users can upload/change avatar
  • βœ… Logout works and clears session
  • βœ… Form validation provides clear error messages
  • βœ… Auth state persists across page refreshes

πŸ“Š Phase 3: Core Features (10-12 hours)

Build the heart of your application: workspaces, projects, and the Kanban board with drag-and-drop functionality.

βœ… Phase 3 Checklist

Tasks to Complete

  1. Create workspace creation wizard/form
  2. Build workspace list and dashboard
  3. Implement workspace member invitation system
  4. Create role-based permission system
  5. Build project creation form
  6. Create project list view with cards
  7. Implement Kanban board layout
  8. Add drag-and-drop for tasks and lists
  9. Create task creation form (quick add + detailed)
  10. Build task detail modal/sidebar
  11. Implement task editing and deletion
  12. Add task assignment functionality
  13. Create due date picker component
  14. Implement priority indicators
  15. Add task filtering and search

🏒 Workspace Management Implementation

Workspace Creation Form

// src/components/workspace/CreateWorkspaceForm.tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { workspaceService } from '../../services/workspace.service';

const workspaceSchema = z.object({
  name: z.string()
    .min(3, 'Name must be at least 3 characters')
    .max(50, 'Name must be less than 50 characters'),
  description: z.string()
    .max(500, 'Description must be less than 500 characters')
    .optional(),
});

type WorkspaceFormData = z.infer;

interface CreateWorkspaceFormProps {
  onSuccess?: (workspaceId: string) => void;
  onCancel?: () => void;
}

export function CreateWorkspaceForm({ onSuccess, onCancel }: CreateWorkspaceFormProps) {
  const queryClient = useQueryClient();
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(workspaceSchema),
  });

  const createMutation = useMutation({
    mutationFn: workspaceService.create,
    onSuccess: (workspace) => {
      queryClient.invalidateQueries({ queryKey: ['workspaces'] });
      onSuccess?.(workspace.id);
    },
  });

  const onSubmit = (data: WorkspaceFormData) => {
    createMutation.mutate(data);
  };

  return (
    
{errors.name && (

{errors.name.message}

)}