diff --git a/src/app/page.tsx b/src/app/page.tsx index f99948c..4e56834 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; // useEffectを追加 // Todo型の定義 type Todo = { @@ -12,6 +12,9 @@ type Todo = { type FilterType = 'all' | 'active' | 'completed'; // フィルターの種類。全て、未完了、完了の3種類。 export default function Home() { + // Local Storage のキー + const STORAGE_KEY = 'todo-app-data'; + // Todoリスト本体の状態管理 const [todos, setTodos] = useState([]); // Todo配列を保持 @@ -141,11 +144,78 @@ export default function Home() { setShowInputAlert(false); // 警告ダイアログを閉じる }; + // アプリ起動時にデータを読み込み + useEffect(() => { + const savedTodos = localStorage.getItem(STORAGE_KEY); + if (savedTodos) { + try { + const parsedTodos = JSON.parse(savedTodos); + setTodos(parsedTodos); + } catch (error) { + console.error('データの読み込みに失敗しました:', error); + } + } + }, []); // 空の依存配列で初回のみ実行 + + // TODOが変更されるたびに保存 + useEffect(() => { + localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)); + }, [todos]); // todosが変更されるたびに実行 + + // データのエクスポート機能 + const exportData = () => { + const dataStr = JSON.stringify(todos, null, 2); + const dataBlob = new Blob([dataStr], { type: 'application/json' }); + const url = URL.createObjectURL(dataBlob); + const link = document.createElement('a'); + link.href = url; + link.download = 'todos.json'; + link.click(); + URL.revokeObjectURL(url); + }; + + // データのインポート機能 + const importData = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + const reader = new FileReader(); + reader.onload = (e) => { + try { + const importedTodos = JSON.parse(e.target?.result as string); + setTodos(importedTodos); + } catch (error) { + alert('ファイルの読み込みに失敗しました'); + } + }; + reader.readAsText(file); + } + }; + // JSX: 実際に表示されるUI定義 return (
{/* 全体の背景や余白 */}
{/* カード風の白背景 */} -

TODOアプリ

{/* タイトル */} + {/* ヘッダー部分にエクスポート・インポート機能を追加 */} +
+

TODOアプリ

+
+ + +
+
{/* 入力フォーム */}
{/* フォーム全体のスタイル */}