Skip to content

Instantly share code, notes, and snippets.

@krnbr
Last active August 13, 2019 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krnbr/42cd4816416e88ce7e6b2af02f1d31b5 to your computer and use it in GitHub Desktop.
Save krnbr/42cd4816416e88ce7e6b2af02f1d31b5 to your computer and use it in GitHub Desktop.
import React, {useEffect, useLayoutEffect, useRef, useState} from 'react';
import {Button,CircularProgress,CssBaseline,TextField,Grid,Container,Theme,makeStyles,Box,FormHelperText,SnackbarContent,Snackbar,Icon,IconButton} from '@material-ui/core';
/*import Link from '@material-ui/core/Link';*/
/*import {makeStyles} from '@material-ui/core/styles';*/
import defaultTheme from '../src/theme';
import {ThemeProvider} from '@material-ui/styles';
import Logo from "../src/components/logo";
import {PasswordDto, RecaptchaDto, RegisterDto, UserDto, RePasswordDto} from "../models/RegisterDto";
import {NextPage} from "next";
import '../styles/signin.scss';
import Link from 'next/link';
import ReCAPTCHA from "react-google-recaptcha";
import Router from 'next/router'
import clsx from 'clsx';
import CloseIcon from '@material-ui/icons/Close';
const useStyles = makeStyles((theme: Theme) => {
return {
body: {
backgroundImage: "url('/static/images/escheresque.png')",
backgroundRepeat:'repeat'
},
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: defaultTheme.palette.secondary.main ? defaultTheme.palette.secondary.main : theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1),
},
error: {
backgroundColor: "#ff6e63",
},
message: {
display: 'flex',
alignItems: 'center',
},
};
});
let registerDto: RegisterDto = new RegisterDto();
let userDto: UserDto = registerDto.username;
let passwordDto: PasswordDto = registerDto.password;
let rePasswordDto: RePasswordDto = registerDto.repassword;
let recaptcha: RecaptchaDto = registerDto.recaptcha;
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
const Register: NextPage = (props:any) => {
const [registerFormData, setRegisterFormData] = useState<RegisterDto>(registerDto);
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const usernameInputRef = useRef({value:""});
const passwordInputRef = useRef({value:""});
const repasswordInputRef = useRef({value:""});
const recaptchaInputRef:any = useRef({});
useIsomorphicLayoutEffect(()=> {
document!.body.classList.add('signin');
console.log('I am about to render register page!');
setRegisterFormData({...registerDto});
},[]);
const handleRouteChange = url => {
console.log('App is changing to: ', url);
setRegisterFormData({...registerDto});
};
useEffect(() => {
return () => {
console.log('will unmount register page!');
Router.events.on('routeChangeStart', handleRouteChange);
//setRegisterFormData({...registerDto});
};
}, []);
function handleClose(event, reason) {
setOpen(false);
}
// React.SyntheticEvent
const handleSubmit = async (event) => {
if (event) event.preventDefault();
usernameValueCheck(usernameInputRef.current!.value);
passwordValueCheck(passwordInputRef.current!.value);
console.log("recaptchaInputRef.current!.value "+ recaptchaInputRef.current.getValue());
recaptchaValueCheck(recaptchaInputRef.current.getValue());
if(registerFormData.username.valid && registerFormData.password.valid && registerFormData.recaptcha.valid){
setLoading(true);
// TODO fetch
console.log("requesting ");
console.log(recaptchaInputRef.current.getValue());
console.log("requesting ---");
const response = await fetch("/sign-up", {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username:usernameInputRef.current!.value,
password:passwordInputRef.current!.value,
recaptchaResponse:recaptchaInputRef.current.getValue(),
})
});
if(response.ok) {
const json = await response.json();
console.log("response " + JSON.stringify(json));
setLoading(false);
// TODO redirect appropriate
Router.push('/');
} else {
const json = await response.json();
console.log("error response " + JSON.stringify(json));
setLoading(false);
setOpen(true);
recaptchaInputRef.current.reset();
}
}
/*setIsSubmitting(true);
setErrors(validate(values));*/
};
const onChange = (value) => {
console.log("Captcha value:", value);
recaptchaValueCheck(value);
}
const onExpired = () => {
console.log("Captcha expired value:", recaptchaInputRef.current.getValue());
recaptchaValueCheck(recaptchaInputRef.current.getValue());
}
const handleChange = (event) => {
if (event) event.preventDefault();
console.log("val of " + JSON.stringify(event.target.id));
if (event.target.id === registerFormData.username.id) {
if (event.target.value.match("^[a-zA-Z0-9]+$")) {
console.log('username changed value');
userDto.valid = true;
} else {
console.log('username changed value and doesnot matches!!');
userDto.valid = false;
}
userDto.value = event.target.value;
setRegisterFormData({
...registerDto,
username: userDto
});
//setFormData(signInDto);
} else if (event.target.id === registerFormData.password.id) {
passwordValueCheck(event.target.value);
}
};
const usernameOnFocus = (event) => {
usernameValueCheck(event.target.value);
}
const usernameValueCheck = (value) => {
if (value.match("^[a-zA-Z0-9]+$")) {
console.log('username changed value');
userDto.valid = true;
} else {
console.log('username changed value and doesnot matches!!');
userDto.valid = false;
}
userDto.value = value;
setRegisterFormData({
...registerDto,
username: userDto
});
}
const passwordOnFocus = (event) => {
passwordValueCheck(event.target.value);
}
const repasswordOnFocus = (event) => {
repasswordValueCheck(event.target.value);
}
const passwordValueCheck = (value) => {
if (value && (value !== null || value !== "")) {
console.log('password changed value');
passwordDto.valid = true;
} else {
console.log('password changed value and does not matches!!');
passwordDto.valid = false;
}
passwordDto.value = value;
setRegisterFormData({
...registerDto,
password: passwordDto
});
}
const repasswordValueCheck = (value) => {
if (value && (value !== null || value !== "")) {
console.log('password changed value');
passwordDto.valid = true;
} else {
console.log('password changed value and does not matches!!');
passwordDto.valid = false;
}
passwordDto.value = value;
setRegisterFormData({
...registerDto,
password: passwordDto
});
}
const recaptchaValueCheck = (value) => {
if (value && (value !== null || value.trim() !== "")) {
console.log('recaptcha changed value');
recaptcha.valid = true;
} else {
console.log('recaptcha changed value and does not matches!!');
recaptcha.valid = false;
}
recaptcha.value = value;
setRegisterFormData({
...registerDto,
recaptcha: recaptcha
});
}
const handlerSignin = () => {
Router.push({
pathname: '/login',
query: { recaptchaKey: props.recaptchaKey }
});
};
const classes = useStyles(props);
return (
<React.Fragment>
<div id="color-overlay"></div>
<Container component="main" maxWidth="xs">
{/*<Logo style={{marginTop: 50, marginBottom: -20, marginLeft: "auto", marginRight: "auto", display: "block"}}/>*/}
<Box boxShadow={3} padding="25px" marginTop="15px" height="100%" bgcolor={"#e8e8e8"}>
<CssBaseline/>
<Logo style={{
margin: "-15px auto -85px",
display: "block"
}}/>
{/*<Typography component="h1" variant="h5">
Sign in
</Typography>*/}
<div className={classes.paper}>
<form className={classes.form} noValidate autoComplete="none" onSubmit={e => handleSubmit(e)}>
<input autoComplete="false" name="hidden" type="text" style={{display: 'none'}}/>
<ThemeProvider theme={defaultTheme}>
<TextField
margin="normal"
required
fullWidth
id="username"
label="Username"
name="username"
autoComplete="off"
autoFocus
/*onFocus={e => usernameOnFocus(e)}*/
onChange={e => handleChange(e)}
error={!registerFormData.username.valid}
helperText={
!registerFormData.username.valid ?
registerFormData.username.requiredMessage : ''
}
inputRef={usernameInputRef}
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="off"
onChange={e => handleChange(e)}
onFocus={e => passwordOnFocus(e)}
error={!registerFormData.password.valid}
helperText={
!registerFormData.password.valid ?
registerFormData.password.requiredMessage : ''
}
inputRef={passwordInputRef}
/>
<TextField
margin="normal"
required
fullWidth
name="repassword"
label="Re-enter Password"
type="repassword"
id="repassword"
autoComplete="off"
onChange={e => handleChange(e)}
onFocus={e => repasswordOnFocus(e)}
error={!registerFormData.repassword.valid}
helperText={
!registerFormData.repassword.valid ?
registerFormData.repassword.requiredMessage : ''
}
inputRef={repasswordInputRef}
/>
{/*not required as not going to support now*/}
{/*<FormControlLabel
control={<Checkbox value="remember" color="primary"/>}
label="Remember me"
color="#0099f8"
style={{marginTop: 20}}
/>*/}
<div id={"captchaContainer"} style={
{
display:"table",
margin: "0 auto",
marginTop:25,
marginBottom: 15,
position:'relative',
}
}>
<ReCAPTCHA
ref={recaptchaInputRef}
sitekey={props.recaptchaKey}
onChange={ onChange }
onExpired={ onExpired }
/>
{
!registerFormData.recaptcha.valid?
<FormHelperText error={true} > {/*style={{display:'contents', position:'absolute'}}*/}
Human verification required
</FormHelperText>:''
}
</div>
<div>
{/*<Snackbar open={true}>
<SnackbarContent color={"red"} message={"Unable to signin with provided credentials!!"}>
</SnackbarContent>
</Snackbar>*/}
{/*<Snackbar
open={open}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
autoHideDuration={20000}
>*/}
{ open &&
<SnackbarContent
className={classes.error}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{"Wrong credentials!!"}
</span>
}
action={[
<IconButton key="close" aria-label="close" color="inherit" onClick={(e)=>handleClose(e,'')} >
<CloseIcon className={classes.icon} />
</IconButton>,
]}
/>
}
{/*</Snackbar>*/}
</div>
<div style={{position:'relative'}}>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
style={{marginTop: 30}}
disabled={loading}
>
Register
</Button>
{ loading && <CircularProgress size={24} className="circularProgressButton" color="primary" />}
</div>
</ThemeProvider>
<Grid container>
<Grid item xs>
{/*<Link href="" variant="body2">
Forgot password?
</Link>*/}
<Link href="/" as={`/`}>
<a className={"anchor"}>Forgot password?</a>
</Link>
</Grid>
<Grid item>
{/*<mLink href="" variant="body2">
{"Don't have an account? Sign Up"}
</mLink>*/}
<Link href={{pathname: '/login', query: {recaptchaKey: props.recaptchaKey}}} as={"/login"}>
<a className={"anchor"} onClick={handlerSignin}>Already have an account? Sign in</a>
</Link>
</Grid>
</Grid>
</form>
</div>
</Box>
</Container>
</React.Fragment>
);
};
Register.getInitialProps = async function(context) {
const { recaptchaKey } = context.query;
return { recaptchaKey, registerDto };
};
export default Register;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment