Passwords: add and use a new PasswordField widget.
parent
3ea16cd0d9
commit
12f5f482cd
|
@ -12,6 +12,7 @@ import Switch from "@material-ui/core/Switch";
|
|||
import { routeResolver } from "./App";
|
||||
|
||||
import Container from "./widgets/Container";
|
||||
import PasswordField from "./widgets/PasswordField";
|
||||
|
||||
import LoadingIndicator from "./widgets/LoadingIndicator";
|
||||
import Alert from "@material-ui/lab/Alert";
|
||||
|
@ -122,8 +123,12 @@ export default function SignupPage() {
|
|||
const styles = {
|
||||
form: {
|
||||
},
|
||||
infoAlert: {
|
||||
marginTop: 20,
|
||||
},
|
||||
textField: {
|
||||
marginTop: 20,
|
||||
width: "18em",
|
||||
},
|
||||
submit: {
|
||||
marginTop: 40,
|
||||
|
@ -189,14 +194,15 @@ export default function SignupPage() {
|
|||
onChange={handleInputChange(setEmail)}
|
||||
/>
|
||||
<br />
|
||||
<TextField
|
||||
type="password"
|
||||
<PasswordField
|
||||
style={styles.textField}
|
||||
error={!!errors.errorPassword}
|
||||
helperText={errors.errorPassword}
|
||||
label="Password"
|
||||
name="password"
|
||||
inputProps={{ minLength: PASSWORD_MIN_LENGTH }}
|
||||
inputProps={{
|
||||
minLength: PASSWORD_MIN_LENGTH,
|
||||
}}
|
||||
value={password}
|
||||
onChange={handleInputChange(setPassword)}
|
||||
/>
|
||||
|
@ -215,10 +221,10 @@ export default function SignupPage() {
|
|||
</FormGroup>
|
||||
{advancedSettings}
|
||||
{errors.errorGeneral && (
|
||||
<Alert severity="error" style={styles.textField}>{errors.errorGeneral}</Alert>
|
||||
<Alert severity="error" style={styles.infoAlert}>{errors.errorGeneral}</Alert>
|
||||
)}
|
||||
|
||||
<Alert severity="warning" style={styles.textField}>
|
||||
<Alert severity="warning" style={styles.infoAlert}>
|
||||
Please make sure you remember your password, as it <em>can't</em> be recovered if lost!
|
||||
</Alert>
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import FormControlLabel from "@material-ui/core/FormControlLabel";
|
|||
import Switch from "@material-ui/core/Switch";
|
||||
|
||||
import ExternalLink from "../widgets/ExternalLink";
|
||||
import PasswordField from "../widgets/PasswordField";
|
||||
|
||||
import * as C from "../constants";
|
||||
import LoadingIndicator from "../widgets/LoadingIndicator";
|
||||
|
@ -67,8 +68,12 @@ export default function LoginForm(props: PropsType) {
|
|||
forgotPassword: {
|
||||
paddingTop: 20,
|
||||
},
|
||||
infoAlert: {
|
||||
marginTop: 20,
|
||||
},
|
||||
textField: {
|
||||
marginTop: 20,
|
||||
width: "18em",
|
||||
},
|
||||
submit: {
|
||||
marginTop: 40,
|
||||
|
@ -122,8 +127,7 @@ export default function LoginForm(props: PropsType) {
|
|||
onChange={handleInputChange(setUsername)}
|
||||
/>
|
||||
<br />
|
||||
<TextField
|
||||
type="password"
|
||||
<PasswordField
|
||||
style={styles.textField}
|
||||
error={!!errors.errorPassword}
|
||||
helperText={errors.errorPassword}
|
||||
|
@ -150,7 +154,7 @@ export default function LoginForm(props: PropsType) {
|
|||
{advancedSettings}
|
||||
|
||||
{props.error && (
|
||||
<Alert severity="error" style={styles.textField}>{props.error.message}</Alert>
|
||||
<Alert severity="error" style={styles.infoAlert}>{props.error.message}</Alert>
|
||||
)}
|
||||
|
||||
<div style={styles.submit}>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as React from "react";
|
||||
import Input, { InputProps } from "@material-ui/core/Input";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import FormHelperText from "@material-ui/core/FormHelperText";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import Visibility from "@material-ui/icons/Visibility";
|
||||
import VisibilityOff from "@material-ui/icons/VisibilityOff";
|
||||
|
||||
let formIdCounter = 0;
|
||||
|
||||
export default function PasswordField(props_: Omit<InputProps, "type"> & { helperText?: string, label?: string }) {
|
||||
const [showPassword, setShowPassword] = React.useState(false);
|
||||
const formId_ = React.useMemo(() => formIdCounter++, []);
|
||||
const { helperText, label, style, id, ...props } = props_;
|
||||
const formId = `password-field-${id ?? formId_}`;
|
||||
|
||||
return (
|
||||
<FormControl style={style}>
|
||||
<InputLabel htmlFor={formId}>{label}</InputLabel>
|
||||
<Input
|
||||
{...props}
|
||||
id={formId}
|
||||
type={showPassword ? "text" : "password"}
|
||||
endAdornment={(
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="Toggle password visibility"
|
||||
title="Toggle password visibility"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? <Visibility /> : <VisibilityOff />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
)}
|
||||
/>
|
||||
<FormHelperText id={formId}>{helperText}</FormHelperText>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue