File size: 4,962 Bytes
90f0c0b c1209d2 6a144bd 90f0c0b c1209d2 6a144bd 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 76a77bc c1209d2 90f0c0b c1209d2 90f0c0b c1209d2 90f0c0b 6a144bd |
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 |
import React, { useState } from "react";
import { User, Mail, Lock, UserPlus } from "lucide-react";
import API from "../../api/api"; // Assuming the API file is one directory up
interface SignUpProps {
onClose: () => void;
onSwitchToSignIn: () => void;
onAuthSuccess: (username: 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. Registration via API (uses axios and the correct base URL)
await API.post("/auth/register", {
username,
email,
password,
});
// 2. Login immediately after successful registration
const loginResponse = await API.post("/auth/login", {
email,
password,
});
// The response data is directly on response.data when using axios
const loginData = loginResponse.data;
localStorage.setItem("token", loginData.access_token);
const loggedInUsername = loginData.username;
onAuthSuccess(loggedInUsername);
} catch (err: any) {
console.error("Registration/Login error:", err);
// Axios error handling: Check for response data and detail for custom error message
let errorMessage = "Registration failed";
if (err.response && err.response.data && err.response.data.detail) {
// Extracts the specific error detail from FastAPI (e.g., 'Username already registered')
errorMessage = err.response.data.detail;
} else if (err.message) {
// Use generic network or request error 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-linear-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; |