import React, { Component } from 'react'; import DialogTitle from '@material-ui/core/DialogTitle'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import SnackbarContent from '@material-ui/core/SnackbarContent'; import ErrorIcon from '@material-ui/icons/Error'; import InputLabel from '@material-ui/core/InputLabel'; import Input from '@material-ui/core/Input'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; import { css } from 'emotion'; import Button from '../../muiComponents/Button'; import * as classes from './styles'; interface FormFields { required: boolean; pristine: boolean; helperText: string; value: string; } export interface FormError { type: string; title: string; description: string; } interface LoginModalProps { visibility: boolean; error?: FormError; onCancel: () => void; onSubmit: (username: string, password: string) => void; } interface LoginModalState { form: { username: Partial; password: Partial; }; error?: FormError; } export default class LoginModal extends Component, LoginModalState> { constructor(props: LoginModalProps) { super(props); this.state = { form: { username: { required: true, pristine: true, helperText: 'Field required', value: '', }, password: { required: true, pristine: true, helperText: 'Field required', value: '', }, }, error: props.error, }; } public render(): JSX.Element { const { visibility = true, onCancel = () => null, error } = this.props as LoginModalProps; return (
{'Login'} {error && this.renderLoginError(error)} {this.renderNameField()} {this.renderPasswordField()} {this.renderActions()}
); } /** * set login modal's username and password to current state * Required to login */ public setCredentials = (name, e) => { const { form } = this.state; this.setState({ form: { ...form, [name]: { ...form[name], value: e.target.value, pristine: false, }, }, }); }; public handleUsernameChange = event => { this.setCredentials('username', event); }; public handlePasswordChange = event => { this.setCredentials('password', event); }; public handleValidateCredentials = event => { const { form } = this.state; // prevents default submit behavior event.preventDefault(); this.setState( { form: Object.keys(form).reduce( (acc, key) => ({ ...acc, ...{ [key]: { ...form[key], pristine: false } }, }), { username: {}, password: {} } ), }, () => { if (!Object.keys(form).some(id => !form[id])) { this.submitCredentials(); } } ); }; public submitCredentials = async () => { const { form } = this.state; const username = (form.username && form.username.value) || ''; const password = (form.password && form.password.value) || ''; const { onSubmit } = this.props; if (onSubmit) { await onSubmit(username, password); } // let's wait for API response and then set // username and password filed to empty state this.setState({ form: Object.keys(form).reduce( (acc, key) => ({ ...acc, ...{ [key]: { ...form[key], value: '', pristine: true } }, }), { username: {}, password: {} } ), }); }; public renderErrorMessage(title: string, description: string): JSX.Element { return (
{title}
{description}
); } public renderMessage(title: string, description: string): JSX.Element { return (
{this.renderErrorMessage(title, description)}
); } public renderLoginError({ type, title, description }: FormError): JSX.Element | false { return type === 'error' && ; } public renderNameField = () => { const { form: { username }, } = this.state; return ( {'Username'} {!username.value && !username.pristine && {username.helperText}} ); }; public renderPasswordField = () => { const { form: { password }, } = this.state; return ( {'Password'} {!password.value && !password.pristine && {password.helperText}} ); }; public renderActions = () => { const { form: { username, password }, } = this.state; const { onCancel } = this.props; return ( ); }; }