11import React , { Component } from 'react' ;
2- import PropTypes from 'prop-types' ;
32import Button from '@material-ui/core/Button' ;
43import DialogTitle from '@material-ui/core/DialogTitle' ;
54import Dialog from '@material-ui/core/Dialog' ;
@@ -15,21 +14,34 @@ import FormHelperText from '@material-ui/core/FormHelperText';
1514// @ts -ignore
1615import classes from './login.scss' ;
1716
18- export default class LoginModal extends Component < any , any > {
19- static propTypes = {
20- visibility : PropTypes . bool ,
21- error : PropTypes . object ,
22- onCancel : PropTypes . func ,
23- onSubmit : PropTypes . func ,
24- } ;
17+ interface FormFields {
18+ required : boolean ;
19+ pristine : boolean ;
20+ helperText : string ;
21+ value : string ;
22+ }
23+ interface FormError {
24+ type : string ;
25+ title : string ;
26+ description : string ;
27+ }
28+
29+ interface LoginModalProps {
30+ visibility : boolean ;
31+ error : Partial < FormError > ;
32+ onCancel : ( ) => void ;
33+ onSubmit : ( username : string , password : string ) => void ;
34+ }
2535
26- static defaultProps = {
27- error : { } ,
28- onCancel : ( ) => { } ,
29- onSubmit : ( ) => { } ,
30- visibility : true ,
36+ interface LoginModalState {
37+ form : {
38+ username : Partial < FormFields > ;
39+ password : Partial < FormFields > ;
3140 } ;
41+ error : FormError ;
42+ }
3243
44+ export default class LoginModal extends Component < Partial < LoginModalProps > , LoginModalState > {
3345 constructor ( props ) {
3446 super ( props ) ;
3547 this . state = {
@@ -51,11 +63,28 @@ export default class LoginModal extends Component<any, any> {
5163 } ;
5264 }
5365
66+ public render ( ) : JSX . Element {
67+ const { visibility, onCancel, error } = this . props as LoginModalProps ;
68+ return (
69+ < Dialog fullWidth = { true } id = { 'login--form-container' } maxWidth = { 'xs' } onClose = { onCancel } open = { visibility } >
70+ < form noValidate = { true } onSubmit = { this . handleValidateCredentials } >
71+ < DialogTitle > { 'Login' } </ DialogTitle >
72+ < DialogContent >
73+ { this . renderLoginError ( error ) }
74+ { this . renderNameField ( ) }
75+ { this . renderPasswordField ( ) }
76+ </ DialogContent >
77+ { this . renderActions ( ) }
78+ </ form >
79+ </ Dialog >
80+ ) ;
81+ }
82+
5483 /**
5584 * set login modal's username and password to current state
5685 * Required to login
5786 */
58- setCredentials = ( name , e ) => {
87+ public setCredentials = ( name , e ) => {
5988 const { form } = this . state ;
6089 this . setState ( {
6190 form : {
@@ -69,15 +98,15 @@ export default class LoginModal extends Component<any, any> {
6998 } ) ;
7099 } ;
71100
72- setUsername = event => {
101+ public handleUsernameChange = event => {
73102 this . setCredentials ( 'username' , event ) ;
74103 } ;
75104
76- setPassword = event => {
105+ public handlePasswordChange = event => {
77106 this . setCredentials ( 'password' , event ) ;
78107 } ;
79108
80- validateCredentials = event => {
109+ public handleValidateCredentials = event => {
81110 const { form } = this . state ;
82111 // prevents default submit behavior
83112 event . preventDefault ( ) ;
@@ -89,7 +118,7 @@ export default class LoginModal extends Component<any, any> {
89118 ...acc ,
90119 ...{ [ key ] : { ...form [ key ] , pristine : false } } ,
91120 } ) ,
92- { }
121+ { username : { } , password : { } }
93122 ) ,
94123 } ,
95124 ( ) => {
@@ -100,10 +129,14 @@ export default class LoginModal extends Component<any, any> {
100129 ) ;
101130 } ;
102131
103- submitCredentials = async ( ) => {
132+ public submitCredentials = async ( ) => {
104133 const { form } = this . state ;
134+ const username = ( form . username && form . username . value ) || '' ;
135+ const password = ( form . password && form . password . value ) || '' ;
105136 const { onSubmit } = this . props ;
106- await onSubmit ( form . username . value , form . password . value ) ;
137+ if ( onSubmit ) {
138+ await onSubmit ( username , password ) ;
139+ }
107140 // let's wait for API response and then set
108141 // username and password filed to empty state
109142 this . setState ( {
@@ -112,12 +145,12 @@ export default class LoginModal extends Component<any, any> {
112145 ...acc ,
113146 ...{ [ key ] : { ...form [ key ] , value : '' , pristine : true } } ,
114147 } ) ,
115- { }
148+ { username : { } , password : { } }
116149 ) ,
117150 } ) ;
118151 } ;
119152
120- renderErrorMessage ( title , description ) {
153+ private renderErrorMessage ( title , description ) : JSX . Element {
121154 return (
122155 < span >
123156 < div >
@@ -128,7 +161,7 @@ export default class LoginModal extends Component<any, any> {
128161 ) ;
129162 }
130163
131- renderMessage ( title , description ) {
164+ private renderMessage ( title , description ) : JSX . Element {
132165 return (
133166 < div className = { classes . loginErrorMsg } id = { 'client-snackbar' } >
134167 < ErrorIcon className = { classes . loginIcon } />
@@ -137,37 +170,37 @@ export default class LoginModal extends Component<any, any> {
137170 ) ;
138171 }
139172
140- renderLoginError ( { type, title, description } ) {
173+ private renderLoginError ( { type, title, description } : Partial < FormError > ) : JSX . Element | false {
141174 return type === 'error' && < SnackbarContent className = { classes . loginError } message = { this . renderMessage ( title , description ) } /> ;
142175 }
143176
144- renderNameField = ( ) => {
177+ private renderNameField = ( ) => {
145178 const {
146179 form : { username } ,
147180 } = this . state ;
148181 return (
149182 < FormControl error = { ! username . value && ! username . pristine } fullWidth = { true } required = { username . required } >
150183 < InputLabel htmlFor = { 'username' } > { 'Username' } </ InputLabel >
151- < Input id = { 'login--form-username' } onChange = { this . setUsername } placeholder = { 'Your username' } value = { username . value } />
184+ < Input id = { 'login--form-username' } onChange = { this . handleUsernameChange } placeholder = { 'Your username' } value = { username . value } />
152185 { ! username . value && ! username . pristine && < FormHelperText id = { 'username-error' } > { username . helperText } </ FormHelperText > }
153186 </ FormControl >
154187 ) ;
155188 } ;
156189
157- renderPasswordField = ( ) => {
190+ private renderPasswordField = ( ) => {
158191 const {
159192 form : { password } ,
160193 } = this . state ;
161194 return (
162195 < FormControl error = { ! password . value && ! password . pristine } fullWidth = { true } required = { password . required } style = { { marginTop : '8px' } } >
163196 < InputLabel htmlFor = { 'password' } > { 'Password' } </ InputLabel >
164- < Input id = { 'login--form-password' } onChange = { this . setPassword } placeholder = { 'Your strong password' } type = { 'password' } value = { password . value } />
197+ < Input id = { 'login--form-password' } onChange = { this . handlePasswordChange } placeholder = { 'Your strong password' } type = { 'password' } value = { password . value } />
165198 { ! password . value && ! password . pristine && < FormHelperText id = { 'password-error' } > { password . helperText } </ FormHelperText > }
166199 </ FormControl >
167200 ) ;
168201 } ;
169202
170- renderActions = ( ) => {
203+ private renderActions = ( ) => {
171204 const {
172205 form : { username, password } ,
173206 } = this . state ;
@@ -183,21 +216,4 @@ export default class LoginModal extends Component<any, any> {
183216 </ DialogActions >
184217 ) ;
185218 } ;
186-
187- render ( ) {
188- const { visibility, onCancel, error } = this . props ;
189- return (
190- < Dialog fullWidth = { true } id = { 'login--form-container' } maxWidth = { 'xs' } onClose = { onCancel } open = { visibility } >
191- < form noValidate = { true } onSubmit = { this . validateCredentials } >
192- < DialogTitle > { 'Login' } </ DialogTitle >
193- < DialogContent >
194- { this . renderLoginError ( error ) }
195- { this . renderNameField ( ) }
196- { this . renderPasswordField ( ) }
197- </ DialogContent >
198- { this . renderActions ( ) }
199- </ form >
200- </ Dialog >
201- ) ;
202- }
203219}
0 commit comments