From 6970ebc5038cc210ea7d68e92362d5d7b7cee3aa Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 1 Sep 2020 17:58:17 +0300 Subject: [PATCH] Add Signup page. --- src/App.tsx | 2 + src/LoginGate.tsx | 54 ++++++----- src/SignupPage.tsx | 218 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 20 deletions(-) create mode 100644 src/SignupPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 3b1d35a..453e73a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -85,6 +85,8 @@ export const routeResolver = new RouteResolver({ new: "new", import: "import", }, + signup: { + }, settings: { }, debug: { diff --git a/src/LoginGate.tsx b/src/LoginGate.tsx index 45a638e..9885732 100644 --- a/src/LoginGate.tsx +++ b/src/LoginGate.tsx @@ -20,6 +20,9 @@ import SignedPagesBadge from "./images/signed-pages-badge.svg"; import { useCredentials } from "./credentials"; import LoadingIndicator from "./widgets/LoadingIndicator"; import { startTask } from "./helpers"; +import { Switch, Route } from "react-router"; +import { routeResolver } from "./App"; +import SignupPage from "./SignupPage"; export default function LoginGate() { @@ -65,27 +68,38 @@ export default function LoginGate() { }; return ( - -

Please Log In

- + ( + + )} /> -
- - SignedPgaes badge - -
    -
  • - The EteSync Website -
  • -
  • - Is the web client safe to use? -
  • -
  • Source code
  • -
-
+ + +

Please Log In

+ +
+ + SignedPgaes badge + +
    +
  • + The EteSync Website +
  • +
  • + Is the web client safe to use? +
  • +
  • Source code
  • +
+
+
+ ); } diff --git a/src/SignupPage.tsx b/src/SignupPage.tsx new file mode 100644 index 0000000..47fc324 --- /dev/null +++ b/src/SignupPage.tsx @@ -0,0 +1,218 @@ +// SPDX-FileCopyrightText: © 2017 EteSync Authors +// SPDX-License-Identifier: AGPL-3.0-only + +import * as React from "react"; +import * as Etebase from "etebase"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import FormGroup from "@material-ui/core/FormGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Switch from "@material-ui/core/Switch"; + +import { routeResolver } from "./App"; + +import ExternalLink from "./widgets/ExternalLink"; +import Container from "./widgets/Container"; + +import * as C from "./constants"; +import LoadingIndicator from "./widgets/LoadingIndicator"; +import Alert from "@material-ui/lab/Alert"; +import { CircularProgress } from "@material-ui/core"; +import { Redirect } from "react-router"; +import { useCredentials } from "./credentials"; +import { useDispatch } from "react-redux"; +import { startTask } from "./helpers"; +import { login } from "./store/actions"; + +interface FormErrors { + errorUsername?: string; + errorEmail?: string; + errorPassword?: string; + errorEncryptionPassword?: string; + errorServer?: string; + + errorGeneral?: string; +} + +export default function SignupPage() { + const credentials = useCredentials(); + const dispatch = useDispatch(); + const [username, setUsername] = React.useState(""); + const [email, setEmail] = React.useState(""); + const [password, setPassword] = React.useState(""); + const [server, setServer] = React.useState(""); + const [showAdvanced, setShowAdvanced] = React.useState(false); + const [loading, setLoading] = React.useState(false); + const [errors, setErrors] = React.useState({}); + + if (credentials) { + return ( + + ); + } + + async function signup(e: React.FormEvent) { + e.preventDefault(); + setLoading(true); + try { + const errors: FormErrors = {}; + const fieldRequired = "This field is required!"; + if (!username) { + errors.errorUsername = fieldRequired; + } + if (!email) { + errors.errorEmail = fieldRequired; + } + if (!password) { + errors.errorPassword = fieldRequired; + } + + if (process.env.NODE_ENV !== "development") { + if (showAdvanced && !server.startsWith("https://")) { + errors.errorServer = "Server URI must start with https://"; + } + } + + if (Object.keys(errors).length) { + setErrors(errors); + return; + } else { + setErrors({}); + } + + const serverUrl = (showAdvanced) ? server : undefined; + const user: Etebase.User = { + username, + email, + }; + const etebase = await startTask((async () => { + return await Etebase.Account.signup(user, password, serverUrl); + })); + dispatch(login(etebase)); + } catch (e) { + errors.errorGeneral = e.toString(); + setErrors(errors); + } finally { + setLoading(false); + } + } + + const styles = { + form: { + }, + forgotPassword: { + paddingTop: 20, + }, + textField: { + marginTop: 20, + }, + submit: { + marginTop: 40, + textAlign: "right" as any, + }, + }; + + function handleInputChange(func: (value: string) => void) { + return (event: React.ChangeEvent) => { + func(event.target.value); + }; + } + + let advancedSettings = null; + if (showAdvanced) { + advancedSettings = ( + + +
+
+ ); + } + + if (loading) { + return ( +
+ +

Deriving encryption data...

+
+ ); + } + + return ( + +

Signup

+
+ +
+ +
+ +
+ Forgot password? +
+ + setShowAdvanced(!showAdvanced)} + /> + } + label="Advanced settings" + /> + + {advancedSettings} + {errors.errorGeneral && ( + {errors.errorGeneral} + )} + +
+ +
+ +
+ ); +}