Implement user authentication and account pages
Adds AuthContext with Orval API integration, user login/logout/register flows, and account settings page. Refactors navigation and layouts to use authentication context. Introduces new account-related pages (Login, Register, Logout, AccountSettings), updates PrivateRoute to use AuthContext, and improves error handling in Downloader. Removes obsolete context example and adds comprehensive usage documentation for AuthContext.
This commit is contained in:
108
frontend/src/pages/account/Login.tsx
Normal file
108
frontend/src/pages/account/Login.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import { useState } from "react";
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
import { useNavigate, Link } from "react-router-dom";
|
||||
import { FaEnvelope, FaLock, FaSpinner } from "react-icons/fa";
|
||||
|
||||
export default function LoginPage() {
|
||||
const { login, isLoading } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
|
||||
if (!username.trim() || !password.trim()) {
|
||||
setError("Vyplňte prosím všechna pole");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await login({ username, password });
|
||||
navigate("/");
|
||||
} catch (err: any) {
|
||||
const errorMessage = err.response?.data?.error || err.message;
|
||||
setError(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100 p-4">
|
||||
<div className="bg-white rounded-lg shadow-xl p-8 w-full max-w-md">
|
||||
<h1 className="text-3xl font-bold text-center mb-2 text-gray-800">Přihlášení</h1>
|
||||
<p className="text-center text-gray-600 mb-8">Vítejte zpět na vontor.cz</p>
|
||||
|
||||
{error && (
|
||||
<div className="mb-6 p-4 bg-red-50 border border-red-200 text-red-700 rounded-lg">
|
||||
<strong>Chyba:</strong> {error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div>
|
||||
<label className="block mb-2 font-medium text-gray-700 flex items-center gap-2">
|
||||
<FaEnvelope className="text-gray-500" />
|
||||
Email nebo uživatelské jméno
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
placeholder="email@example.com nebo username"
|
||||
className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
||||
disabled={isLoading}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block mb-2 font-medium text-gray-700 flex items-center gap-2">
|
||||
<FaLock className="text-gray-500" />
|
||||
Heslo
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="••••••••"
|
||||
className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
||||
disabled={isLoading}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<Link to="/password-reset" className="text-blue-600 hover:text-blue-800 hover:underline">
|
||||
Zapomenuté heslo?
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="w-full bg-blue-600 text-white py-3 rounded-lg font-semibold hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition flex items-center justify-center gap-2"
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<FaSpinner className="animate-spin" />
|
||||
Přihlašování...
|
||||
</>
|
||||
) : (
|
||||
"Přihlásit se"
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-gray-600">
|
||||
Ještě nemáte účet?{" "}
|
||||
<Link to="/register" className="text-blue-600 hover:text-blue-800 font-semibold hover:underline">
|
||||
Zaregistrujte se
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user