DDevArchive
Đăng nhập

Dự án Giai đoạn 1: Todo App hoàn chỉnh + đẩy lên GitHub Pages

Tổng hợp toàn bộ kiến thức: HTML cấu trúc, CSS giao diện responsive, JavaScript DOM + event + localStorage. Bạn sẽ xây Todo App hoàn chỉnh từ đầu, rồi đẩy lên GitHub Pages để có URL thật khoe với mọi người.

Bước 1 — HTML: bộ khung

Tạo file index.html với form thêm việc, danh sách hiển thị, và bộ lọc (Tất cả / Chưa xong / Đã xong). Dùng semantic HTML.

// File: index.html
<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Todo App — Dự án Foundation</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="app">
    <h1>📝 Todo App</h1>
    <form id="todoForm">
      <input type="text" id="todoInput" placeholder="Thêm việc cần làm..." required>
      <button type="submit">Thêm</button>
    </form>
    <div class="filters">
      <button class="active" data-filter="all">Tất cả</button>
      <button data-filter="active">Chưa xong</button>
      <button data-filter="done">Đã xong</button>
    </div>
    <ul id="todoList"></ul>
    <p class="count"><span id="count">0</span> việc còn lại</p>
  </main>
  <script src="app.js"></script>
</body>
</html>

Bước 2 — CSS: giao diện responsive

Style gọn gàng, có dark mode toggle, card bóng đổ, transition mượt khi thêm/xoá việc.

// File: style.css
* { box-sizing: border-box; margin: 0; }

body {
  font-family: "Inter", sans-serif;
  background: #f0f2f5;
  display: flex;
  justify-content: center;
  padding: 40px 16px;
}

.app {
  background: #fff;
  border-radius: 16px;
  padding: 32px;
  width: 100%;
  max-width: 480px;
  box-shadow: 0 8px 32px rgba(0,0,0,.08);
}

#todoForm {
  display: flex;
  gap: 8px;
  margin: 20px 0;
}

#todoForm input { flex: 1; padding: 10px 14px; border: 1px solid #dee2e6; border-radius: 8px; }
#todoForm button { padding: 10px 20px; background: #6c5ce7; color: #fff; border: none; border-radius: 8px; cursor: pointer; }

Bước 3 — JavaScript: logic + localStorage

// File: app.js
const STORAGE_KEY = "todos"

function load() {
  const raw = localStorage.getItem(STORAGE_KEY)
  return raw ? JSON.parse(raw) : []
}

function save(todos) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
}

let todos = load()
let filter = "all"

function render() {
  const list = document.querySelector("#todoList")
  const filtered = todos.filter(t =>
    filter === "all" ? true :
    filter === "done" ? t.done : !t.done
  )

  list.innerHTML = filtered.map(t => `
    <li class="${t.done ? "done" : ""}">
      <input type="checkbox" ${t.done ? "checked" : ""}
        onchange="toggle(${t.id})">
      <span>${t.title}</span>
      <button onclick="remove(${t.id})">✕</button>
    </li>
  `).join("")

  document.querySelector("#count").textContent = todos.filter(t => !t.done).length
}

document.querySelector("#todoForm").addEventListener("submit", (e) => {
  e.preventDefault()
  const input = document.querySelector("#todoInput")
  if (!input.value.trim()) return
  todos.push({ id: Date.now(), title: input.value.trim(), done: false })
  input.value = ""
  save(todos)
  render()
})

Bước 4 — Đẩy lên GitHub Pages

Tạo repo trên GitHub, git init, commit, push. Vào Settings → Pages → chọn branch main. Sau 1 phút bạn có URL thật để gửi cho mọi người.

BướcLệnh / thao tácKết quả
Tạo repogithub.com → New repositoryRepo rỗng trên GitHub
Đẩy codegit init → add → commit → pushCode lên remote
Bật PagesSettings → Pages → branch mainCó URL https://you.github.io/repo
Kiểm thửMở URL từ điện thoạiAi cũng truy cập được

❓ Dự án web tĩnh đẩy lên GitHub Pages, ai "chạy" server trả về trang web cho người truy cập?

  • Hoàn thành Todo App với HTML semantic
  • Style responsive với CSS Flexbox
  • Logic JS đầy đủ: thêm, xoá, toggle, filter
  • Lưu dữ liệu bằng localStorage
  • Push lên GitHub và bật GitHub Pages