get rid of horrible class component

This commit is contained in:
Brandon Thomas committed 2022-02-16 01:39:03 -05:00
1 parent 7492d12ca0
commit e4486c7802
3 files changed
+333 -372

No files matched your search

@@ -10,7 +10,7 @@ import { NewTopNavFc } from './NewTopNavFc';
import { ProfileEditFc } from './profile/profile_edit/ProfileEditFc';
import { ProfileFc } from './profile/profile_view/ProfileFc';
import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper';
import { SignupComponent } from './signup/SignupComponent';
import { SignupPage } from './signup/SignupPage';
import { Switch, Route } from 'react-router-dom';
import { TermsFc } from './about/terms_page/TermsFc';
import { TtsInferenceJob, W2lInferenceJob } from '../../App';
@@ -167,7 +167,7 @@ class NewVocodesContainer extends React.Component<Props, State> {
</Route>
<Route path="/signup">
<SignupComponent
<SignupPage
querySessionCallback={()=>{}}
sessionWrapper={this.props.sessionWrapper}
/>
@@ -1,370 +0,0 @@
import React from 'react';
import { CreateAccount, CreateAccountIsError, CreateAccountIsSuccess } from '@storyteller/components/src/api/user/CreateAccount';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Link } from 'react-router-dom';
import { Mode } from '../../../AppMode';
import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper';
import { iconEmailField, iconPasswordField, iconUser } from '@storyteller/components/src/icons/SemanticIcons';
enum FieldTriState {
EMPTY_FALSE,
FALSE,
TRUE,
}
interface Props {
sessionWrapper: SessionWrapper,
querySessionCallback : () => void,
switchModeCallback?: (mode: Mode) => void,
}
interface State {
username: string,
usernameValid: FieldTriState,
usernameInvalidReason: string,
email: string,
emailValid: FieldTriState,
emailInvalidReason: string,
password: string,
passwordValid: FieldTriState,
passwordInvalidReason: string,
passwordConfirmation: string,
passwordConfirmationValid: FieldTriState,
passwordConfirmationInvalidReason: string,
}
class SignupComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
username: "",
usernameValid: FieldTriState.EMPTY_FALSE,
usernameInvalidReason: "",
email: "",
emailValid: FieldTriState.EMPTY_FALSE,
emailInvalidReason: "",
password: "",
passwordValid: FieldTriState.EMPTY_FALSE,
passwordInvalidReason: "",
passwordConfirmation: "",
passwordConfirmationValid: FieldTriState.EMPTY_FALSE,
passwordConfirmationInvalidReason: "",
};
}
handleUsernameChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const username = (ev.target as HTMLInputElement).value;
let usernameValid = FieldTriState.EMPTY_FALSE;
let usernameInvalidReason = "";
if (username.length > 1) {
if (username.length < 3) {
usernameValid = FieldTriState.FALSE;
usernameInvalidReason = "username is too short";
} else if (username.length > 15) {
usernameValid = FieldTriState.FALSE;
usernameInvalidReason = "username is too long";
} else {
usernameValid = FieldTriState.TRUE;
}
}
this.setState({
username: username,
usernameValid: usernameValid,
usernameInvalidReason: usernameInvalidReason,
})
return false;
}
handleEmailChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const email = (ev.target as HTMLInputElement).value;
let emailValid = FieldTriState.EMPTY_FALSE;
let emailInvalidReason = "";
if (email.length > 1) {
if (email.length < 3) {
emailValid = FieldTriState.FALSE;
emailInvalidReason = "email is too short";
} else if (!email.includes("@")) {
emailValid = FieldTriState.FALSE;
emailInvalidReason = "email is invalid";
} else {
emailValid = FieldTriState.TRUE;
}
}
this.setState({
email: email,
emailValid: emailValid,
emailInvalidReason: emailInvalidReason,
})
return false;
}
handlePasswordChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const password = (ev.target as HTMLInputElement).value;
let passwordValid = FieldTriState.EMPTY_FALSE;
let passwordInvalidReason = "";
let passwordConfirmationValid = FieldTriState.EMPTY_FALSE;
let passwordConfirmationInvalidReason = "";
if (password.length > 1) {
if (password.length < 5) {
passwordValid = FieldTriState.FALSE;
passwordInvalidReason = "password is too short";
} else {
passwordValid = FieldTriState.TRUE;
}
if (password !== this.state.passwordConfirmation) {
passwordConfirmationValid = FieldTriState.FALSE;
passwordConfirmationInvalidReason = "passwords do not match";
} else {
passwordConfirmationValid = FieldTriState.TRUE;
passwordConfirmationInvalidReason = "";
}
}
this.setState({
password: password,
passwordValid: passwordValid,
passwordInvalidReason: passwordInvalidReason,
passwordConfirmationValid: passwordConfirmationValid,
passwordConfirmationInvalidReason: passwordConfirmationInvalidReason,
})
return false;
}
handlePasswordConfirmationChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const passwordConfirmation = (ev.target as HTMLInputElement).value;
let passwordConfirmationValid = FieldTriState.EMPTY_FALSE;
let passwordConfirmationInvalidReason = "";
if (passwordConfirmation.length > 1) {
if (passwordConfirmation !== this.state.password) {
passwordConfirmationValid = FieldTriState.FALSE;
passwordConfirmationInvalidReason = "passwords do not match";
} else {
passwordConfirmationValid = FieldTriState.TRUE;
passwordConfirmationInvalidReason = "";
}
}
this.setState({
passwordConfirmation: passwordConfirmation,
passwordConfirmationValid: passwordConfirmationValid,
passwordConfirmationInvalidReason: passwordConfirmationInvalidReason,
})
return false;
}
handleFormSubmit = async (ev: React.FormEvent<HTMLFormElement>) : Promise<boolean> => {
ev.preventDefault();
if (!this.state.usernameValid ||
!this.state.emailValid ||
!this.state.passwordValid ||
!this.state.passwordConfirmationValid) {
return false;
}
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'] || "",
})
}
} else if (CreateAccountIsSuccess(response)) {
console.log('querying new session');
this.props.querySessionCallback();
// TODO: Switch to functional component.
window.location.href = '/';
}
return false;
}
public render() {
if (this.props.sessionWrapper.isLoggedIn()) {
return <div>Invalid view for logged in users.</div>;
}
let usernameInputClass = "input";
let usernameHelpClass = "help";
switch (this.state.usernameValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
usernameInputClass += " is-danger";
usernameHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
usernameInputClass += " is-success";
usernameHelpClass += " is-success";
break;
}
let emailInputClass = "input";
let emailHelpClass = "help";
switch (this.state.emailValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
emailInputClass += " is-danger";
emailHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
emailInputClass += " is-success";
emailHelpClass += " is-success";
break;
}
let passwordInputClass = "input";
let passwordHelpClass = "help";
switch (this.state.passwordValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
passwordInputClass += " is-danger";
passwordHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
passwordInputClass += " is-success";
passwordHelpClass += " is-success";
break;
}
let passwordConfirmationInputClass = "input";
let passwordConfirmationHelpClass = "help";
switch (this.state.passwordConfirmationValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
passwordConfirmationInputClass += " is-danger";
passwordConfirmationHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
passwordConfirmationInputClass += " is-success";
passwordConfirmationHelpClass += " is-success";
break;
}
return (
<div>
<h1 className="title is-1"> Sign Up </h1>
<form onSubmit={this.handleFormSubmit}>
<div className="field">
<label className="label">Username</label>
<div className="control has-icons-left has-icons-right">
<input className={usernameInputClass} type="text" placeholder="Username" value={this.state.username} onChange={this.handleUsernameChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconUser} />
</span>
</div>
<p className={usernameHelpClass}>{this.state.usernameInvalidReason}</p>
</div>
<div className="field">
<label className="label">Email</label>
<div className="control has-icons-left has-icons-right">
<input className={emailInputClass} type="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconEmailField} />
</span>
</div>
<p className={emailHelpClass}>{this.state.emailInvalidReason}</p>
</div>
<div className="field">
<label className="label">Password</label>
<div className="control has-icons-left has-icons-right">
<input className={passwordInputClass} type="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconPasswordField} />
</span>
</div>
<p className={passwordHelpClass}>{this.state.passwordInvalidReason}</p>
</div>
<div className="field">
<label className="label">Password Confirmation</label>
<div className="control has-icons-left has-icons-right">
<input className={passwordConfirmationInputClass} type="password" placeholder="Password confirmation" value={this.state.passwordConfirmation} onChange={this.handlePasswordConfirmationChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconPasswordField} />
</span>
</div>
<p className={passwordConfirmationHelpClass}>
{this.state.passwordConfirmationInvalidReason}
</p>
</div>
<br />
<div className="notification is-warning">
<strong>Remember your password!</strong> We don't have password reset currently, and it'll be a
few more weeks before it's added (there are more important features to work on). If you lose your
password, please let us know in Discord.
</div>
<button className="button is-link is-large is-fullwidth">Sign up</button>
</form>
<br />
<Link to="/login"
className="button is-info is-large is-fullwidth is-inverted"
>Already have an account? Log in instead!</Link>
</div>
)
}
}
export { SignupComponent };
@@ -0,0 +1,331 @@
import React, { useState } from 'react';
import { CreateAccount, CreateAccountIsError, CreateAccountIsSuccess } from '@storyteller/components/src/api/user/CreateAccount';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Link } from 'react-router-dom';
import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper';
import { iconEmailField, iconPasswordField, iconUser } from '@storyteller/components/src/icons/SemanticIcons';
enum FieldTriState {
EMPTY_FALSE,
FALSE,
TRUE,
}
interface Props {
sessionWrapper: SessionWrapper,
querySessionCallback : () => void,
}
function SignupPage(props: Props) {
const [username, setUsername] = useState('');
const [usernameValid, setUsernameValid] = useState(FieldTriState.EMPTY_FALSE);
const [usernameInvalidReason, setUsernameInvalidReason] = useState('');
const [email, setEmail] = useState('');
const [emailValid, setEmailValid] = useState(FieldTriState.EMPTY_FALSE);
const [emailInvalidReason, setEmailInvalidReason] = useState('');
const [password, setPassword] = useState('');
const [passwordValid, setPasswordValid] = useState(FieldTriState.EMPTY_FALSE);
const [passwordInvalidReason, setPasswordInvalidReason] = useState('');
const [passwordConfirmation, setPasswordConfirmation] = useState('');
const [passwordConfirmationValid, setPasswordConfirmationValid] = useState(FieldTriState.EMPTY_FALSE);
const [passwordConfirmationInvalidReason, setPasswordConfirmationInvalidReason] = useState('');
const handleUsernameChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const newUsername = (ev.target as HTMLInputElement).value;
let usernameValid = FieldTriState.EMPTY_FALSE;
let usernameInvalidReason = "";
if (newUsername.length > 1) {
if (newUsername.length < 3) {
usernameValid = FieldTriState.FALSE;
usernameInvalidReason = "username is too short";
} else if (newUsername.length > 15) {
usernameValid = FieldTriState.FALSE;
usernameInvalidReason = "username is too long";
} else {
usernameValid = FieldTriState.TRUE;
}
}
setUsername(newUsername);
setUsernameValid(usernameValid);
setUsernameInvalidReason(usernameInvalidReason);
return false;
}
const handleEmailChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const newEmail = (ev.target as HTMLInputElement).value;
let emailValid = FieldTriState.EMPTY_FALSE;
let emailInvalidReason = "";
if (newEmail.length > 1) {
if (newEmail.length < 3) {
emailValid = FieldTriState.FALSE;
emailInvalidReason = "email is too short";
} else if (!newEmail.includes("@")) {
emailValid = FieldTriState.FALSE;
emailInvalidReason = "email is invalid";
} else {
emailValid = FieldTriState.TRUE;
}
}
setEmail(newEmail);
setEmailValid(emailValid);
setEmailInvalidReason(emailInvalidReason);
return false;
}
const handlePasswordChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const newPassword = (ev.target as HTMLInputElement).value;
let passwordValid = FieldTriState.EMPTY_FALSE;
let passwordInvalidReason = "";
let passwordConfirmationValid = FieldTriState.EMPTY_FALSE;
let passwordConfirmationInvalidReason = "";
if (newPassword.length > 1) {
if (newPassword.length < 5) {
passwordValid = FieldTriState.FALSE;
passwordInvalidReason = "password is too short";
} else {
passwordValid = FieldTriState.TRUE;
}
if (newPassword !== passwordConfirmation) {
passwordConfirmationValid = FieldTriState.FALSE;
passwordConfirmationInvalidReason = "passwords do not match";
} else {
passwordConfirmationValid = FieldTriState.TRUE;
passwordConfirmationInvalidReason = "";
}
}
setPassword(newPassword);
setPasswordValid(passwordValid);
setPasswordInvalidReason(passwordInvalidReason);
setPasswordConfirmationValid(passwordConfirmationValid);
setPasswordConfirmationInvalidReason(passwordConfirmationInvalidReason)
return false;
}
const handlePasswordConfirmationChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const newPasswordConfirmation = (ev.target as HTMLInputElement).value;
let passwordConfirmationValid = FieldTriState.EMPTY_FALSE;
let passwordConfirmationInvalidReason = "";
if (newPasswordConfirmation.length > 1) {
if (newPasswordConfirmation !== password) {
passwordConfirmationValid = FieldTriState.FALSE;
passwordConfirmationInvalidReason = "passwords do not match";
} else {
passwordConfirmationValid = FieldTriState.TRUE;
passwordConfirmationInvalidReason = "";
}
}
setPasswordConfirmation(newPasswordConfirmation);
setPasswordConfirmationValid(passwordConfirmationValid);
setPasswordConfirmationInvalidReason(passwordConfirmationInvalidReason);
return false;
}
const handleFormSubmit = async (ev: React.FormEvent<HTMLFormElement>) : Promise<boolean> => {
ev.preventDefault();
if (!usernameValid ||
!emailValid ||
!passwordValid ||
!passwordConfirmationValid) {
return false;
}
const request = {
username: username,
email_address: email,
password: password,
password_confirmation: passwordConfirmation,
};
const response = await CreateAccount(request);
if (CreateAccountIsError(response)) {
if ('email_address' in response.error_fields) {
setEmailValid(FieldTriState.FALSE);
setEmailInvalidReason(response.error_fields['email_address'] || "");
}
if ('username' in response.error_fields) {
setUsernameValid(FieldTriState.FALSE);
setUsernameInvalidReason(response.error_fields['username'] || "");
}
} else if (CreateAccountIsSuccess(response)) {
console.log('querying new session');
props.querySessionCallback();
// TODO: Switch to functional component.
window.location.href = '/';
}
return false;
}
if (props.sessionWrapper.isLoggedIn()) {
return <div>Invalid view for logged in users.</div>;
}
let usernameInputClass = "input";
let usernameHelpClass = "help";
switch (usernameValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
usernameInputClass += " is-danger";
usernameHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
usernameInputClass += " is-success";
usernameHelpClass += " is-success";
break;
}
let emailInputClass = "input";
let emailHelpClass = "help";
switch (emailValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
emailInputClass += " is-danger";
emailHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
emailInputClass += " is-success";
emailHelpClass += " is-success";
break;
}
let passwordInputClass = "input";
let passwordHelpClass = "help";
switch (passwordValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
passwordInputClass += " is-danger";
passwordHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
passwordInputClass += " is-success";
passwordHelpClass += " is-success";
break;
}
let passwordConfirmationInputClass = "input";
let passwordConfirmationHelpClass = "help";
switch (passwordConfirmationValid) {
case FieldTriState.EMPTY_FALSE:
break;
case FieldTriState.FALSE:
passwordConfirmationInputClass += " is-danger";
passwordConfirmationHelpClass += " is-danger";
break;
case FieldTriState.TRUE:
passwordConfirmationInputClass += " is-success";
passwordConfirmationHelpClass += " is-success";
break;
}
return (
<div>
<h1 className="title is-1"> Sign Up </h1>
<form onSubmit={handleFormSubmit}>
<div className="field">
<label className="label">Username</label>
<div className="control has-icons-left has-icons-right">
<input className={usernameInputClass} type="text" placeholder="Username" value={username} onChange={handleUsernameChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconUser} />
</span>
</div>
<p className={usernameHelpClass}>{usernameInvalidReason}</p>
</div>
<div className="field">
<label className="label">Email</label>
<div className="control has-icons-left has-icons-right">
<input className={emailInputClass} type="email" placeholder="Email" value={email} onChange={handleEmailChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconEmailField} />
</span>
</div>
<p className={emailHelpClass}>{emailInvalidReason}</p>
</div>
<div className="field">
<label className="label">Password</label>
<div className="control has-icons-left has-icons-right">
<input className={passwordInputClass} type="password" placeholder="Password" value={password} onChange={handlePasswordChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconPasswordField} />
</span>
</div>
<p className={passwordHelpClass}>{passwordInvalidReason}</p>
</div>
<div className="field">
<label className="label">Password Confirmation</label>
<div className="control has-icons-left has-icons-right">
<input className={passwordConfirmationInputClass} type="password" placeholder="Password confirmation" value={passwordConfirmation} onChange={handlePasswordConfirmationChange} />
<span className="icon is-small is-left">
<FontAwesomeIcon icon={iconPasswordField} />
</span>
</div>
<p className={passwordConfirmationHelpClass}>
{passwordConfirmationInvalidReason}
</p>
</div>
<br />
<div className="notification is-warning">
<strong>Remember your password!</strong> We don't have password reset currently, and it'll be a
few more weeks before it's added (there are more important features to work on). If you lose your
password, please let us know in Discord.
</div>
<button className="button is-link is-large is-fullwidth">Sign up</button>
</form>
<br />
<Link to="/login"
className="button is-info is-large is-fullwidth is-inverted"
>Already have an account? Log in instead!</Link>
</div>
)
}
export { SignupPage };