Skip to content
Open
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
16 changes: 16 additions & 0 deletions .history/src/__tests__/components/app.test_20200601125027.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import { Provider } from 'react-redux';
import App from '../../app.js';
import store from '../../redux/store.js';


it('renders app component without crashing', () => {
shallow(<App />);
});

it('renders entire app without crashing', () => {
mount(<Provider store={store}>
<App />
</Provider>);
});
16 changes: 16 additions & 0 deletions .history/src/__tests__/components/app.test_20200610111723.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import { Provider } from 'react-redux';
import App from '../../app.js';
import store from '../../redux/store.js';


it('renders app component without crashing', () => {
shallow(<App />);
});

it('renders entire app without crashing', () => {
mount(<Provider store={store}>
<App />
</Provider>);
});
16 changes: 16 additions & 0 deletions .history/src/__tests__/components/app.test_20200610111724.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import { Provider } from 'react-redux';
import App from '../../app.js';
import store from '../../redux/store.js';


it('renders app component without crashing', () => {
shallow(<App />);
});

it('renders entire app without crashing', () => {
mount(<Provider store={store}>
<App />
</Provider>);
});
19 changes: 19 additions & 0 deletions .history/src/api/api_20200601125027.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// axiosconfig.js
import axios from 'axios';
import store from '../redux/store.js';

// configure base url
const api = axios.create({
baseURL: 'https://edukolab-api-team-099-b-li6nmp.herokuapp.com/v1'
});

// intercept requests and add authorization token
api.interceptors.request.use((config) => {
const { token } = store.getState().auth;
if (token) {
config.headers.authorization = `Bearer ${token}`;
}
return config;
});

export default api;
19 changes: 19 additions & 0 deletions .history/src/api/api_20200610111716.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// axiosconfig.js
import axios from 'axios';
import store from '../redux/store.js';

// configure base url
const api = axios.create({
baseURL: 'https://edukolab-api-team-099-b-li6nmp.herokuapp.com/v1'
});

// intercept requests and add authorization token
api.interceptors.request.use((config) => {
const { token } = store.getState().auth;
if (token) {
config.headers.authorization = `Bearer ${token}`;
}
return config;
});

export default api;
19 changes: 19 additions & 0 deletions .history/src/api/api_20200610111717.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// axiosconfig.js
import axios from 'axios';
import store from '../redux/store.js';

// configure base url
const api = axios.create({
baseURL: 'https://edukolab-api-team-099-b-li6nmp.herokuapp.com/v1'
});

// intercept requests and add authorization token
api.interceptors.request.use((config) => {
const { token } = store.getState().auth;
if (token) {
config.headers.authorization = `Bearer ${token}`;
}
return config;
});

export default api;
142 changes: 142 additions & 0 deletions .history/src/components/auth/authForm_20200601125027.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAddressCard, faCheckCircle } from '@fortawesome/free-regular-svg-icons';

import { faLock, faTimes } from '@fortawesome/free-solid-svg-icons';
import { Link } from 'react-router-dom';
import { Field, reduxForm } from 'redux-form';

import '../../assets/css/auth/authForm.css';

class AuthForm extends Component {
static propTypes = {
handleSubmit: PropTypes.func
};

renderValidateIcon = (touched, error) => {
let className = null;
let icon = null;
if (touched) {
className = error === undefined ? 'text-success' : 'text-danger';
icon = error === undefined ? faCheckCircle : faTimes;

return <FontAwesomeIcon className={className} icon={icon} />;
}
return false;
}

renderField = ({
input, label, type, placeholder, icon, action, meta: { touched, error, warning }
}) => (

<div className="col-12 form-holder">
<div className="d-flex align-items-center">
<div className="form-icon">
<FontAwesomeIcon icon={icon} />
</div>
<div className="flex-grow-1">
<label htmlFor={`${action}${input.name}`}>{label}</label>
<input
{...input}
component="input"
type={type}
className="form-control"
id={`${action}${input.name}`}
placeholder={placeholder}
autoComplete="off"
/>
</div>
<div className="form-validation-response">
{this.renderValidateIcon(touched, error)}
</div>
</div>
{ touched ? (
touched
&& (error && <small className="form-info text-danger">{error}</small>))
: warning && <small className="form-info text-info">{warning}</small>}
</div>
);

render() {
const { handleSubmit } = this.props;

return (
<form onSubmit={handleSubmit} autoComplete="off">
<h2 className="mb-0">Welcome Back</h2>
<p>
Login to EduKolab{' '}
<span role="img" aria-label="smiley-face-wink">
&#128521;
</span>
</p>
<div className="form-row">
<Field action='login' name="contact" type="text" component={this.renderField} label="contact" placeholder="e.g: 08103459871" icon={faAddressCard} />
</div>
<div className="form-row">
<Field action='login' name="password" type="password" component={this.renderField} label="password" placeholder="Type Here" icon={faLock} />
</div>

<div className="button-group">
<button className="btn btn-auth btn-auth-main" type="submit">
Login
</button>
<Link className="btn btn-auth btn-auth-side" to="/register" role="button">
Create Account
</Link>
</div>
</form>
);
}
}

const warn = () => {
const warnings = {
contact: 'Phone number or email address',
password: 'Forgot password?'
};

return warnings;
};

const validate = (authUser) => {
const errors = {};
if (!authUser.fName) {
errors.fName = 'First Name is required';
}
if (!authUser.lName) {
errors.lName = 'Family Name is required';
}

if (!authUser.contact) {
errors.contact = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(authUser.contact)) {
errors.contact = authUser.contact.length === 11 && authUser.contact.split('')[0] === '0'
? undefined
: 'A valid email address or phone number is required';
}

if (!authUser.password) {
errors.password = 'Required';
} else if (!/\d/.test(authUser.password)) {
errors.password = 'Password must contain a number';
} else if (!/[A-Z]/.test(authUser.password)) {
errors.password = 'Password must contain an upperCase letter';
} else if (authUser.password.length < 6) {
errors.password = 'Password must be at least 6 characters long';
}

if (!authUser.cpassword) {
errors.cpassword = 'Required';
} else if (authUser.cpassword !== authUser.password) {
errors.cpassword = 'Passwords must match';
}

if (!authUser.role) {
errors.age = 'Required';
}

return errors;
};

export default reduxForm({ form: 'authForm', validate, warn })(AuthForm);
142 changes: 142 additions & 0 deletions .history/src/components/auth/authForm_20200610111645.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAddressCard, faCheckCircle } from '@fortawesome/free-regular-svg-icons';

import { faLock, faTimes } from '@fortawesome/free-solid-svg-icons';
import { Link } from 'react-router-dom';
import { Field, reduxForm } from 'redux-form';

import '../../assets/css/auth/authForm.css';

class AuthForm extends Component {
static propTypes = {
handleSubmit: PropTypes.func
};

renderValidateIcon = (touched, error) => {
let className = null;
let icon = null;
if (touched) {
className = error === undefined ? 'text-success' : 'text-danger';
icon = error === undefined ? faCheckCircle : faTimes;

return <FontAwesomeIcon className={className} icon={icon} />;
}
return false;
}

renderField = ({
input, label, type, placeholder, icon, action, meta: { touched, error, warning }
}) => (

<div className="col-12 form-holder">
<div className="d-flex align-items-center">
<div className="form-icon">
<FontAwesomeIcon icon={icon} />
</div>
<div className="flex-grow-1">
<label htmlFor={`${action}${input.name}`}>{label}</label>
<input
{...input}
component="input"
type={type}
className="form-control"
id={`${action}${input.name}`}
placeholder={placeholder}
autoComplete="off"
/>
</div>
<div className="form-validation-response">
{this.renderValidateIcon(touched, error)}
</div>
</div>
{ touched ? (
touched
&& (error && <small className="form-info text-danger">{error}</small>))
: warning && <small className="form-info text-info">{warning}</small>}
</div>
);

render() {
const { handleSubmit } = this.props;

return (
<form onSubmit={handleSubmit} autoComplete="off">
<h2 className="mb-0">Welcome Back</h2>
<p>
Login to EduKolab{' '}
<span role="img" aria-label="smiley-face-wink">
&#128521;
</span>
</p>
<div className="form-row">
<Field action='login' name="contact" type="text" component={this.renderField} label="contact" placeholder="e.g: 08103459871" icon={faAddressCard} />
</div>
<div className="form-row">
<Field action='login' name="password" type="password" component={this.renderField} label="password" placeholder="Type Here" icon={faLock} />
</div>

<div className="button-group">
<button className="btn btn-auth btn-auth-main" type="submit">
Login
</button>
<Link className="btn btn-auth btn-auth-side" to="/register" role="button">
Create Account
</Link>
</div>
</form>
);
}
}

const warn = () => {
const warnings = {
contact: 'Phone number or email address',
password: 'Forgot password?'
};

return warnings;
};

const validate = (authUser) => {
const errors = {};
if (!authUser.fName) {
errors.fName = 'First Name is required';
}
if (!authUser.lName) {
errors.lName = 'Family Name is required';
}

if (!authUser.contact) {
errors.contact = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(authUser.contact)) {
errors.contact = authUser.contact.length === 11 && authUser.contact.split('')[0] === '0'
? undefined
: 'A valid email address or phone number is required';
}

if (!authUser.password) {
errors.password = 'Required';
} else if (!/\d/.test(authUser.password)) {
errors.password = 'Password must contain a number';
} else if (!/[A-Z]/.test(authUser.password)) {
errors.password = 'Password must contain an upperCase letter';
} else if (authUser.password.length < 6) {
errors.password = 'Password must be at least 6 characters long';
}

if (!authUser.cpassword) {
errors.cpassword = 'Required';
} else if (authUser.cpassword !== authUser.password) {
errors.cpassword = 'Passwords must match';
}

if (!authUser.role) {
errors.age = 'Required';
}

return errors;
};

export default reduxForm({ form: 'authForm', validate, warn })(AuthForm);
Loading