Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signup #36

Merged
merged 24 commits into from
Nov 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ Django API server for the **Triplannet** frontend
# setup for virtual environment
pip install -r requirements.txt

# run server
# migrate and run server
cd triplannet
python manage.py migrate
python manage.py runserver

# You can run test suite by typing:
Expand Down
87 changes: 87 additions & 0 deletions frontend/src/components/auth/SignupForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import styled from 'styled-components';
import palette from '../../lib/styles/palette';

const useStyles = makeStyles((theme) => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
}));


function ValidationTextFields(props) {
const classes = useStyles();

return (
<form className={classes.container} noValidate autoComplete="off">
<div className="ValidationTextFields">
<TextField
error
label={props.label}
name={props.name}
type={props.type}
value={props.value}
helperText={props.helperText}
onChange={props.onChange}
className={classes.textField}
margin="normal"
/>
</div>

</form>
);
}

function UncontrolledTextField(props) {
const classes = useStyles();

return (
<form className={classes.container} noValidate autoComplete="off">
<div className="UncontrolledTextField">
<TextField
required
label={props.label}
name={props.name}
type={props.type}
value={props.value}
helperText={props.helperText}
onChange={props.onChange}
className={classes.textField}
margin="normal"
/>
</div>
</form>
);
}

function FormControl(props) {
return props.validated !== false
? UncontrolledTextField(props)
: ValidationTextFields(props);
}

const Footer = styled.div`
margin-top: 2rem;
text-align: right;
a {
color: ${palette.gray[6]};
text-decoration: underline;
&:hover {
color: ${palette.gray[9]};
}
}
`;


export {
FormControl,
Footer,
};
17 changes: 17 additions & 0 deletions frontend/src/components/auth/SignupForm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { shallow } from 'enzyme';
import { FormControl, Footer } from './SignupForm';


describe('<SignupForm />', () => {
it('should render FormControl1 without errors', () => {
const component = shallow(<FormControl />);
const wrapper = component.find('.UncontrolledTextField');
expect(wrapper.length).toBe(1);
});
it('should render FormControl2 without errors', () => {
const component = shallow(<FormControl validated={false} />);
const wrapper = component.find('.ValidationTextFields');
expect(wrapper.length).toBe(1);
});
});
250 changes: 188 additions & 62 deletions frontend/src/containers/auth/SignupForm.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,188 @@
import React, { Component } from 'react';

import { connect } from 'react-redux';
import * as actionCreators from '../../store/actions/index';

import AuthForm from '../../components/auth/AuthForm';

class SignupForm extends Component {
state = {
email: '',
password: '',
// password_confirm: '',
nickname: '',
};

componentDidMount() {}

onChange = (e) => {
const { value, name } = e.target;
this.setState({ [name]: value });
};

onSubmit = (e) => {
e.preventDefault();
this.props.onSignup(
this.state.email,
this.state.password,
this.state.nickname,
);
};

render() {
return (
<AuthForm
type="signup"
form={this.state}
onChange={this.onChange}
onSubmit={this.onSubmit}
error={null}
/>
);
}
}

const mapDispatchToProps = (dispatch) => {
return {
onSignup: (email, password, nickname) => {
dispatch(
actionCreators.signUp({
email: email,
password: password,
nickname: nickname,
}),
);
},
};
};

export default connect(
null,
mapDispatchToProps,
)(SignupForm);
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import axios from 'axios';


import * as actionCreators from '../../store/actions/index';

import Button from '../../components/common/Button';
import { FormControl, Footer } from '../../components/auth/SignupForm';

class SignupForm extends Component {
state = {
email: '',
password: '',
password_confirm: '',
nickname: '',
password_checked: null,
email_checked: null,
nickname_checked: null,
email_helperText: '',
password_helperText: '',
nickname_helperText: '',
};

onChange = (e) => {
const { value, name } = e.target;
this.setState({ [name]: value });
this.setState({ [`${name}_checked`]: null });
this.setState({ [`${name}_helperText`]: null });
};


onChangePassword = (e) => {
const { value, name } = e.target;
this.setState({ [name]: value });

let password_checked;
if (name === 'password') {
if (!this.state.password_confirm) {
this.setState({ password_checked: null });
this.setState({ password_helperText: 'Enter your password' });
return;
}
const password = value;
password_checked = (password === this.state.password_confirm);
} else if (name === 'password_confirm') {
if (!this.state.password) {
this.setState({ password_checked: null });
this.setState({ password_helperText: 'Enter your password' });
return;
}

const password_confirm = value;
password_checked = (password_confirm === this.state.password);
}
this.setState({ password_checked: password_checked });
this.setState({ password_helperText: (password_checked ? 'Valid Password' : 'Must match password') });
}

clickCheckEmail = () => {
if (!this.state.email) {
this.setState({ email_checked: false });
this.setState({ email_helperText: 'Enter your email' });
return;
}

let email_checked = null;
axios.get(`/api/user/check/email/${this.state.email}`)
.then((res) => {
email_checked = !res.data.check;
this.setState({ email_checked: email_checked });
this.setState({ email_helperText: (email_checked ? 'Available Email' : 'Email already in use. Try another') });
dreamsh19 marked this conversation as resolved.
Show resolved Hide resolved
});
}

clickCheckNickname = () => {
if (!this.state.nickname) {
this.setState({ nickname_checked: false });
this.setState({ nickname_helperText: 'Enter your nickname' });
return;
}

let nickname_checked = null;
axios.get(`/api/user/check/nickname/${this.state.nickname}`)
.then((res) => {
nickname_checked = !res.data.check;
this.setState({ nickname_checked: nickname_checked });
this.setState({ nickname_helperText: (nickname_checked ? 'Available Nickname' : 'Nickname already in use. Try another') });
});
}


clickSubmit = () => {
if (this.state.email_checked && this.state.password_checked && this.state.nickname_checked) {
const newUserInfo = {
email: this.state.email,
password: this.state.password,
nickname: this.state.nickname,
};
this.props.onSignup(newUserInfo);
dreamsh19 marked this conversation as resolved.
Show resolved Hide resolved
} else {
if (!this.state.password || !this.state.password_confirm) {
this.setState({ password_checked: false });
this.setState({ password_helperText: 'Enter your password' });
}
this.clickCheckEmail();
this.clickCheckNickname();
}
}

render() {
return (
<div className="SignupForm">
<div>
<FormControl
id="email"
validated={this.state.email_checked}
label="Email"
name="email"
value={this.state.email}
helperText={this.state.email_helperText}
onChange={this.onChange}
/>
<Button id="checkEmail" onClick={this.clickCheckEmail}>Check Email</Button>
<FormControl
id="password"
// validated={this.state.password_checked}
label="Password"
name="password"
type="password"
value={this.state.password}
// helperText={this.state.password_helperText}
onChange={this.onChangePassword}
/>
<FormControl
id="password_confirm"
validated={this.state.password_checked}
label="Password Confirmation"
name="password_confirm"
type="password"
value={this.state.password_confirm}
onChange={this.onChangePassword}
helperText={this.state.password_helperText}
/>
<FormControl
id="nickname"
validated={this.state.nickname_checked}
label="Nickname"
name="nickname"
value={this.state.nickname}
helperText={this.state.nickname_helperText}
onChange={this.onChange}
/>
<Button id="checkNickname" onClick={this.clickCheckNickname}>Check Nickname</Button>
</div>
<div>
<br />
<Button
id="submit"
onClick={this.clickSubmit}
>Sign in
</Button>
<br />

</div>
<Footer>
<Link to="/login">Log In</Link>
</Footer>
</div>
);
}
}
const mapDispatchToProps = (dispatch) => {
return {
onSignup: (userInfo) => {
dispatch(
actionCreators.signup(userInfo),
);
},
};
};


export default connect(
null,
mapDispatchToProps,
)(SignupForm);
Loading