import * as React from "react"; import * as Actions from "~/common/actions"; import * as System from "~/components/system"; import * as Constants from "~/common/constants"; import * as Validations from "~/common/validations"; import * as Strings from "~/common/strings"; import { css } from "@emotion/core"; import { Logo, Symbol } from "~/common/logo"; import { dispatchCustomEvent } from "~/common/custom-events"; const delay = (time) => new Promise((resolve) => setTimeout(() => { resolve(); }, time) ); const STYLES_POPOVER = css` height: 424px; padding: 32px 36px; border-radius: 4px; max-width: 376px; width: 95vw; display: flex; flex-direction: column; background: ${Constants.system.white}; color: ${Constants.system.black}; ${"" /* box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25); */} box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.05); @keyframes authentication-popover-fade-in { from { transform: translateY(-8px); opacity: 0; } to { transform: translateY(0px); opacity: 1; } } animation: authentication-popover-fade-in 400ms ease; `; const STYLES_LINKS = css` margin-top: 24px; max-width: 376px; width: 100%; padding-left: 26px; `; const STYLES_LINK_ITEM = css` display: block; text-decoration: none; font-weight: 400; font-size: 14px; font-family: ${Constants.font.semiBold}; user-select: none; cursor: pointer; margin-top: 2px; color: ${Constants.system.black}; transition: 200ms ease all; word-wrap: break-word; :visited { color: ${Constants.system.black}; } :hover { color: ${Constants.system.brand}; } `; export class SignIn extends React.Component { state = { scene: "WELCOME", username: "", password: "", loading: false, usernameTaken: false, }; componentDidMount() { // window.history.replaceState({ id: null }, "Slate", `/_`); } _handleChange = (e) => { if (e.target.name === "accepted" && e.target.value) { const hash = Strings.generateRandomString(); const confirm = window.prompt(`Please type ${hash} to continue.`); if (confirm !== hash) { window.alert("Please try again."); return; } } this.setState({ [e.target.name]: e.target.value }); }; _handleUsernameChange = (e) => { const value = Strings.createSlug(e.target.value, ""); this.setState({ [e.target.name]: value, usernameTaken: false }); }; _handleSubmit = async () => { this.setState({ loading: true }); await delay(100); if (!this.state.accepted && this.state.scene === "CREATE_ACCOUNT") { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: "You must accept the terms of service to create an account", }, }, }); this.setState({ loading: false }); return; } if (!Validations.username(this.state.username)) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: this.state.scene === "CREATE_ACCOUNT" ? "Usernames must between 1-48 characters and consist of only characters and numbers" : "Invalid username", }, }, }); this.setState({ loading: false }); return; } if (!Validations.password(this.state.password)) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: this.state.scene === "CREATE_ACCOUNT" ? "Your password must be at least 8 characters" : "Incorrect password", }, }, }); this.setState({ loading: false }); return; } let response = null; if (this.state.scene === "CREATE_ACCOUNT") { response = await this.props.onCreateUser({ username: this.state.username.toLowerCase(), password: this.state.password, accepted: this.state.accepted, }); } else { response = await this.props.onAuthenticate({ username: this.state.username.toLowerCase(), password: this.state.password, }); } if (!response) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: "1We're having trouble connecting right now. Please try again later.", }, }, }); this.setState({ loading: false }); return; } if (response.error) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { decorator: response.decorator } }, }); this.setState({ loading: false }); return; } this.setState({ scene: "whatever" }); }; _handleCheckUsername = async () => { if (!this.state.username || !this.state.username.length) { return; } if (!Validations.username(this.state.username)) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: "Usernames must between 1-48 characters and consist of only characters and numbers", }, }, }); return; } const response = await Actions.checkUsername({ username: this.state.username.toLowerCase(), }); if (!response) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: "2We're having trouble connecting right now. Please try again later.", }, }, }); return; } if (response.error) { dispatchCustomEvent({ name: "create-alert", detail: { alert: { decorator: response.decorator, }, }, }); return; } if (response.data) { //NOTE(martina): username taken this.setState({ usernameTaken: true }); dispatchCustomEvent({ name: "create-alert", detail: { alert: { message: "That username is taken", }, }, }); return; } //NOTE(martina): username not taken return this.setState({ usernameTaken: false, }); }; render() { if (this.state.scene === "WELCOME") { return (
{this.props.external ? "Sign up or sign in to continue" : "An open-source file sharing network for research and collaboration"} this.setState({ scene: "CREATE_ACCOUNT" })} loading={this.state.loading} > Sign up this.setState({ scene: "SIGN_IN" })} loading={this.state.loading} > Sign in
⭢ Terms of service ⭢ Community guidelines
); } if (this.state.scene === "CREATE_ACCOUNT") { return (
Create your account To create an account you must accept the terms of service. {}} loading={this.state.loading} > Sign up
{ this.setState({ scene: "SIGN_IN", loading: false }); }} > ⭢ Already have an account?
); } return (
Welcome back {}} loading={this.state.loading} > Sign in
{ this.setState({ scene: "CREATE_ACCOUNT", loading: false }); }} > ⭢ Not registered? Sign up instead
); } }