You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
5.2 KiB
137 lines
5.2 KiB
import React, { useReducer } from 'react'; |
|
import { WindowState } from "../Windows"; |
|
import { Box, Paper, Typography, TextField, Button } from "@material-ui/core"; |
|
import { useHistory } from 'react-router'; |
|
import { useAuth, Auth } from '../../../lib/useAuth'; |
|
import Alert from '@material-ui/lab/Alert'; |
|
import { Link } from 'react-router-dom'; |
|
|
|
export enum RegistrationStatus { |
|
NoneSubmitted = 0, |
|
Successful, |
|
Unsuccessful, |
|
} |
|
|
|
export interface RegisterWindowState extends WindowState { |
|
email: string, |
|
password: string, |
|
status: RegistrationStatus, |
|
} |
|
export enum RegisterWindowStateActions { |
|
SetEmail = "SetEmail", |
|
SetPassword = "SetPassword", |
|
SetStatus = "SetStatus", |
|
} |
|
export function RegisterWindowReducer(state: RegisterWindowState, action: any) { |
|
switch (action.type) { |
|
case RegisterWindowStateActions.SetEmail: |
|
return { ...state, email: action.value } |
|
case RegisterWindowStateActions.SetPassword: |
|
return { ...state, password: action.value } |
|
case RegisterWindowStateActions.SetStatus: |
|
return { ...state, status: action.value } |
|
default: |
|
throw new Error("Unimplemented RegisterWindow state update.") |
|
} |
|
} |
|
|
|
export default function RegisterWindow(props: {}) { |
|
const [state, dispatch] = useReducer(RegisterWindowReducer, { |
|
email: "", |
|
password: "", |
|
status: RegistrationStatus.NoneSubmitted, |
|
}); |
|
|
|
return <RegisterWindowControlled state={state} dispatch={dispatch} /> |
|
} |
|
|
|
export function RegisterWindowControlled(props: { |
|
state: RegisterWindowState, |
|
dispatch: (action: any) => void, |
|
}) { |
|
let history: any = useHistory(); |
|
let auth: Auth = useAuth(); |
|
|
|
const onSubmit = (event: any) => { |
|
event.preventDefault(); |
|
auth.signup(props.state.email, props.state.password) |
|
.then(() => { |
|
props.dispatch({ |
|
type: RegisterWindowStateActions.SetStatus, |
|
value: RegistrationStatus.Successful, |
|
}) |
|
}).catch((e: any) => { |
|
props.dispatch({ |
|
type: RegisterWindowStateActions.SetStatus, |
|
value: RegistrationStatus.Unsuccessful, |
|
}) |
|
}) |
|
} |
|
|
|
return <Box width="100%" justifyContent="center" display="flex" flexWrap="wrap"> |
|
<Box |
|
m={1} |
|
mt={4} |
|
width="500px" |
|
> |
|
<Paper> |
|
<Box p={3}> |
|
<Typography variant="h5">Sign up</Typography> |
|
<form noValidate onSubmit={onSubmit}> |
|
<TextField |
|
variant="outlined" |
|
margin="normal" |
|
required |
|
fullWidth |
|
id="email" |
|
label="Email" |
|
name="email" |
|
autoFocus |
|
onInput={(e: any) => props.dispatch({ |
|
type: RegisterWindowStateActions.SetEmail, |
|
value: e.target.value |
|
})} |
|
/> |
|
<TextField |
|
variant="outlined" |
|
margin="normal" |
|
required |
|
fullWidth |
|
id="password" |
|
label="Password" |
|
name="password" |
|
type="password" |
|
onInput={(e: any) => props.dispatch({ |
|
type: RegisterWindowStateActions.SetPassword, |
|
value: e.target.value |
|
})} |
|
/> |
|
{props.state.status === RegistrationStatus.Successful && <Alert severity="success"> |
|
Registration successful! Please {<Link to="/login">sign in</Link>} to continue. |
|
</Alert> |
|
} |
|
{props.state.status === RegistrationStatus.Unsuccessful && <Alert severity="error"> |
|
Registration failed - please check your inputs and try again. |
|
</Alert> |
|
} |
|
{props.state.status !== RegistrationStatus.Successful && <Button |
|
type="submit" |
|
fullWidth |
|
variant="outlined" |
|
color="primary" |
|
>Sign up</Button>} |
|
<Box display="flex" alignItems="center" mt={2}> |
|
<Typography>Already have an account?</Typography> |
|
<Box flexGrow={1} ml={2}><Button |
|
onClick={() => history.replace("/login")} |
|
fullWidth |
|
variant="outlined" |
|
color="primary" |
|
>Sign in</Button></Box> |
|
</Box> |
|
</form> |
|
</Box> |
|
</Paper> |
|
</Box> |
|
</Box> |
|
} |