Updated plop templates and added mobile first components
This commit is contained in:
3
src/app/components/atoms/Button/Button.component.scss
Normal file
3
src/app/components/atoms/Button/Button.component.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.c-Button {
|
||||
|
||||
}
|
||||
20
src/app/components/atoms/Button/Button.jsx
Normal file
20
src/app/components/atoms/Button/Button.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Button.component.scss'
|
||||
|
||||
const Button = props => {
|
||||
return (
|
||||
<div className='c-Button'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Button.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Button.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Button;
|
||||
8
src/app/components/atoms/Button/Button.test.js
Normal file
8
src/app/components/atoms/Button/Button.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Button from './Button';
|
||||
|
||||
describe('Button', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/atoms/Button/index.js
Normal file
3
src/app/components/atoms/Button/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Button from './Button.jsx';
|
||||
|
||||
export default Button;
|
||||
@@ -0,0 +1,15 @@
|
||||
.c-InputField {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
// label {
|
||||
// float: left;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// margin-right: 10px;
|
||||
// }
|
||||
input[type="text"],input[type="password"] {
|
||||
padding: 5px;
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
69
src/app/components/atoms/InputField/InputField.js
Normal file
69
src/app/components/atoms/InputField/InputField.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const InputField = ({meta}) => {
|
||||
return (
|
||||
<div className='c-InputField'>
|
||||
<div
|
||||
className={`form-group row ${
|
||||
meta.container_class ? meta.container_class : ''
|
||||
}`}
|
||||
aria-required={meta.aria_required}
|
||||
>
|
||||
<label htmlFor={meta.id} className="col-12 col-sm-3 col-lg-12 col-form-label">
|
||||
{meta.validation.required.isRequired && !meta.isStandAloneField && (
|
||||
<span className="required-indicator">* </span>
|
||||
)}
|
||||
{meta.label}
|
||||
</label>
|
||||
{meta.secondaryLabel ? (
|
||||
<span className="field--label-description">{meta.secondaryLabel}</span>
|
||||
) : null}
|
||||
<div className="col-12 col-sm-9 col-12">
|
||||
{meta.error && (
|
||||
<span className="form-wrapper__field-error">{meta.errorMessage}</span>
|
||||
)}
|
||||
<input
|
||||
className={`form-control ${meta.error ? 'error' : ''}`}
|
||||
type={meta.type}
|
||||
id={meta.id}
|
||||
name={meta.name}
|
||||
data-firstname="null"
|
||||
value={
|
||||
meta.fieldValues && meta.fieldValues.stateValue !== undefined
|
||||
? meta.fieldValues.stateValue
|
||||
: meta.fieldValues.propsValue
|
||||
}
|
||||
required={meta.validation.required.isRequired ? 'required' : ''}
|
||||
minLength={meta.validation.rules.minlength}
|
||||
maxLength={meta.validation.rules.maxlength}
|
||||
placeholder={meta.placeholder}
|
||||
aria-required={meta.aria_required}
|
||||
aria-invalid={meta.aria_invalid}
|
||||
// onFocus={onBlurProp ? onBlurProp : this.onFocusHandler}
|
||||
onBlur={(e) =>
|
||||
meta.handlers.onBlurHandler(
|
||||
meta.validation,
|
||||
meta.handlers.customBlurHandler,
|
||||
e
|
||||
)
|
||||
}
|
||||
onFocus={meta.handlers.onFocusHandler}
|
||||
onChange={meta.handlers.onChangeHandler}
|
||||
style={{width: '100%'}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
InputField.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
InputField.propTypes = {
|
||||
meta: PropTypes.object
|
||||
};
|
||||
|
||||
export default InputField;
|
||||
8
src/app/components/atoms/InputField/InputField.test.js
Normal file
8
src/app/components/atoms/InputField/InputField.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import InputField from './InputField';
|
||||
|
||||
describe('InputField', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/atoms/InputField/index.js
Normal file
3
src/app/components/atoms/InputField/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import InputField from './InputField';
|
||||
|
||||
export default InputField;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-SelectOption {
|
||||
|
||||
}
|
||||
11
src/app/components/atoms/SelectOption/SelectOption.js
Normal file
11
src/app/components/atoms/SelectOption/SelectOption.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import styles from './SelectOption.component.scss';
|
||||
|
||||
const SelectOption = props => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectOption;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import SelectOption from './SelectOption';
|
||||
|
||||
describe('SelectOption', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/atoms/SelectOption/index.js
Normal file
3
src/app/components/atoms/SelectOption/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SelectOption from './SelectOption';
|
||||
|
||||
export default SelectOption;
|
||||
@@ -1,9 +1,47 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
import Header from './Header';
|
||||
import PageLoader from './PageLoader';
|
||||
import CartSummary from './molecules/CartSummary';
|
||||
import CartItem from './molecules/CartItem';
|
||||
import CartList from './molecules/CartList';
|
||||
import Footer from './molecules/Footer';
|
||||
import ProductTile from './molecules/ProductTile';
|
||||
import ProductContainer from './molecules/ProductContainer';
|
||||
import FilterModal from './molecules/FilterModal';
|
||||
import SortModal from './molecules/SortModal';
|
||||
import SortAndFilterPanel from './molecules/SortAndFilterPanel';
|
||||
import CartIcon from './molecules/CartIcon';
|
||||
import Search from './molecules/Search';
|
||||
import Jumbotron from './molecules/common/Jumbotron';
|
||||
import FormFieldContainer from './molecules/common/FormFieldContainer';
|
||||
import Form from './molecules/common/Form';
|
||||
import SocialLogin from './molecules/SocialLogin';
|
||||
import LoginForm from './molecules/LoginForm';
|
||||
import PageLoader from './molecules/PageLoader';
|
||||
import Header from './molecules/Header'
|
||||
import Button from './atoms/Button';
|
||||
import InputField from './atoms/InputField';
|
||||
import SelectOption from './atoms/SelectOption';
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
Header,
|
||||
PageLoader
|
||||
CartSummary,
|
||||
CartItem,
|
||||
CartList,
|
||||
Footer,
|
||||
ProductTile,
|
||||
ProductContainer,
|
||||
FilterModal,
|
||||
SortModal,
|
||||
Button,
|
||||
SortAndFilterPanel,
|
||||
CartIcon,
|
||||
Search,
|
||||
Jumbotron,
|
||||
FormFieldContainer,
|
||||
Form,
|
||||
Header,
|
||||
SocialLogin,
|
||||
LoginForm,
|
||||
SelectOption,
|
||||
InputField,
|
||||
PageLoader,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-CartIcon {
|
||||
|
||||
}
|
||||
19
src/app/components/molecules/CartIcon/CartIcon.jsx
Normal file
19
src/app/components/molecules/CartIcon/CartIcon.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const CartIcon = props => {
|
||||
return (
|
||||
<div className='c-CartIcon'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CartIcon.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
CartIcon.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default CartIcon;
|
||||
8
src/app/components/molecules/CartIcon/CartIcon.test.js
Normal file
8
src/app/components/molecules/CartIcon/CartIcon.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import CartIcon from './CartIcon';
|
||||
|
||||
describe('CartIcon', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/CartIcon/index.js
Normal file
3
src/app/components/molecules/CartIcon/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import CartIcon from './CartIcon.jsx';
|
||||
|
||||
export default CartIcon;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-CartItem {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/CartItem/CartItem.jsx
Normal file
20
src/app/components/molecules/CartItem/CartItem.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './CartItem.component.scss';
|
||||
|
||||
const CartItem = props => {
|
||||
return (
|
||||
<div className='c-CartItem'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CartItem.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
CartItem.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default CartItem;
|
||||
8
src/app/components/molecules/CartItem/CartItem.test.js
Normal file
8
src/app/components/molecules/CartItem/CartItem.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import CartItem from './CartItem';
|
||||
|
||||
describe('CartItem', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/CartItem/index.js
Normal file
3
src/app/components/molecules/CartItem/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import CartItem from './CartItem.jsx';
|
||||
|
||||
export default CartItem;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-CartList {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/CartList/CartList.jsx
Normal file
20
src/app/components/molecules/CartList/CartList.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './CartList.component.scss';
|
||||
|
||||
const CartList = props => {
|
||||
return (
|
||||
<div className='c-CartList'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CartList.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
CartList.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default CartList;
|
||||
8
src/app/components/molecules/CartList/CartList.test.js
Normal file
8
src/app/components/molecules/CartList/CartList.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import CartList from './CartList';
|
||||
|
||||
describe('CartList', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/CartList/index.js
Normal file
3
src/app/components/molecules/CartList/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import CartList from './CartList.jsx';
|
||||
|
||||
export default CartList;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-CartSummary {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/CartSummary/CartSummary.jsx
Normal file
20
src/app/components/molecules/CartSummary/CartSummary.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './CartSummary.component.scss';
|
||||
|
||||
const CartSummary = props => {
|
||||
return (
|
||||
<div className='c-CartSummary'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CartSummary.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
CartSummary.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default CartSummary;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import CartSummary from './CartSummary';
|
||||
|
||||
describe('CartSummary', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/CartSummary/index.js
Normal file
3
src/app/components/molecules/CartSummary/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import CartSummary from './CartSummary.jsx';
|
||||
|
||||
export default CartSummary;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-FilterModal {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/FilterModal/FilterModal.jsx
Normal file
20
src/app/components/molecules/FilterModal/FilterModal.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './FilterModal.component.scss';
|
||||
|
||||
const FilterModal = props => {
|
||||
return (
|
||||
<div className='c-FilterModal'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FilterModal.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
FilterModal.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default FilterModal;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import FilterModal from './FilterModal';
|
||||
|
||||
describe('FilterModal', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/FilterModal/index.js
Normal file
3
src/app/components/molecules/FilterModal/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import FilterModal from './FilterModal.jsx';
|
||||
|
||||
export default FilterModal;
|
||||
@@ -0,0 +1,9 @@
|
||||
.c-Footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: #222;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
20
src/app/components/molecules/Footer/Footer.jsx
Normal file
20
src/app/components/molecules/Footer/Footer.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Footer.component.scss';
|
||||
|
||||
const Footer = props => {
|
||||
return (
|
||||
<footer className='c-Footer'>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
Footer.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Footer.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
8
src/app/components/molecules/Footer/Footer.test.js
Normal file
8
src/app/components/molecules/Footer/Footer.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Footer from './Footer';
|
||||
|
||||
describe('Footer', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/Footer/index.js
Normal file
3
src/app/components/molecules/Footer/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Footer from './Footer.jsx';
|
||||
|
||||
export default Footer;
|
||||
@@ -1,10 +1,15 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Search from './../Search'
|
||||
import CartIcon from './../CartIcon'
|
||||
|
||||
const Header = props => {
|
||||
return (
|
||||
<div className='c-Header'>
|
||||
</div>
|
||||
<header className='c-Header'>
|
||||
<Search />
|
||||
<CartIcon />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import Header from './Header';
|
||||
import Header from './Header.jsx';
|
||||
|
||||
export default Header;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-LoginForm {
|
||||
padding: 1rem;
|
||||
}
|
||||
29
src/app/components/molecules/LoginForm/LoginForm.js
Normal file
29
src/app/components/molecules/LoginForm/LoginForm.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import loginFormFields from './../../../config/forms-meta/login-form.json'
|
||||
import Form from './../common/Form'
|
||||
|
||||
const LoginForm = props => {
|
||||
return (
|
||||
<div className='c-LoginForm'>
|
||||
<Form
|
||||
metaData={loginFormFields}
|
||||
context="login"
|
||||
updateFormValues={props.updateFormValues}
|
||||
updateFormErrors={props.updateFormErrors}
|
||||
formErrors={props.formErrors}
|
||||
formValues={props.formValues}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
LoginForm.propTypes = {
|
||||
updateFormValues: PropTypes.func,
|
||||
updateFormErrors: PropTypes.func,
|
||||
formValues: PropTypes.object,
|
||||
formErrors: PropTypes.object
|
||||
};
|
||||
|
||||
export default LoginForm;
|
||||
8
src/app/components/molecules/LoginForm/LoginForm.test.js
Normal file
8
src/app/components/molecules/LoginForm/LoginForm.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import LoginForm from './LoginForm';
|
||||
|
||||
describe('LoginForm', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/LoginForm/index.js
Normal file
3
src/app/components/molecules/LoginForm/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import LoginForm from './LoginForm';
|
||||
|
||||
export default LoginForm;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-ProductContainer {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './ProductContainer.component.scss';
|
||||
|
||||
const ProductContainer = props => {
|
||||
return (
|
||||
<div className='c-ProductContainer'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductContainer.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
ProductContainer.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default ProductContainer;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ProductContainer from './ProductContainer';
|
||||
|
||||
describe('ProductContainer', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/ProductContainer/index.js
Normal file
3
src/app/components/molecules/ProductContainer/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import ProductContainer from './ProductContainer.jsx';
|
||||
|
||||
export default ProductContainer;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-ProductTile {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/ProductTile/ProductTile.jsx
Normal file
20
src/app/components/molecules/ProductTile/ProductTile.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './ProductTile.component.scss';
|
||||
|
||||
const ProductTile = props => {
|
||||
return (
|
||||
<div className='c-ProductTile'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductTile.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
ProductTile.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default ProductTile;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ProductTile from './ProductTile';
|
||||
|
||||
describe('ProductTile', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/ProductTile/index.js
Normal file
3
src/app/components/molecules/ProductTile/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import ProductTile from './ProductTile.jsx';
|
||||
|
||||
export default ProductTile;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-Search {
|
||||
|
||||
}
|
||||
19
src/app/components/molecules/Search/Search.jsx
Normal file
19
src/app/components/molecules/Search/Search.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Search = props => {
|
||||
return (
|
||||
<div className='c-Search'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Search.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Search.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Search;
|
||||
8
src/app/components/molecules/Search/Search.test.js
Normal file
8
src/app/components/molecules/Search/Search.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Search from './Search';
|
||||
|
||||
describe('Search', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/Search/index.js
Normal file
3
src/app/components/molecules/Search/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Search from './Search.jsx';
|
||||
|
||||
export default Search;
|
||||
@@ -0,0 +1,10 @@
|
||||
.c-SocialLogin {
|
||||
padding: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.abcRioButtonBlue {
|
||||
background: white;
|
||||
color: #585f6b;
|
||||
}
|
||||
}
|
||||
68
src/app/components/molecules/SocialLogin/SocialLogin.jsx
Normal file
68
src/app/components/molecules/SocialLogin/SocialLogin.jsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import {withRouter} from 'react-router-dom'
|
||||
import {gapi} from 'gapi-script'
|
||||
|
||||
class SocialLogin extends React.Component{
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.width = 254
|
||||
this.height = 50
|
||||
this.onSuccess = this.onSuccess.bind(this)
|
||||
this.onFailure = this.onFailure.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
gapi && gapi.signin2 && gapi.signin2.render('g-signin2', {
|
||||
'scope': 'profile email',
|
||||
'width': this.width,
|
||||
'height': this.height,
|
||||
'longtitle': true,
|
||||
'theme': 'dark',
|
||||
'onsuccess': this.onSuccess,
|
||||
'onfailure': this.onFailure
|
||||
});
|
||||
}
|
||||
|
||||
onSuccess(googleUser) {
|
||||
console.log('Logged in as: ' + googleUser.getBasicProfile().getName());
|
||||
this.props.history.push('/view/plp')
|
||||
}
|
||||
|
||||
onFailure(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='c-SocialLogin'>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className="g-signin2" id="g-signin2"></div>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<div
|
||||
className="fb-login-button"
|
||||
data-width={this.width}
|
||||
data-height={this.height}
|
||||
data-size="large"
|
||||
data-button-type="continue_with"
|
||||
data-auto-logout-link="false"
|
||||
data-use-continue-as="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SocialLogin.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
SocialLogin.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default withRouter(SocialLogin)
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import SocialLogin from './SocialLogin';
|
||||
|
||||
describe('SocialLogin', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/SocialLogin/index.js
Normal file
3
src/app/components/molecules/SocialLogin/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SocialLogin from './SocialLogin.jsx';
|
||||
|
||||
export default SocialLogin;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-SortAndFilterPanel {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const SortAndFilterPanel = props => {
|
||||
return (
|
||||
<div className='c-SortAndFilterPanel'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SortAndFilterPanel.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
SortAndFilterPanel.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default SortAndFilterPanel;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import SortAndFilterPanel from './SortAndFilterPanel';
|
||||
|
||||
describe('SortAndFilterPanel', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/SortAndFilterPanel/index.js
Normal file
3
src/app/components/molecules/SortAndFilterPanel/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SortAndFilterPanel from './SortAndFilterPanel.jsx';
|
||||
|
||||
export default SortAndFilterPanel;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-SortModal {
|
||||
|
||||
}
|
||||
20
src/app/components/molecules/SortModal/SortModal.jsx
Normal file
20
src/app/components/molecules/SortModal/SortModal.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './SortModal.component.scss';
|
||||
|
||||
const SortModal = props => {
|
||||
return (
|
||||
<div className='c-SortModal'>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SortModal.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
SortModal.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default SortModal;
|
||||
8
src/app/components/molecules/SortModal/SortModal.test.js
Normal file
8
src/app/components/molecules/SortModal/SortModal.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import SortModal from './SortModal';
|
||||
|
||||
describe('SortModal', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/SortModal/index.js
Normal file
3
src/app/components/molecules/SortModal/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SortModal from './SortModal.jsx';
|
||||
|
||||
export default SortModal;
|
||||
@@ -0,0 +1,7 @@
|
||||
.c-Form {
|
||||
padding: 15px;
|
||||
background: #ddd;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
91
src/app/components/molecules/common/Form/Form.js
Normal file
91
src/app/components/molecules/common/Form/Form.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import FormFieldContainer from '../FormFieldContainer';
|
||||
|
||||
class Form extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
name: '',
|
||||
greeting: ''
|
||||
};
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
this.onFocusHandler = this.onFocusHandler.bind(this)
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
this.setState({ name: event.target.value });
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
// fetch(`/api/greeting?name=${encodeURIComponent(this.state.name)}`)
|
||||
// .then(response => response.json())
|
||||
// .then(state => this.setState(state));
|
||||
|
||||
}
|
||||
|
||||
onFocusHandler() {
|
||||
console.log('Parent, on focus handler')
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
context,
|
||||
fieldValues,
|
||||
formErrors,
|
||||
formValues,
|
||||
metaData,
|
||||
updateFormErrors,
|
||||
updateFormValues
|
||||
} = this.props
|
||||
// const jsonData = this.props && this.props.metaData
|
||||
const inputList = metaData && context ? Object.keys(metaData[context]) : []
|
||||
|
||||
let inputListSection =
|
||||
inputList &&
|
||||
inputList.map((item, index) => {
|
||||
const formFieldObject = metaData[context][item]
|
||||
const formField = formFieldObject ? (
|
||||
<FormFieldContainer
|
||||
propsData={formFieldObject}
|
||||
key={index}
|
||||
onFocus={this.onFocusHandler}
|
||||
value={fieldValues && fieldValues[item]}
|
||||
formErrors={formErrors}
|
||||
formValues={formValues}
|
||||
updateFormErrors={updateFormErrors}
|
||||
updateFormValues={updateFormValues}
|
||||
/>
|
||||
) : null
|
||||
return formField
|
||||
})
|
||||
|
||||
inputListSection = inputListSection.filter((formFieldObject) => {
|
||||
return formFieldObject !== null
|
||||
})
|
||||
|
||||
return (
|
||||
<form className='c-Form' onSubmit={this.handleSubmit}>
|
||||
<fieldset>{inputListSection}</fieldset>
|
||||
<button type="submit" className="btn btn-primary btn-block" style={{marginTop: '15px', background: 'black'}}>Submit</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Form.propTypes = {
|
||||
context: PropTypes.string,
|
||||
customBlurHandler: PropTypes.func,
|
||||
customBlurFormatter: PropTypes.func,
|
||||
metaData: PropTypes.object.isRequired,
|
||||
className: PropTypes.string,
|
||||
fieldValues: PropTypes.object,
|
||||
formErrors: PropTypes.object,
|
||||
formValues: PropTypes.object,
|
||||
updateFormErrors: PropTypes.func,
|
||||
updateFormValues: PropTypes.func
|
||||
}
|
||||
|
||||
export default Form
|
||||
8
src/app/components/molecules/common/Form/Form.test.js
Normal file
8
src/app/components/molecules/common/Form/Form.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Form from './Form';
|
||||
|
||||
describe('Form', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/common/Form/index.js
Normal file
3
src/app/components/molecules/common/Form/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Form from './Form';
|
||||
|
||||
export default Form;
|
||||
@@ -0,0 +1,3 @@
|
||||
.c-FormFieldContainer {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import InputField from '../../../atoms/InputField'
|
||||
import SelectOption from '../../../atoms/SelectOption'
|
||||
|
||||
/**
|
||||
* INSERT_DESCRIPTION_HERE
|
||||
*/
|
||||
|
||||
class FormFieldContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
const componentKey = this.props.propsData && this.props.propsData.id
|
||||
const passedValue = this.props.value || (this.props.propsData && this.props.propsData.value)
|
||||
this.state = {
|
||||
error: false,
|
||||
errorMessage: null
|
||||
}
|
||||
this.props.updateFormValues({
|
||||
formValues: {
|
||||
// ...this.props.formValues,
|
||||
[componentKey]: passedValue ? passedValue : ''
|
||||
}
|
||||
})
|
||||
this.props.updateFormErrors({
|
||||
formErrors: {
|
||||
// ...this.props.formErrors,
|
||||
[componentKey]: ''
|
||||
}
|
||||
})
|
||||
this.customExecutes = this.customExecutes.bind(this)
|
||||
this.prepareCVN = this.prepareCVN.bind(this)
|
||||
this.executeDateValidations = this.executeDateValidations.bind(this)
|
||||
this.onChangeHandler = this.onChangeHandler.bind(this)
|
||||
this.onBlurHandler = this.onBlurHandler.bind(this)
|
||||
this.onFocusHandler = this.onFocusHandler.bind(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* validateFormField - validates the input field values
|
||||
* @param {object} event js event object
|
||||
* @param {object} validationObj fieldinput data as props
|
||||
*/
|
||||
validateFormField(e, validationObj) {
|
||||
const {propsData, formErrors, formValues, updateFormErrors, updateFormValues} = this.props
|
||||
const inputValue = e.target.value && e.target.value
|
||||
let error = false
|
||||
let errorMessage = ''
|
||||
const componentKey = propsData.id
|
||||
const validRegex =
|
||||
validationObj.dataRuleRegex &&
|
||||
new RegExp(validationObj.dataRuleRegex.regex).test(inputValue)
|
||||
const poValidRegex =
|
||||
e.target.id === 'address1' &&
|
||||
validationObj.dataRuleRegex.po_regex &&
|
||||
new RegExp(validationObj.dataRuleRegex.po_regex, 'i').test(inputValue)
|
||||
|
||||
if (e.target.tagName && e.target.tagName === 'SELECT') {
|
||||
if (
|
||||
validationObj.required.isRequired &&
|
||||
e.target.selectedIndex === 0 &&
|
||||
!validationObj.required.preSelected
|
||||
) {
|
||||
error = true
|
||||
errorMessage = validationObj.required.error_message
|
||||
}
|
||||
} else if (e.target.tagName && e.target.tagName === 'INPUT') {
|
||||
if (validationObj.required.isRequired) {
|
||||
if (inputValue.trim('') === '') {
|
||||
error = true
|
||||
errorMessage = validationObj.required.error_message
|
||||
} else if (validationObj.dataRuleRegex && !validRegex) {
|
||||
error = true
|
||||
errorMessage = validationObj.dataRuleRegex.error_message
|
||||
} else if (validationObj.dataRuleRegex && poValidRegex) {
|
||||
error = true
|
||||
errorMessage = validationObj.dataRuleRegex.po_error_message
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error = false
|
||||
errorMessage = null
|
||||
}
|
||||
|
||||
if (!errorMessage && propsData.id === 'expiration_month') {
|
||||
errorMessage = this.executeDateValidations()
|
||||
if (errorMessage) {
|
||||
error = true
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
error
|
||||
})
|
||||
|
||||
updateFormErrors({
|
||||
formErrors: {
|
||||
...formErrors,
|
||||
[componentKey]: errorMessage
|
||||
}
|
||||
})
|
||||
|
||||
updateFormValues({
|
||||
formValues: {
|
||||
...formValues,
|
||||
[componentKey]: inputValue
|
||||
}
|
||||
})
|
||||
|
||||
return error
|
||||
}
|
||||
|
||||
onChangeHandler(event) {
|
||||
const value = event.target.value
|
||||
this.setState({
|
||||
value
|
||||
})
|
||||
this.executeDateValidations(event)
|
||||
}
|
||||
|
||||
onFocusHandler(event) {
|
||||
this.setState({
|
||||
oldValue: event.target.value
|
||||
})
|
||||
}
|
||||
|
||||
onBlurHandler(validation, customBlurHandler, e) {
|
||||
e.oldValue = this.state.oldValue
|
||||
const {customBlurFormatter} = this.props
|
||||
const isError = this.validateFormField(e, validation)
|
||||
if (!isError) {
|
||||
if (customBlurHandler && typeof customBlurHandler === 'function') {
|
||||
customBlurHandler(e)
|
||||
}
|
||||
if (customBlurFormatter && typeof customBlurFormatter === 'function') {
|
||||
this.setState({value: customBlurFormatter(e)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prepareCVN() {
|
||||
const {propsData, selectedCreditCard} = this.props
|
||||
if (propsData && propsData.ccNumberUpdated !== undefined && propsData.ccNumberUpdated) {
|
||||
this.setState({
|
||||
value: ''
|
||||
})
|
||||
this.props.updateFormValues({
|
||||
formValues: {
|
||||
...this.props.formValues,
|
||||
security_code: ''
|
||||
}
|
||||
})
|
||||
propsData.ccNumberUpdated = false
|
||||
}
|
||||
if (selectedCreditCard) {
|
||||
if (selectedCreditCard.payment_card.card_type === 'Amex') {
|
||||
propsData.validation.dataRuleRegex.regex = /^[0-9'\s]{4}$/
|
||||
propsData.validation.rules.maxlength = 4
|
||||
} else {
|
||||
propsData.validation.dataRuleRegex.regex = /^[0-9'\s]{3}$/
|
||||
propsData.validation.rules.maxlength = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
executeDateValidations(event) {
|
||||
const {propsData, formValues, formErrors, updateFormErrors} = this.props
|
||||
let errorMessage = ''
|
||||
if (propsData.id === 'expiration_month' || propsData.id === 'expiration_year') {
|
||||
let month = ''
|
||||
let year = ''
|
||||
if (propsData.id === 'expiration_month') {
|
||||
month = +event.target.value
|
||||
year = +formValues.expiration_year
|
||||
} else if (propsData.id === 'expiration_year') {
|
||||
month = +formValues.expiration_month
|
||||
year = +event.target.value
|
||||
}
|
||||
const currentYear = new Date().getFullYear()
|
||||
const currentMonth = new Date().getMonth()
|
||||
if (year === currentYear && month < currentMonth + 1) {
|
||||
errorMessage = 'This Credit Card is expired'
|
||||
} else {
|
||||
errorMessage = ''
|
||||
}
|
||||
updateFormErrors({
|
||||
formErrors: {
|
||||
...formErrors,
|
||||
expiration_month: errorMessage
|
||||
}
|
||||
})
|
||||
}
|
||||
return errorMessage
|
||||
}
|
||||
|
||||
customExecutes() {
|
||||
this.prepareCVN()
|
||||
}
|
||||
|
||||
render() {
|
||||
const {customBlurHandler, formErrors, propsData} = this.props
|
||||
const {elementType} = propsData
|
||||
const errorMessage = formErrors && formErrors[propsData.id]
|
||||
this.customExecutes()
|
||||
const meta = {
|
||||
...this.props.propsData,
|
||||
className: this.state.error ? 'error' : '',
|
||||
error: this.state.error || errorMessage,
|
||||
errorMessage,
|
||||
handlers: {
|
||||
onBlurHandler: this.onBlurHandler,
|
||||
customBlurHandler,
|
||||
onChangeHandler: this.onChangeHandler,
|
||||
onFocusHandler: this.onFocusHandler
|
||||
},
|
||||
fieldValues: {
|
||||
propsValue: this.props.value,
|
||||
stateValue: this.state.value
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* switch function - returns HTML Tag depending upon the requirement
|
||||
* @param {string} elementType - element type e.g. input,select
|
||||
*/
|
||||
switch (elementType) {
|
||||
case 'input':
|
||||
return <InputField meta={meta} />
|
||||
case 'select':
|
||||
return <SelectOption meta={meta} />
|
||||
default:
|
||||
return <input />
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormFieldContainer.propTypes = {
|
||||
propsData: PropTypes.object.isRequired,
|
||||
className: PropTypes.string,
|
||||
customBlurHandler: PropTypes.func,
|
||||
customBlurFormatter: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
value: PropTypes.string,
|
||||
formValues: PropTypes.object,
|
||||
formErrors: PropTypes.object,
|
||||
selectedCreditCard: PropTypes.object,
|
||||
updateFormValues: PropTypes.func,
|
||||
updateFormErrors: PropTypes.func
|
||||
}
|
||||
|
||||
export default FormFieldContainer
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import FormFieldContainer from './FormFieldContainer';
|
||||
|
||||
describe('FormFieldContainer', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
import FormFieldContainer from './FormFieldContainer';
|
||||
|
||||
export default FormFieldContainer;
|
||||
@@ -0,0 +1,9 @@
|
||||
.c-Jumbotron {
|
||||
padding: 1rem;
|
||||
background: #222;
|
||||
color: #bbbbbb;
|
||||
margin-bottom: 0;
|
||||
.my-4 {
|
||||
border-color: #bbb;
|
||||
}
|
||||
}
|
||||
27
src/app/components/molecules/common/Jumbotron/Jumbotron.jsx
Normal file
27
src/app/components/molecules/common/Jumbotron/Jumbotron.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import {Link} from 'react-router-dom'
|
||||
|
||||
const Jumbotron = props => {
|
||||
return (
|
||||
<div className='c-Jumbotron'>
|
||||
<h1 className="display-4">{props.jumboText}</h1>
|
||||
<p className="lead">{props.subText}</p>
|
||||
<hr className='my-4' />
|
||||
<p>{props.jumboDescription}</p>
|
||||
<p className="lead">
|
||||
<Link className="btn btn-primary btn-lg" to="/view/plp" role="button">Go To PLP</Link>
|
||||
<Link className="btn btn-primary btn-lg float-right" to="#" role="button" style={{marginLeft: '15px'}}>{props.furtherLink}</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Jumbotron.propTypes = {
|
||||
furtherLink: PropTypes.string,
|
||||
jumboDescription: PropTypes.string,
|
||||
jumboText: PropTypes.string,
|
||||
subText: PropTypes.string
|
||||
};
|
||||
|
||||
export default Jumbotron;
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Jumbotron from './Jumbotron.jsx';
|
||||
|
||||
describe('Jumbotron', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/molecules/common/Jumbotron/index.js
Normal file
3
src/app/components/molecules/common/Jumbotron/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Jumbotron from './Jumbotron.jsx';
|
||||
|
||||
export default Jumbotron;
|
||||
37
src/app/config/forms-meta/login-form.json
Normal file
37
src/app/config/forms-meta/login-form.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"login": {
|
||||
"email": {
|
||||
"label": "Email ID",
|
||||
"placeholder": "Email ID",
|
||||
"type": "text",
|
||||
"id": "email",
|
||||
"elementType": "input",
|
||||
"validation": {
|
||||
"required": {
|
||||
"isRequired": "true",
|
||||
"error_message": "This field is required."
|
||||
},
|
||||
"rules": {
|
||||
"minlength": 6,
|
||||
"maxlength": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"placeholder": "Password",
|
||||
"type": "password",
|
||||
"id": "password",
|
||||
"elementType": "input",
|
||||
"validation": {
|
||||
"required": {
|
||||
"isRequired": "true",
|
||||
"error_message": "This field is required."
|
||||
},
|
||||
"rules": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
@import 'styles/variables';
|
||||
@import 'styles/base';
|
||||
@import 'styles/components';
|
||||
@import 'styles/utilities';
|
||||
@import 'styles/pages';
|
||||
@import 'styles/components';
|
||||
|
||||
.abcRioButtonBlue {
|
||||
background-color: white!important;
|
||||
|
||||
@@ -6,8 +6,8 @@ import {createStore, applyMiddleware, compose} from 'redux'
|
||||
// import * as serviceWorker from '../serviceWorker';
|
||||
import Router from './router';
|
||||
import reducer from './reducer'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import './index.scss'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
|
||||
const composeEnhancers =
|
||||
typeof window === 'object' &&
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Login.module.scss';
|
||||
|
||||
const Login = props => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<p>This is the login module</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Login.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Login.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Login;
|
||||
84
src/app/pages/Login/Login.jsx
Normal file
84
src/app/pages/Login/Login.jsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import styles from './Login.module.scss'
|
||||
import {connect} from 'react-redux'
|
||||
import {createPropsSelector} from 'reselect-immutable-helpers'
|
||||
|
||||
import * as actions from './actions'
|
||||
import {getLogin, getFormErrors, getFormValues} from './selectors'
|
||||
import LoginForm from '../../components/molecules/LoginForm'
|
||||
import SocialLogin from '../../components/molecules/SocialLogin'
|
||||
import Jumbotron from '../../components/molecules/common/Jumbotron'
|
||||
|
||||
class Login extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.pageType = 'login'
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {initializeLogin} = this.props
|
||||
initializeLogin()
|
||||
}
|
||||
|
||||
clicked() {
|
||||
console.log('login handler')
|
||||
}
|
||||
|
||||
render() {
|
||||
const {updateFormErrors, updateFormValues, formErrors, formValues} = this.props
|
||||
return (
|
||||
<div className={`${styles.Login} container`} onClick={this.clicked}>
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-8">
|
||||
<Jumbotron
|
||||
jumboText="Adobe - Joules to Watts assignment"
|
||||
subText="PLP and Cart Page Demo"
|
||||
jumboDescription="This app is build using React JS and routing is added using custom solutions to work on GH Pages. Login is optional and can be skipped."
|
||||
furtherLink="Learn more"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-lg-4">
|
||||
<div className={styles.loginContainer}>
|
||||
<p className={styles['c-login-intimation']}>Let's get to know each other, shall we!</p>
|
||||
<LoginForm
|
||||
updateFormValues={updateFormValues}
|
||||
updateFormErrors={updateFormErrors}
|
||||
formErrors={formErrors}
|
||||
formValues={formValues}
|
||||
/>
|
||||
<p className={styles.loginSplitter}>OR</p>
|
||||
<SocialLogin />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Login.propTypes = {
|
||||
initializeLogin: PropTypes.func,
|
||||
dataState: PropTypes.object,
|
||||
updateFormValues: PropTypes.func,
|
||||
updateFormErrors: PropTypes.func,
|
||||
formValues: PropTypes.object,
|
||||
formErrors: PropTypes.object
|
||||
}
|
||||
|
||||
const mapStateToProps = createPropsSelector({
|
||||
dataState: getLogin,
|
||||
formErrors: getFormErrors,
|
||||
formValues: getFormValues
|
||||
})
|
||||
|
||||
const mapDispatchToProps = {
|
||||
initializeLogin: actions.initializeLogin,
|
||||
updateFormErrors: actions.updateFormErrors,
|
||||
updateFormValues: actions.updateFormValues
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Login)
|
||||
@@ -1,3 +1,32 @@
|
||||
.c-Login {
|
||||
|
||||
.Login {
|
||||
background: #222;
|
||||
max-width: unset;
|
||||
@media only screen and (max-width: 1140px) {
|
||||
padding-left: unset;
|
||||
padding-right: unset;
|
||||
margin-right: unset;
|
||||
margin-left: unset;
|
||||
}
|
||||
.loginContainer {
|
||||
border: 2px solid grey;
|
||||
border-radius: 0.3rem;
|
||||
margin: 1rem;
|
||||
background: #eee;
|
||||
padding-bottom: 20px;
|
||||
.c-login-intimation {
|
||||
padding: 15px 5px 15px 15px;
|
||||
background: black;
|
||||
color: white;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.loginSplitter {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-transform: capitalize;
|
||||
font-size: 25px;
|
||||
font-weight: bolder;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import Login from './Login';
|
||||
import Login from './Login.jsx';
|
||||
|
||||
export default Login;
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Plp.module.scss';
|
||||
|
||||
const Plp = props => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Plp.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Plp.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Plp;
|
||||
29
src/app/pages/PLP/Plp.jsx
Normal file
29
src/app/pages/PLP/Plp.jsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Plp.module.scss';
|
||||
|
||||
import Header from './../../components/molecules/Header'
|
||||
import SortAndFilterPanel from './../../components/molecules/SortAndFilterPanel'
|
||||
import ProductContainer from './../../components/molecules/ProductContainer'
|
||||
import Footer from './../../components/molecules/Footer'
|
||||
|
||||
const Plp = props => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<Header />
|
||||
<SortAndFilterPanel />
|
||||
<ProductContainer />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Plp.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Plp.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Plp;
|
||||
@@ -1,3 +1,3 @@
|
||||
import Plp from './Plp';
|
||||
import Plp from './Plp.jsx';
|
||||
|
||||
export default Plp;
|
||||
@@ -1,5 +1,8 @@
|
||||
@import 'base/animations';
|
||||
@import 'base/forms';
|
||||
@import 'base/general';
|
||||
@import 'base/lists';
|
||||
@import 'base/material';
|
||||
@import 'base/mixins';
|
||||
@import 'base/tables';
|
||||
@import 'base/typography';
|
||||
@@ -1,5 +1,13 @@
|
||||
// Components
|
||||
// ===
|
||||
// @import '../components/atoms/InputField/InputField.component';
|
||||
@import '../components/atoms/InputField/InputField.component';
|
||||
@import '../components/atoms/SelectOption/SelectOption.component';
|
||||
@import '../components/molecules/common/Form/Form.component';
|
||||
@import '../components/molecules/common/FormFieldContainer/FormFieldContainer.component';
|
||||
@import '../components/molecules/common/Jumbotron/Jumbotron.component';
|
||||
@import '../components/molecules/Header/Header.component';
|
||||
@import '../components/molecules/LoginForm/LoginForm.component';
|
||||
@import '../components/molecules/PageLoader/PageLoader.component';
|
||||
@import '../components/molecules/SocialLogin/SocialLogin.component';
|
||||
// @import '../preloader/preload';
|
||||
|
||||
25
src/app/styles/_utilities.scss
Normal file
25
src/app/styles/_utilities.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
// Utilities
|
||||
// ===
|
||||
//
|
||||
// Use wrap-at-root mixin to allow overriding existing styles with extreme
|
||||
// specificity while keeping source code clean and readable. Does not override
|
||||
// !important or inline styles; those must be dealt with separately.
|
||||
|
||||
@import 'base/mixins';
|
||||
|
||||
|
||||
@include wrap-at-root("#app", 1) {
|
||||
@import 'utilities/border';
|
||||
@import 'utilities/box-shadow';
|
||||
@import 'utilities/color';
|
||||
@import 'utilities/flexbox';
|
||||
@import 'utilities/heading';
|
||||
@import 'utilities/layout';
|
||||
@import 'utilities/margin';
|
||||
@import 'utilities/padding';
|
||||
@import 'utilities/text-content';
|
||||
@import 'utilities/text';
|
||||
@import 'utilities/display';
|
||||
@import 'utilities/visibility';
|
||||
@import 'utilities/z-index';
|
||||
}
|
||||
@@ -115,6 +115,7 @@ $bold-font-weight: 700;
|
||||
// Neutrals
|
||||
$neutral-00: #fff;
|
||||
$neutral-10: #f7f7f7;
|
||||
$neutral-12: #f1f3f6;
|
||||
$neutral-15: #eee;
|
||||
$neutral-20: #d5d5d5;
|
||||
$neutral-30: #bfbfbf;
|
||||
@@ -124,8 +125,10 @@ $neutral-60: #333;
|
||||
$neutral-70: #000;
|
||||
|
||||
// Brand colors
|
||||
$brand-color: #017e9b; // blue
|
||||
$secondary-brand-color: #005569;
|
||||
// $brand-color: #017e9b; // blue
|
||||
$brand-color: #4471ea; // blue
|
||||
// $secondary-brand-color: #005569;
|
||||
$secondary-brand-color: #fafafa;
|
||||
$tertiary-brand-color: #83bdcb;
|
||||
$quaternary-brand-color: #bfdfe6;
|
||||
|
||||
@@ -175,6 +178,7 @@ $yelp-color: #af0606;
|
||||
// ---
|
||||
|
||||
$font-color: $neutral-60;
|
||||
$font-color-light: #b8b8b8;
|
||||
|
||||
$link-color: $ui-brand-color;
|
||||
$active-link-color: $dark-accent-color;
|
||||
@@ -193,7 +197,7 @@ $disabled-button-background-color: $neutral-15;
|
||||
$horizontal-input-padding: $unit;
|
||||
$vertical-input-padding: $unit;
|
||||
|
||||
$background-color: $neutral-10;
|
||||
$background-color: $neutral-12;
|
||||
$overlay-color: rgba($neutral-00, 0.85);
|
||||
|
||||
|
||||
|
||||
15
src/app/styles/base/_animations.scss
Normal file
15
src/app/styles/base/_animations.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
// Animations
|
||||
// ===
|
||||
//
|
||||
// Background Shimmer
|
||||
// ---
|
||||
|
||||
@keyframes background-shimmer {
|
||||
0% {
|
||||
background-position: 150vw 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -150vw 0;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ html {
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #222!important;
|
||||
}
|
||||
|
||||
// Grouping content
|
||||
|
||||
26
src/app/styles/base/_tables.scss
Normal file
26
src/app/styles/base/_tables.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
// Tables
|
||||
// ===
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: $unit 0;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: $unit 0;
|
||||
|
||||
font-weight: $semi-bold-font-weight;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: $unit 0;
|
||||
}
|
||||
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
vertical-align: middle;
|
||||
}
|
||||
61
src/app/styles/utilities/_border.scss
Normal file
61
src/app/styles/utilities/_border.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
// Border
|
||||
// ===
|
||||
|
||||
// Border (Width and Color)
|
||||
// ---
|
||||
|
||||
.u-border {
|
||||
border: $border;
|
||||
}
|
||||
|
||||
.u-border-0 {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.u-border-top {
|
||||
border-top: $border;
|
||||
}
|
||||
|
||||
.u-border-end {
|
||||
border-right: $border;
|
||||
}
|
||||
|
||||
.u-border-bottom {
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.u-border-start {
|
||||
border-left: $border;
|
||||
}
|
||||
|
||||
|
||||
// Light Border (Width and Color)
|
||||
// ---
|
||||
|
||||
.u-border-light {
|
||||
border: $light-border;
|
||||
}
|
||||
|
||||
.u-border-light-top {
|
||||
border-top: $light-border;
|
||||
}
|
||||
|
||||
.u-border-light-end {
|
||||
border-right: $light-border;
|
||||
}
|
||||
|
||||
.u-border-light-bottom {
|
||||
border-bottom: $light-border;
|
||||
}
|
||||
|
||||
.u-border-light-start {
|
||||
border-left: $light-border;
|
||||
}
|
||||
|
||||
|
||||
// Border (Other)
|
||||
// ---
|
||||
|
||||
.u-border-radius {
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
18
src/app/styles/utilities/_box-shadow.scss
Normal file
18
src/app/styles/utilities/_box-shadow.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
// Box Shadow
|
||||
// ===
|
||||
|
||||
.u-box-shadow {
|
||||
box-shadow: $box-shadow;
|
||||
}
|
||||
|
||||
.u-box-shadow-inset {
|
||||
box-shadow: $inset-box-shadow;
|
||||
}
|
||||
|
||||
.u-box-shadow-lg {
|
||||
box-shadow: $large-box-shadow;
|
||||
}
|
||||
|
||||
.u-box-shadow-input {
|
||||
box-shadow: $input-box-shadow;
|
||||
}
|
||||
177
src/app/styles/utilities/_color.scss
Normal file
177
src/app/styles/utilities/_color.scss
Normal file
@@ -0,0 +1,177 @@
|
||||
// Color
|
||||
// ===
|
||||
|
||||
// Neutral Colors
|
||||
// ---
|
||||
|
||||
.u-color-neutral-00 {
|
||||
color: $neutral-00;
|
||||
|
||||
fill: $neutral-00;
|
||||
}
|
||||
|
||||
.u-color-neutral-10 {
|
||||
color: $neutral-10;
|
||||
|
||||
fill: $neutral-10;
|
||||
}
|
||||
|
||||
.u-color-neutral-15 {
|
||||
color: $neutral-15;
|
||||
|
||||
fill: $neutral-15;
|
||||
}
|
||||
|
||||
.u-color-neutral-20 {
|
||||
color: $neutral-20;
|
||||
|
||||
fill: $neutral-20;
|
||||
}
|
||||
|
||||
.u-color-neutral-30 {
|
||||
color: $neutral-30;
|
||||
|
||||
fill: $neutral-30;
|
||||
}
|
||||
|
||||
.u-color-neutral-40 {
|
||||
color: $neutral-40;
|
||||
|
||||
fill: $neutral-40;
|
||||
}
|
||||
|
||||
.u-color-neutral-50 {
|
||||
color: $neutral-50;
|
||||
|
||||
fill: $neutral-50;
|
||||
}
|
||||
|
||||
.u-color-neutral-60 {
|
||||
color: $neutral-60;
|
||||
|
||||
fill: $neutral-60;
|
||||
}
|
||||
|
||||
.u-color-neutral-70 {
|
||||
color: $neutral-70;
|
||||
|
||||
fill: $neutral-70;
|
||||
}
|
||||
|
||||
|
||||
// Other Colors
|
||||
// ---
|
||||
|
||||
.u-color-brand {
|
||||
color: $brand-color;
|
||||
|
||||
fill: $brand-color;
|
||||
}
|
||||
|
||||
.u-color-accent {
|
||||
color: $accent-color;
|
||||
|
||||
fill: $accent-color;
|
||||
}
|
||||
|
||||
.u-color-primary-action {
|
||||
color: $primary-action-color;
|
||||
|
||||
fill: $primary-action-color;
|
||||
}
|
||||
|
||||
.u-color-secondary-action {
|
||||
color: $secondary-action-color;
|
||||
|
||||
fill: $secondary-action-color;
|
||||
}
|
||||
|
||||
.u-color-success {
|
||||
color: $success-color;
|
||||
|
||||
fill: $success-color;
|
||||
}
|
||||
|
||||
.u-color-error {
|
||||
color: $error-color;
|
||||
|
||||
fill: $error-color;
|
||||
}
|
||||
|
||||
.u-color-sale {
|
||||
color: $sale-color;
|
||||
|
||||
fill: $sale-color;
|
||||
}
|
||||
|
||||
|
||||
// Background Colors
|
||||
// ---
|
||||
|
||||
.u-bg-color-neutral-00 {
|
||||
background-color: $neutral-00;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-10 {
|
||||
background-color: $neutral-10;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-15 {
|
||||
background-color: $neutral-15;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-20 {
|
||||
background-color: $neutral-20;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-30 {
|
||||
background-color: $neutral-30;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-40 {
|
||||
background-color: $neutral-40;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-50 {
|
||||
background-color: $neutral-50;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-60 {
|
||||
background-color: $neutral-60;
|
||||
}
|
||||
|
||||
.u-bg-color-neutral-70 {
|
||||
background-color: $neutral-70;
|
||||
}
|
||||
|
||||
|
||||
// Other Background Colors
|
||||
// ---
|
||||
|
||||
.u-bg-color-brand {
|
||||
background-color: $brand-color;
|
||||
}
|
||||
|
||||
.u-bg-color-accent {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
|
||||
.u-bg-color-primary-action {
|
||||
background-color: $primary-action-color;
|
||||
}
|
||||
|
||||
.u-bg-color-secondary-action {
|
||||
background-color: $secondary-action-color;
|
||||
}
|
||||
|
||||
.u-bg-color-success {
|
||||
background-color: $success-color;
|
||||
}
|
||||
|
||||
.u-bg-color-error {
|
||||
background-color: $error-color;
|
||||
}
|
||||
|
||||
.u-bg-color-sale {
|
||||
background-color: $sale-color;
|
||||
}
|
||||
42
src/app/styles/utilities/_display.scss
Normal file
42
src/app/styles/utilities/_display.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
// Display
|
||||
// ===
|
||||
|
||||
|
||||
// Display: Block
|
||||
// ---
|
||||
|
||||
.u-display-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
// Display: Inline Block
|
||||
// ---
|
||||
|
||||
.u-display-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
// Display: Inline
|
||||
// ---
|
||||
|
||||
.u-display-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
// Dispaly: Inline Table
|
||||
// ---
|
||||
|
||||
.u-display-inline-table {
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
|
||||
// Display: None
|
||||
// ---
|
||||
|
||||
.u-display-none {
|
||||
display: none;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user