import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import { useRecoilState } from "recoil"; import BlueLink from "../../components/BlueLink"; import Button, { ButtonStyle } from "../../components/Button"; import Loading from "../../components/Loading"; import Notice from "../../components/Notice"; import TextInput from "../../components/TextInput"; import { fetchAPI, MeUser, SignupResponse } from "../../lib/api-fetch"; import { userState } from "../../lib/state"; import toast from "../../lib/toast"; interface CallbackResponse { has_account: boolean; token?: string; user?: MeUser; discord?: string; ticket?: string; require_invite: boolean; } interface State { hasAccount: boolean; isLoading: boolean; token: string | null; user: MeUser | null; discord: string | null; ticket: string | null; error?: any; requireInvite: boolean; } export default function Discord() { const router = useRouter(); const [user, setUser] = useRecoilState(userState); const [state, setState] = useState({ hasAccount: false, isLoading: false, token: null, user: null, discord: null, ticket: null, error: null, requireInvite: false, }); const [formData, setFormData] = useState<{ username: string; invite: string; }>({ username: "", invite: "" }); useEffect(() => { if (state.isLoading || !router.query.code || !router.query.state) { return; } // we got a token + user, save it and return to the home page if (state.token) { window.localStorage.setItem("pronouns-token", state.token); setUser(state.user!); router.push("/"); return; } setState({ ...state, isLoading: true }); fetchAPI("/auth/discord/callback", "POST", { callback_domain: window.location.origin, code: router.query.code, state: router.query.state, }) .then((resp) => { setState({ hasAccount: resp.has_account, isLoading: false, token: resp.token || null, user: resp.user || null, discord: resp.discord || null, ticket: resp.ticket || null, requireInvite: resp.require_invite, }); }) .catch((e) => { setState({ hasAccount: false, isLoading: false, error: e, token: null, user: null, discord: null, ticket: null, requireInvite: false, }); }); if (!state.ticket && !state.token) { return; } }, [router.query.code, router.query.state, state.token]); if (state.isLoading || (!state.ticket && !state.error)) { return ; } else if (!state.ticket && state.error) { return (

{state.error.message ?? state.error}

Try again?

); } // user needs to create an account const signup = async () => { try { const resp = await fetchAPI( "/auth/discord/signup", "POST", { ticket: state.ticket, username: formData.username, invite_code: formData.invite, } ); setUser(resp.user); localStorage.setItem("pronouns-token", resp.token); toast({ text: "Created account!", background: "success" }); router.push("/"); } catch (e: any) { toast({ text: `${e.message ?? e}`, background: "error" }); } }; return (

Get started

Just one more thing!
{state.discord}, you need to choose a username {state.requireInvite && " and fill in an invite code"} before you create an account!

{state.requireInvite && ( )}
Note: by clicking "Create account", you agree to the{" "} terms of service and the{" "} privacy policy.
); }