/** * ユーザーログイン機能を提供するページコンポーネント * ユーザー名とパスワードによる認証フォームを表示し、認証APIと連携 */ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Container, Box, Typography, TextField, Button, Paper, Alert, Link, Grid, } from '@mui/material'; import { LoginCredentials } from '../types/types'; import { authApi } from '../services/api'; import { GENERAL_ERRORS } from '../constants/errorMessages'; const LoginPage: React.FC = () => { const navigate = useNavigate(); // ログイン情報の状態管理 const [credentials, setCredentials] = useState({ username: '', password: '', }); // エラーメッセージの状態管理 const [error, setError] = useState(''); /** * フォーム入力値の変更を処理するハンドラー * 入力フィールドの変更をcredentials状態に反映 */ const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setCredentials(prev => ({ ...prev, [name]: value, // 動的にプロパティ名を使用して状態を更新 })); }; /** * ログインフォームの送信を処理するハンドラー * 認証APIを呼び出し、成功時はトークンを保存してタスク一覧ページに遷移 * 失敗時はエラーメッセージを表示 */ const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // フォームのデフォルト送信動作を防止 try { const response = await authApi.login(credentials); localStorage.setItem('token', response.token); // 認証トークンをローカルストレージに保存 navigate('/tasks'); // タスク一覧ページにリダイレクト } catch (err) { setError(err instanceof Error ? err.message : GENERAL_ERRORS.UNEXPECTED_ERROR); } }; return ( ToDoアプリ ログイン {/* エラーがある場合のみアラートを表示 */} {error && ( {error} )} {/* ログインフォーム */} {/* ユーザー名入力フィールド */} {/* パスワード入力フィールド */} {/* ログインボタン */} {/* 新規登録ページへのリンク */} アカウントをお持ちでない方はこちら ); }; export default LoginPage;