File size: 4,767 Bytes
90f0c0b c1209d2 23c3caf 6a144bd 90f0c0b 23c3caf 6a144bd 90f0c0b c1209d2 90f0c0b 23c3caf 90f0c0b c1209d2 90f0c0b 23c3caf c1209d2 90f0c0b 23c3caf fcb1d4c 23c3caf 90f0c0b c1209d2 23c3caf c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 23c3caf c1209d2 90f0c0b c1209d2 90f0c0b 23c3caf 90f0c0b 6a144bd 23c3caf |
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
import React, { useState } from "react";
import { User, Mail, Lock, UserPlus } from "lucide-react";
import API from "../../api/api";
interface SignUpProps {
onClose: () => void;
onSwitchToSignIn: () => void;
// ✅ UPDATED: Signature now includes token
onAuthSuccess: (username: string, token: string) => void;
}
const SignUp: React.FC<SignUpProps> = ({ onSwitchToSignIn, onAuthSuccess }) => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirm, setConfirm] = useState("");
const [error, setError] = useState("");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
if (password !== confirm) {
return setError("Passwords do not match.");
}
try {
// 1. Register via API
await API.post("/auth/register", {
username,
email,
password,
});
// 2. Login immediately after to get the token
const loginResponse = await API.post("/auth/login", {
email,
password,
});
// Extract token and username
const { access_token, username: loggedInUser } = loginResponse.data;
// 3. Pass both to the parent handler
// This ensures the AuthContext gets the token to persist the session
onAuthSuccess(loggedInUser, access_token);
} catch (err: any) {
console.error("Registration/Login error:", err);
let errorMessage = "Registration failed";
// Handle FastAPI error details
if (err.response && err.response.data && err.response.data.detail) {
errorMessage = err.response.data.detail;
} else if (err.message) {
errorMessage = err.message;
}
setError(errorMessage);
}
};
return (
<>
<h2 className="text-3xl font-bold mb-8 text-center text-white">
Create Your Account
</h2>
{error && <p className="text-red-400 text-center mb-3">{error}</p>}
<div className="space-y-5">
<div>
<label className="text-gray-300">Username</label>
<div className="relative">
<User className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
<input
value={username}
onChange={(e) => setUsername(e.target.value)}
type="text"
className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
required
/>
</div>
</div>
<div>
<label className="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="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="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"
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>
<div>
<label className="text-gray-300">Confirm 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"
value={confirm}
onChange={(e) => setConfirm(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
onClick={handleSubmit}
className="w-full px-5 py-3 rounded-lg bg-gradient-to-r from-blue-500 to-purple-500 text-white flex items-center justify-center gap-2 hover:from-blue-600 hover:to-purple-600 transition"
>
<UserPlus className="w-5 h-5" />
Sign Up
</button>
</div>
<p className="mt-8 text-center text-sm text-gray-400">
Already have an account?
<button
onClick={onSwitchToSignIn}
className="text-blue-400 ml-2 hover:underline"
>
Sign In
</button>
</p>
</>
);
};
export default SignUp;
|