Day23我們就來做筆記管理工具Note Manager」吧
新增一個NoteManager
import { useState, useEffect } from "react"
export default function NoteManager() {
const [notes, setNotes] = useState([])
const [title, setTitle] = useState("")
const [content, setContent] = useState("")
const [search, setSearch] = useState("")
// 讀取 localStorage
useEffect(() => {
const saved = JSON.parse(localStorage.getItem("notes") || "[]")
setNotes(saved)
}, [])
// 自動儲存
useEffect(() => {
localStorage.setItem("notes", JSON.stringify(notes))
}, [notes])
const addNote = () => {
if (!title.trim() || !content.trim()) return
const newNote = {
id: Date.now(),
title,
content,
date: new Date().toLocaleString(),
}
setNotes([newNote, ...notes])
setTitle("")
setContent("")
}
const deleteNote = (id) => {
setNotes(notes.filter((n) => n.id !== id))
}
const filteredNotes = notes.filter(
(n) =>
n.title.toLowerCase().includes(search.toLowerCase()) ||
n.content.toLowerCase().includes(search.toLowerCase())
)
return (
<div className="space-y-6">
<h2 className="text-2xl font-bold">🗒️ 筆記管理工具</h2>
{/* 新增筆記區 */}
<div className="bg-white p-4 rounded shadow space-y-3">
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="筆記標題"
className="w-full border px-3 py-2 rounded"
/>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="筆記內容..."
rows="4"
className="w-full border px-3 py-2 rounded"
/>
<button
onClick={addNote}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
>
新增筆記
</button>
</div>
{/* 搜尋欄 */}
<div>
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="搜尋筆記..."
className="w-full border px-3 py-2 rounded"
/>
</div>
{/* 筆記列表 */}
<div className="space-y-3">
{filteredNotes.length === 0 ? (
<p className="text-gray-500">目前沒有筆記。</p>
) : (
filteredNotes.map((n) => (
<div
key={n.id}
className="bg-white p-4 rounded shadow flex justify-between items-start"
>
<div>
<h3 className="text-lg font-semibold">{n.title}</h3>
<p className="text-gray-700 whitespace-pre-wrap">
{n.content}
</p>
<p className="text-xs text-gray-400 mt-1">{n.date}</p>
</div>
<button
onClick={() => deleteNote(n.id)}
className="text-red-600 hover:text-red-800 text-sm"
>
刪除
</button>
</div>
))
)}
</div>
</div>
)
}
然後接著在layout中加入筆記工具這個功能
import { useState } from "react"
import TodoApp from "./TodoApp"
import ChatBox from "./ChatBox"
import TranslationTool from "./TranslationTool"
import NoteManager from "./NoteManager" // ← 新增
export default function Layout() {
const [active, setActive] = useState("todo")
return (
<div className="min-h-screen flex">
<aside className="w-64 bg-gray-800 text-white p-6 space-y-4">
<h2 className="text-xl font-bold mb-6">AI工具箱</h2>
<nav className="space-y-2">
{[
["todo", "待辦清單"],
["chat", "Chat工具"],
["translate", "翻譯工具"],
["notes", "筆記工具"], // ← 新增
].map(([key, label]) => (
<button
key={key}
className={`block w-full text-left px-3 py-2 rounded ${
active === key ? "bg-blue-600" : "hover:bg-gray-700"
}`}
onClick={() => setActive(key)}
>
{label}
</button>
))}
</nav>
</aside>
<main className="flex-1 bg-gray-50 p-6">
{active === "todo" && <TodoApp />}
{active === "chat" && <ChatBox />}
{active === "translate" && <TranslationTool />}
{active === "notes" && <NoteManager />} {/* ← 新增 */}
</main>
</div>
)
}