aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/Login.tsx
blob: 2e8bbf7069dea85765d36c623e03a7c17ccef312 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { useState, type FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import './Login.css';

export default function Login() {
    const [password, setPassword] = useState('');
    const [error, setError] = useState('');
    const navigate = useNavigate();

    const handleSubmit = async (e: FormEvent) => {
        e.preventDefault();
        setError('');

        try {
            // Use URLSearchParams to send as form-urlencoded, matching backend expectation
            const params = new URLSearchParams();
            params.append('password', password);

            const res = await fetch('/api/login', {
                method: 'POST',
                body: params,
            });

            if (res.ok) {
                navigate('/');
            } else {
                const data = await res.json();
                setError(data.message || 'Login failed');
            }
        } catch (err) {
            setError('Network error');
        }
    };

    return (
        <div className="login-container">
            <form onSubmit={handleSubmit} className="login-form">
                <h1>neko rss mode</h1>
                <div className="form-group">
                    <label htmlFor="password">password</label>
                    <input
                        id="password"
                        type="password"
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        autoFocus
                    />
                </div>
                {error && <div className="error-message">{error}</div>}
                <button type="submit">login</button>
            </form>
        </div>
    );
}