diff --git a/vocodes/src/v2/api/user/CreateAccount.ts b/vocodes/src/v2/api/user/CreateAccount.ts new file mode 100644 index 0000000000..ee9d09d54b --- /dev/null +++ b/vocodes/src/v2/api/user/CreateAccount.ts @@ -0,0 +1,59 @@ + +import { ApiConfig } from "../../../common/ApiConfig"; + +export interface CreateAccountRequest { + username: string, + email_address: string, + password: string, + password_confirmation: string, +} + +export interface CreateAccountSuccessResponse { + success: boolean, +} + +export interface CreateAccountErrorResponse { + success: boolean, + error_type: string, + error_fields: { [key: string]: string; }, +} + +type CreateAccountResponse = CreateAccountSuccessResponse | CreateAccountErrorResponse; + +export function CreateAccountIsSuccess(response: CreateAccountResponse): response is CreateAccountSuccessResponse { + return response?.success === true; +} + +export function CreateAccountIsError(response: CreateAccountResponse): response is CreateAccountErrorResponse { + return response?.success === false; +} + +export async function CreateAccount(request: CreateAccountRequest) : Promise +{ + const endpoint = new ApiConfig().createAccount(); + + return await fetch(endpoint, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + credentials: 'include', + body: JSON.stringify(request), + }) + .then(res => res.json()) + .then(res => { + if (!res) { + return { success : false }; + } + + if (res && 'success' in res) { + return res; + } else { + return { success : false }; + } + }) + .catch(e => { + return { success : false }; + }); +} diff --git a/vocodes/src/v2/api/user/GetUserByUsername.ts b/vocodes/src/v2/api/user/GetUserByUsername.ts index 991495dc71..caf4a0b428 100644 --- a/vocodes/src/v2/api/user/GetUserByUsername.ts +++ b/vocodes/src/v2/api/user/GetUserByUsername.ts @@ -38,7 +38,6 @@ export interface ProfileBadge { granted_at: string, } - export async function GetUserByUsername(username: string) : Promise { const usernameLower = username.toLowerCase(); // NB: Until I standardize on display name vs username lookup. const endpoint = new ApiConfig().getProfile(usernameLower); diff --git a/vocodes/src/v2/view/signup/SignupComponent.tsx b/vocodes/src/v2/view/signup/SignupComponent.tsx index 08c100dd3c..b8a007a035 100644 --- a/vocodes/src/v2/view/signup/SignupComponent.tsx +++ b/vocodes/src/v2/view/signup/SignupComponent.tsx @@ -6,6 +6,7 @@ import { Link } from 'react-router-dom'; import { Mode } from '../../../AppMode'; import { SessionWrapper } from '../../../session/SessionWrapper'; import { UserIcon } from '../_icons/UserIcon'; +import { CreateAccount, CreateAccountIsError, CreateAccountIsSuccess } from '../../api/user/CreateAccount'; enum FieldTriState { EMPTY_FALSE, @@ -187,7 +188,7 @@ class SignupComponent extends React.Component { return false; } - handleFormSubmit = (ev: React.FormEvent) : boolean => { + handleFormSubmit = async (ev: React.FormEvent) : Promise => { ev.preventDefault(); if (!this.state.usernameValid || @@ -197,39 +198,37 @@ class SignupComponent extends React.Component { return false; } - const api = new ApiConfig(); - const endpointUrl = api.createAccount(); - const request = { username: this.state.username, email_address: this.state.email, password: this.state.password, password_confirmation: this.state.passwordConfirmation, + }; + + const response = await CreateAccount(request); + + if (CreateAccountIsError(response)) { + if ('email_address' in response.error_fields) { + this.setState({ + emailValid: FieldTriState.FALSE, + emailInvalidReason: response.error_fields['email_address'] || "", + }) + } + if ('username' in response.error_fields) { + this.setState({ + usernameValid: FieldTriState.FALSE, + usernameInvalidReason: response.error_fields['username'] || "", + }) + } } - fetch(endpointUrl, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - body: JSON.stringify(request), - }) - .then(res => res.json()) - .then(res => { - console.log('create account response', res) - if (res.success) { - console.log('querying new session'); - this.props.querySessionCallback(); + if (CreateAccountIsSuccess(response)) { + console.log('querying new session'); + this.props.querySessionCallback(); - // TODO: Switch to functional component. - window.location.href = '/'; - } - }) - .catch(e => { - //this.props.onSpeakErrorCallback(); - }); + // TODO: Switch to functional component. + window.location.href = '/'; + } return false; }