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;