10 minlesson

Capstone Projects Overview

Capstone Projects

Apply everything you've learned by building three progressively challenging projects.

Project Overview

ProjectDifficultyCore Concepts
Todo ApplicationBeginnerDOM, Events, localStorage, Classes
Real-Time DashboardIntermediateAsync/Await, Promises, API Integration
Mini FrameworkAdvancedProxy, WeakMap, Generators, Modules

Project 1: Todo Application

Build a fully-featured todo list with:

  • CRUD Operations: Create, read, update, delete todos
  • Filtering: View all, active, or completed todos
  • Persistence: Save to localStorage
  • Responsive UI: Clean, functional interface

Concepts Applied

javascript
1// Class-based architecture
2class TodoApp {
3 constructor(container) {
4 this.container = container;
5 this.todos = this.loadTodos();
6 this.filter = 'all';
7 this.render();
8 }
9
10 // DOM manipulation
11 render() {
12 const fragment = document.createDocumentFragment();
13 this.getFilteredTodos().forEach(todo => {
14 fragment.appendChild(this.createTodoElement(todo));
15 });
16 this.container.replaceChildren(fragment);
17 }
18
19 // Event delegation
20 bindEvents() {
21 this.container.addEventListener('click', (e) => {
22 if (e.target.matches('.delete-btn')) {
23 this.deleteTodo(e.target.closest('[data-id]').dataset.id);
24 }
25 });
26 }
27
28 // localStorage persistence
29 saveTodos() {
30 localStorage.setItem('todos', JSON.stringify(this.todos));
31 }
32}

Learning Goals

  • Class-based application architecture
  • DOM manipulation and event handling
  • State management with persistence
  • Clean separation of concerns

Project 2: Real-Time Dashboard

Build a dashboard displaying data from multiple APIs:

  • Multi-API Integration: Fetch from multiple endpoints
  • Real-Time Updates: Auto-refresh with intervals
  • Error Handling: Retry failed requests, show errors gracefully
  • Loading States: Visual feedback during fetches

Concepts Applied

javascript
1// Async data fetching
2class Dashboard {
3 async fetchAllData() {
4 const results = await Promise.allSettled([
5 this.fetchUsers(),
6 this.fetchStats(),
7 this.fetchNotifications()
8 ]);
9
10 return results.map((result, i) => ({
11 source: this.dataSources[i],
12 status: result.status,
13 data: result.value,
14 error: result.reason
15 }));
16 }
17
18 // Retry logic
19 async fetchWithRetry(url, retries = 3) {
20 for (let i = 0; i < retries; i++) {
21 try {
22 const response = await fetch(url);
23 if (!response.ok) throw new Error(response.status);
24 return await response.json();
25 } catch (error) {
26 if (i === retries - 1) throw error;
27 await this.delay(1000 * (i + 1)); // Exponential backoff
28 }
29 }
30 }
31
32 // Real-time updates
33 startAutoRefresh(interval = 30000) {
34 this.refreshInterval = setInterval(() => {
35 this.refresh();
36 }, interval);
37 }
38}

Learning Goals

  • Promise.all and Promise.allSettled
  • Error handling and retry patterns
  • Interval-based updates
  • Managing loading and error states

Project 3: Mini Framework

Build a reactive mini-framework with:

  • Reactive State: Proxy-based state management
  • Component System: Reusable component classes
  • Data Binding: Auto-update DOM when state changes
  • Module Architecture: Clean imports/exports

Concepts Applied

javascript
1// Reactive state with Proxy
2function reactive(target, onChange) {
3 return new Proxy(target, {
4 set(obj, prop, value) {
5 const oldValue = obj[prop];
6 obj[prop] = value;
7 onChange(prop, value, oldValue);
8 return true;
9 }
10 });
11}
12
13// Component base class
14class Component {
15 #state;
16 #element;
17 #subscriptions = new WeakMap();
18
19 constructor(element) {
20 this.#element = element;
21 this.#state = reactive({}, () => this.render());
22 }
23
24 get state() { return this.#state; }
25
26 setState(updates) {
27 Object.assign(this.#state, updates);
28 }
29
30 render() {
31 // Override in subclass
32 }
33}
34
35// Generator for unique IDs
36function* idGenerator(prefix = 'id') {
37 let id = 0;
38 while (true) {
39 yield `${prefix}_${id++}`;
40 }
41}

Learning Goals

  • Proxy for reactivity
  • WeakMap for private component data
  • Generators for sequences
  • Module organization

Common Requirements

All projects should demonstrate:

Code Quality

javascript
1// Clear naming
2const addTodo = (text) => { /* ... */ };
3const toggleComplete = (id) => { /* ... */ };
4
5// Proper error handling
6try {
7 await saveData(data);
8} catch (error) {
9 showError('Failed to save');
10 console.error(error);
11}
12
13// Type-safe operations
14const count = items?.length ?? 0;
15const name = user?.profile?.name || 'Anonymous';

Project Structure

1project/
2├── index.html
3├── main.js # Entry point
4├── styles.css # Styles
5└── modules/
6 ├── app.js # Main application class
7 ├── storage.js # localStorage utilities
8 └── utils.js # Helper functions

User Experience

  • Clear visual feedback for actions
  • Loading states during async operations
  • Error messages that help users
  • Accessible keyboard navigation

Assessment Criteria

Your projects will be evaluated on:

  1. Functionality - Does it work correctly?
  2. Code Organization - Is it well-structured?
  3. ES6+ Features - Are modern features used appropriately?
  4. Error Handling - Are edge cases handled?
  5. User Experience - Is it pleasant to use?

Getting Started

Choose a project that matches your current skill level:

  • Beginner: Start with the Todo App
  • Confident: Try the Dashboard
  • Ambitious: Tackle the Mini Framework

Each project builds on skills from the previous one. You can complete them in order or jump to your challenge level.

Good luck! Apply what you've learned and build something great.