Step3: 基本機能(追加,更新,削除)実装

This commit is contained in:
2025-06-30 16:42:12 +09:00
parent a6ff1b3ff5
commit a121cc9dfe

View File

@@ -17,6 +17,41 @@ export default function Home() {
{ id: 3, text: "TODOアプリを作る", completed: false }, { id: 3, text: "TODOアプリを作る", completed: false },
]); ]);
// 入力中のテキストを管理
const [inputText, setInputText] = useState("");
// TODO追加機能
const handleAddTodo = (e: React.FormEvent) => {
e.preventDefault(); // フォームのデフォルト動作を防ぐ
if (inputText.trim() === "") {
return; // 空文字の場合は追加しない
}
const newTodo: Todo = {
id: Date.now(), // 簡易的なID生成
text: inputText,
completed: false,
};
setTodos([...todos, newTodo]); // 新しいTODOを配列に追加
setInputText(""); // 入力欄をクリア
};
// TODO完了状態の切り替え機能
const handleToggleTodo = (id: number) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
// TODO削除機能
const handleDeleteTodo = (id: number) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
return ( return (
<main className="min-h-screen p-8 bg-gray-50 dark:bg-gray-900"> <main className="min-h-screen p-8 bg-gray-50 dark:bg-gray-900">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
@@ -26,9 +61,11 @@ export default function Home() {
{/* TODO入力フォーム */} {/* TODO入力フォーム */}
<div className="mb-8"> <div className="mb-8">
<form className="flex gap-2"> <form onSubmit={handleAddTodo} className="flex gap-2">
<input <input
type="text" type="text"
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="新しいTODOを入力..." placeholder="新しいTODOを入力..."
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100" className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100"
/> />
@@ -51,6 +88,7 @@ export default function Home() {
<input <input
type="checkbox" type="checkbox"
checked={todo.completed} checked={todo.completed}
onChange={() => handleToggleTodo(todo.id)}
className="w-5 h-5 text-blue-500 rounded focus:ring-2 focus:ring-blue-500" className="w-5 h-5 text-blue-500 rounded focus:ring-2 focus:ring-blue-500"
/> />
<span <span
@@ -62,7 +100,10 @@ export default function Home() {
> >
{todo.text} {todo.text}
</span> </span>
<button className="px-3 py-1 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors"> <button
onClick={() => handleDeleteTodo(todo.id)}
className="px-3 py-1 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors"
>
</button> </button>
</div> </div>