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;