File size: 3,267 Bytes
90f0c0b 76a77bc 90f0c0b 76a77bc 6a144bd acceac1 6a144bd 76a77bc 57c296e 90f0c0b 76a77bc 90f0c0b b811a8f 90f0c0b b811a8f 90f0c0b 76a77bc acceac1 90f0c0b c1209d2 76a77bc c1209d2 76a77bc c1209d2 90f0c0b b811a8f 6a144bd 90f0c0b acceac1 6a144bd 90f0c0b b811a8f 90f0c0b b811a8f 90f0c0b b811a8f 76a77bc 90f0c0b 57c296e 90f0c0b b811a8f 6a144bd b811a8f 90f0c0b b811a8f 90f0c0b b811a8f 76a77bc b811a8f 90f0c0b b811a8f 6a144bd c1209d2 76a77bc acceac1 76a77bc b811a8f 6a144bd b811a8f 6a144bd b811a8f 76a77bc 57c296e b811a8f 6a144bd acceac1 |
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
import React, { useState, type FormEvent } from "react";
import { Mail, Lock, LogIn } from "lucide-react";
import API from "../../api/api";
import { useAuth } from "../context/AuthContext";
interface SignInProps {
onSwitchToSignUp: () => void;
}
const SignIn: React.FC<SignInProps> = ({ onSwitchToSignUp }) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const { login } = useAuth();
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
setError("");
try {
const res = await API.post("/auth/login", { email, password });
// ✅ UPDATED: Pass token to login() to persist session
login(
res.data.username || res.data.user?.username || "User",
res.data.access_token
);
} catch (err: any) {
console.error("Login error:", err);
let errorMessage = "Login failed.";
if (err.response?.data?.detail) {
const detail = err.response.data.detail;
if (typeof detail === "string") errorMessage = detail;
else if (Array.isArray(detail)) {
const first = detail[0];
errorMessage = `${first.loc.join(" -> ")}: ${first.msg}`;
}
}
setError(errorMessage);
}
};
return (
<>
<h2 className="text-3xl font-bold mb-8 text-center text-white">
Welcome Back
</h2>
{error && <p className="text-red-400 text-center mb-3">{error}</p>}
<form className="space-y-5" onSubmit={handleSubmit}>
<div>
<label className="block text-sm mb-1 text-gray-300">Email</label>
<div className="relative">
<Mail className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
<input
type="text"
placeholder="username or email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
required
/>
</div>
</div>
<div>
<label className="block text-sm mb-1 text-gray-300">Password</label>
<div className="relative">
<Lock className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
<input
type="password"
placeholder="••••••••"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
required
/>
</div>
</div>
<button
type="submit"
className="w-full px-5 py-3 rounded-lg bg-gradient-to-r from-blue-500 to-gray-500 text-white flex items-center justify-center gap-2"
>
<LogIn className="w-5 h-5" />
Sign In
</button>
</form>
<p className="mt-8 text-center text-sm text-gray-400">
Don’t have an account?{" "}
<button onClick={onSwitchToSignUp} className="ml-2 text-blue-400">
Sign Up
</button>
</p>
</>
);
};
export default SignIn;
|