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

Feature/194 #219

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
53 changes: 53 additions & 0 deletions client/src/backendCalls/auth/registerUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Registers a user with the given email, password, first and last name.
* If either first_name or last_name are undefined, the user will be registered
* without a first or last name respectively.
*/

import store from '../../store.js';

export async function registerUser(email, password, first_name, last_name) {
var details = {
'email': email,
'password': password,
'first_name': first_name,
'last_name': last_name
}

var formBody = [];
for (var property in details) {
if (details[property] === undefined) {
continue;
}
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + '=' + encodedValue);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use a string template here

}
formBody = formBody.join('&');

const response = await fetch(store.authApiBase + '/user', {
method: 'POST',
mode: 'cors',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formBody,
});

const body = await response.json();

console.log(body);
if (response.status !== 201) {
if (body.error) {
return body.error;
}
else {
return JSON.stringify(body);
}
} else {
return 200;
}
}

export default registerUser
45 changes: 45 additions & 0 deletions client/src/backendCalls/auth/userLogin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import store from '../../store.js';

export async function userLogin(email, password) {
var details = {
'email': email,
'password': password,
}

var formBody = [];
for (var property in details) {
if (details[property] === undefined) {
continue;
}
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');

const response = await fetch(store.authApiBase + '/user/login', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formBody,
});

const body = await response.json();

console.log(body);
if (response.status !== 201) {
if (body.error) {
return body.error;
}
else {
document.cookie = body.token;
return JSON.stringify(body);
}
} else {
return 200;
}
}

export default userLogin
1 change: 1 addition & 0 deletions client/src/store.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const store = {
searchResults: [],
apiBase: 'https://internado.ubclaunchpad.com',
authApiBase: 'http://localhost:5050'
};
export default store;
12 changes: 12 additions & 0 deletions client/src/store.js.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const store = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this file appeared because of a Git issue, it should be safe to delete

searchResults: [],
<<<<<<< HEAD
apiBase: 'http://localhost:5000',
authApiBase: 'http://localhost:5050'
||||||| merged common ancestors
apiBase: 'http://localhost:5000'
=======
apiBase: 'https://internado.ubclaunchpad.com',
>>>>>>> develop
};
export default store;
108 changes: 77 additions & 31 deletions client/src/views/Login.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,81 @@
import React from 'react';
import React, {Component} from 'react';
import '../sass/LoginSignup.scss';
import { Button, Form, Grid, Header, Message, Segment } from 'semantic-ui-react';
import userLogin from '../backendCalls/auth/userLogin.js';
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
formData: new Map([
['email', ''],
['password', ''],
]),
result: ''
};
}

const LoginForm = () => (
<div className='login-form'>
<Grid textAlign='center' style={{ height: '100%' }} verticalAlign='middle'>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='black' textAlign='center'>
Log in
</Header>
<Form size='large'>
<Segment raised>
<Form.Input fluid icon='user' iconPosition='left' placeholder='Username/email' />
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Password'
type='password'
/>
<Button color='blue' fluid size='large'>
Login
</Button>
</Segment>
</Form>
<Message>
Don't have an Account? <a href='/signup'>Sign Up</a>
</Message>
</Grid.Column>
</Grid>
</div>
)
handleDataChange = (e, item) => {
let newData = this.state.formData;
newData[item] = e.target.value;
this.setState({formData: newData});
};

export default LoginForm;
handleSubmit = async(e) => {
let data = this.state.formData;
let response = await userLogin(data['email'], data['password']);
let responseHTML = '';
try {
// If the login failed, the next line will fail to parse response
JSON.parse(response);
responseHTML = 'Logged in successfully';
} catch {
// If the login failed, response will be a string describing the failure
responseHTML = <font color='#ff0000'> {response} </font>;
}
this.setState({result: responseHTML});
};

render() {
return (
<div className='login-form'>
<Grid textAlign='center' style={{ height: '100%' }} verticalAlign='middle'>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='black' textAlign='center'>
Log in
</Header>
<Form size='large'>
<Segment raised>
<Form.Input fluid icon='user'
iconPosition='left'
placeholder='email'
value={this.state.formData['email']}
onChange={(e) => this.handleDataChange(e, 'email')}
/>
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Password'
type='password'
value={this.state.formData['password']}
onChange={(e) => this.handleDataChange(e, 'password')}
/>
<Button color='blue' fluid size='large' onClick={this.handleSubmit}>
Login
</Button>
</Segment>
</Form>
<p>
{this.state.result}
</p>
<Message>
Don't have an Account? <a href='/signup'>Sign Up</a>
</Message>
</Grid.Column>
</Grid>
</div>
)
}
}

export default LoginForm;
140 changes: 101 additions & 39 deletions client/src/views/SignUp.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,105 @@
import React from 'react';
import React, {Component} from 'react';
import '../sass/LoginSignup.scss';
import { Button, Form, Grid, Header, Message, Segment } from 'semantic-ui-react';
import registerUser from '../backendCalls/auth/registerUser.js';

const SignUpForm = () => (
<div className='signup-form'>
<Grid textAlign='center' style={{ height: '100%' }} verticalAlign='middle'>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='black' textAlign='center'>
Sign up
</Header>
<Form size='large'>
<Segment raise>
<Form.Input fluid icon='user' iconPosition='left' placeholder='Username/email' />
<Form.Input fluid icon='mail' iconPosition='left' placeholder='Email' />
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Password'
type='password'
/>
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Repeat password'
type='password'
/>
<Button color='blue' fluid size='large'>
Create your account
</Button>
</Segment>
</Form>
<Message>
Already a member? <a href='/login'>Log in</a>
</Message>
</Grid.Column>
</Grid>
</div>
)
class SignUpForm extends Component {
constructor(props) {
super(props);
this.state = {
formData: new Map([
['username', ''],
['email', ''],
['password', ''],
['repeatPassword', '']
]),
result: ''
};
}

export default SignUpForm;
handleDataChange = (e, item) => {
let newData = this.state.formData;
newData[item] = e.target.value;
this.setState({formData: newData});
};

handleSubmit = async(e) => {
let data = this.state.formData;
if (data['password'] !== data['repeatPassword']) {
this.setState({result: <font color='#ff0000'> Passwords do not match</font>})

} else {
let response = await registerUser(data['email'], data['password'], data['username'], undefined);
let responseHTML = '';
if (response === 200) {
responseHTML = 'Account successfully created';
} else {
responseHTML = <font color='#ff0000'> {response} </font>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that you set color='blue' on a button in another part of the code, is it possible to do color='red' here?

}
this.setState({result: responseHTML});
}
};

render() {
return (
<div className='signup-form'>
<Grid textAlign='center' style={{ height: '100%' }} verticalAlign='middle'>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='black' textAlign='center'>
Sign up
</Header>
<Form size='large'>
<Segment raise>
<Form.Input
fluid
icon='user'
iconPosition='left'
placeholder='Username/email'
value={this.state.formData['username']}
onChange={(e) => this.handleDataChange(e, 'username')}
/>
<Form.Input
fluid
icon='mail'
iconPosition='left'
placeholder='Email'
value={this.state.formData['email']}
onChange={(e) => this.handleDataChange(e, 'email')}
/>
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Password'
type='password'
value={this.state.formData['password']}
onChange={(e) => this.handleDataChange(e, 'password')}
/>
<Form.Input
fluid
icon='key'
iconPosition='left'
placeholder='Repeat password'
type='password'
value={this.state.formData['repeatPassword']}
onChange={(e) => this.handleDataChange(e, 'repeatPassword')}
/>
<Button color='blue' fluid size='large' onClick={this.handleSubmit}>
Create your account
</Button>
</Segment>
</Form>
<p>
{this.state.result}
</p>
<Message>
Already a member? <a href='/login'>Log in</a>
</Message>
</Grid.Column>
</Grid>
</div>
)
}
}

export default SignUpForm;