()
| 25 | }; |
| 26 | |
| 27 | export default function Signup() { |
| 28 | const navigate = useNavigate(); |
| 29 | const [searchParams] = useSearchParams(); |
| 30 | const message = searchParams.get('message'); |
| 31 | const [name, setName] = useState(""); |
| 32 | const [email, setEmail] = useState(""); |
| 33 | const [password, setPassword] = useState(""); |
| 34 | const [username, setUsername] = useState(""); |
| 35 | const [legalName, setLegalName] = useState(""); |
| 36 | const [address, setAddress] = useState({ |
| 37 | street: "", |
| 38 | city: "", |
| 39 | state: "", |
| 40 | postalCode: "", |
| 41 | country: "" |
| 42 | }); |
| 43 | const [usernameAvailable, setUsernameAvailable] = useState(null); |
| 44 | const [usernameChecking, setUsernameChecking] = useState(false); |
| 45 | const [usernameError, setUsernameError] = useState(""); |
| 46 | const [emailError, setEmailError] = useState(""); |
| 47 | const [agreedToTerms, setAgreedToTerms] = useState(false); |
| 48 | const [showPassword, setShowPassword] = useState(false); |
| 49 | const [captchaToken, setCaptchaToken] = useState(import.meta.env.DEV ? "dev-bypass" : null); |
| 50 | const [isLoading, setIsLoading] = useState(false); |
| 51 | const [isSuccess, setIsSuccess] = useState(false); |
| 52 | const { toast } = useToast(); |
| 53 | |
| 54 | useEffect(() => { |
| 55 | if (message === 'github_closed') { |
| 56 | toast({ |
| 57 | title: "GitHub Signups Closed", |
| 58 | description: "New accounts must use Email/Password. Existing GitHub users can still login.", |
| 59 | }); |
| 60 | } |
| 61 | }, [message, toast]); |
| 62 | |
| 63 | // Debounced username availability check |
| 64 | useEffect(() => { |
| 65 | if (!username) { |
| 66 | setUsernameAvailable(null); |
| 67 | setUsernameError(""); |
| 68 | return; |
| 69 | } |
| 70 | |
| 71 | // Validate format first |
| 72 | const usernameRegex = /^[a-zA-Z0-9_-]{3,20}$/; |
| 73 | if (!usernameRegex.test(username)) { |
| 74 | setUsernameAvailable(false); |
| 75 | setUsernameError("Username must be 3-20 characters (letters, numbers, _, -)"); |
| 76 | return; |
| 77 | } |
| 78 | |
| 79 | setUsernameChecking(true); |
| 80 | setUsernameError(""); |
| 81 | |
| 82 | const timeoutId = setTimeout(async () => { |
| 83 | try { |
| 84 | const response = await subdomainAPI.post('/auth/email/check-username', { username }); |
nothing calls this directly
no test coverage detected