-
Notifications
You must be signed in to change notification settings - Fork 13
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
create products layout. #3
Changes from 1 commit
e3adff8
bba7480
40711c1
f38af4f
32c0ec0
dfafd5c
66b0912
8049f97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const tailwindcss = require('tailwindcss'); | ||
module.exports = { | ||
plugins: [ | ||
tailwindcss('./tailwind.config.js'), | ||
require('autoprefixer'), | ||
], | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
const tailwindcss = require('tailwindcss'); | ||
module.exports = { | ||
plugins: [require('tailwindcss'), require('autoprefixer')], | ||
}; | ||
plugins: [ | ||
tailwindcss('./tailwind.config.js'), | ||
require('autoprefixer'), | ||
], | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import './Products.scss'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,54 @@ | ||
import React, { Component } from 'react'; | ||
import UnbxdSearchCore from 'unbxd-search-core'; | ||
import UnbxdSearch from 'unbxd-search-core'; | ||
|
||
import { AppContextProvider } from './common/context'; | ||
import searchConfigurations from './config'; | ||
import '../public/css/index.scss'; | ||
|
||
class App extends Component { | ||
|
||
state = { | ||
unbxdCore: null | ||
setProductConfiguration = (config) => { | ||
const { per_page, requiredFields, variants, | ||
variantCount, variantRequiredFields, groupBy } = config; | ||
this.state.unbxdCore.setNumberOfProducts(per_page); | ||
this.state.unbxdCore.setFields(requiredFields); | ||
this.state.unbxdCore.setIsVariants(variants); | ||
this.state.unbxdCore.setVariantsCount(variantCount); | ||
this.state.unbxdCore.setVariantFields(variantRequiredFields); | ||
this.state.unbxdCore.setVariantsGroupBy(groupBy); | ||
} | ||
|
||
unbxdCallBack = (unbxdSearchObj, eventName) => { | ||
if (eventName === 'afterApiCall') { | ||
helpers = { setProductConfiguration: this.setProductConfiguration } | ||
|
||
constructor(props) { | ||
super(props) | ||
const { siteName, siteKey } = this.props; | ||
|
||
this.state = { | ||
unbxdCore: | ||
new UnbxdSearch({ ...searchConfigurations, siteName, siteKey, callBackFn: this.unbxdCallBack }), | ||
helpers: this.helpers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, is this a dynamically changing value to be kept on state? can we just use instance variable instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is dynamic. |
||
}; | ||
|
||
} | ||
|
||
unbxdCallBack = (unbxdSearchObj, eventName) => { | ||
console.log("hello ", eventName) | ||
if (eventName === 'AFTER_API_CALL') { | ||
this.setState({ unbxdCore: unbxdSearchObj }) | ||
} | ||
} | ||
|
||
componentDidMount() { | ||
const { siteName, siteKey } = this.props; | ||
const searchObj = new UnbxdSearchCore({ ...searchConfigurations, siteName, siteKey }, this.unbxdCallBack); | ||
searchObj.getResults('shoes'); | ||
//this.state.unbxdCore.getResults('boots'); | ||
//this.state.unbxdCore.getResults('cooking stoves'); | ||
this.state.unbxdCore.getResults('red shirt'); | ||
//this.state.unbxdCore.getResults('xxxxxxxxxxxxxxx'); | ||
} | ||
|
||
render() { | ||
|
||
const { unbxdCore } = this.state | ||
return ( | ||
<AppContextProvider value={unbxdCore}> | ||
<AppContextProvider value={this.state}> | ||
{this.props.children} | ||
</AppContextProvider> | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export const conditionalRenderer = (children, state, DefaultComponents) => { | ||
const isChildren = children ? true : false; | ||
|
||
return isChildren ? | ||
(typeof children === 'function' ? | ||
children(state) : children) : | ||
(DefaultComponents) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { GridProductCard } from './ProductCards'; | ||
//We need the fieldMap object to map to values | ||
|
||
const GridView = (props) => { | ||
|
||
const { products = [], | ||
per_row, | ||
fieldMap, | ||
variantMap, | ||
unbxdProductCardClickHandler } = props; | ||
|
||
return (<div className={`Unbx-product-container Unbx-grid-view grid grid-cols-${per_row} gap-4 p-4`}>{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets keep the prefix as |
||
products.map((product) => { | ||
return (<GridProductCard product={product} | ||
fieldMap={fieldMap} | ||
variantMap={variantMap} | ||
per_row={per_row} | ||
key={product.uniqueId} | ||
unbxdProductCardClickHandler={unbxdProductCardClickHandler} />) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we move the click to the parent so that we have only 1 click handler instead of one per product (if we show 100 products on page, we will have 100 click handlers) |
||
}) | ||
|
||
} | ||
</div>) | ||
} | ||
|
||
GridView.propTypes = { | ||
products: PropTypes.arrayOf(PropTypes.object).isRequired, | ||
per_row: PropTypes.number.isRequired, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets have a standard of camelCase props everywhere |
||
fieldMap: PropTypes.object.isRequired, | ||
variantMap: PropTypes.object.isRequired, | ||
unbxdProductCardClickHandler: PropTypes.func.isRequired | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets keep naming standard for click handlers as per the React standards in the format |
||
} | ||
|
||
export default GridView; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { ListProductCard } from './ProductCards'; | ||
|
||
const ListView = ({ products = [], fieldMap, isVariant, variantMap, unbxdProductCardClickHandler }) => { | ||
|
||
return (<div className={`Unbx-product-container Unbx-grid-view grid grid-cols-1 gap-4 p-4`}>{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, lets add prefix as |
||
products.map((product) => { | ||
return (<ListProductCard product={product} | ||
fieldMap={fieldMap} | ||
isVariant={isVariant} | ||
variantMap={variantMap} | ||
key={product.uniqueId} | ||
unbxdProductCardClickHandler={unbxdProductCardClickHandler} />) | ||
}) | ||
|
||
} | ||
</div>) | ||
} | ||
ListView.propTypes = { | ||
products: PropTypes.arrayOf(PropTypes.object).isRequired, | ||
per_row: PropTypes.number.isRequired, | ||
fieldMap: PropTypes.object.isRequired, | ||
isVariant: PropTypes.bool.isRequired, | ||
variantMap: PropTypes.object.isRequired, | ||
unbxdProductCardClickHandler: PropTypes.func.isRequired | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as the GridView props comments above |
||
} | ||
|
||
export default ListView; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const NoProducts = () => { | ||
return (<div className='Unbx-no-products-container'>Sorry! No products found!</div>) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefix as |
||
} | ||
|
||
export default NoProducts; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets keep small case beginning names for folder names. Here it would be |
||
import PropTypes from 'prop-types'; | ||
|
||
import { productFieldsMapper } from '../utils'; | ||
|
||
const GridProductCard = ({ product, fieldMap, variantMap, unbxdProductCardClickHandler }) => { | ||
|
||
//Get the datas from the product bases on fieldMap and create the card | ||
const productValues = productFieldsMapper(product, fieldMap, variantMap); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. name the functions with the "action" type present in the name, like |
||
|
||
const { | ||
productName, | ||
imageUrl, | ||
price, | ||
sellingPrice } = productValues; | ||
|
||
//Add support for router as a config | ||
return (<div className='Unbx-product-card-container'> | ||
<a href={product.productUrl} className={`Unbx-product-card Unbx-grid-card`} onClick={unbxdProductCardClickHandler}> | ||
<img className='Unbx-product-card Unbx-image' src={imageUrl[0]} /> | ||
<p className='Unbx-product-card Unbx-product-name'>{productName}</p> | ||
<p className='Unbx-product-card Unbx-price'>{price}</p> | ||
<p className='Unbx-product-card Unbx-selling-price'>{sellingPrice}</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as the parent has the |
||
</a> | ||
{/* swatch content */} | ||
</div>) | ||
} | ||
|
||
GridProductCard.propTypes = { | ||
product: PropTypes.object.isRequired, | ||
fieldMap: PropTypes.object.isRequired, | ||
isVariant: PropTypes.bool.isRequired, | ||
variantMap: PropTypes.object.isRequired, | ||
unbxdProductCardClickHandler: PropTypes.func.isRequired | ||
} | ||
|
||
export default GridProductCard; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { productFieldsMapper } from '../utils'; | ||
|
||
const ListProductCard = ({ product, fieldMap, variantMap, unbxdProductCardClickHandler }) => { | ||
|
||
//Get the datas from the product bases on fieldMap and create the card | ||
const productValues = productFieldsMapper(product, fieldMap, variantMap); | ||
|
||
const { | ||
productName, | ||
imageUrl, | ||
price, | ||
sellingPrice } = productValues; | ||
|
||
//Add support for router as a config | ||
return (<div className='Unbx-product-card-container'> | ||
<a href={product.productUrl} className={`Unbx-product-card Unbx-grid-card`} onClick={unbxdProductCardClickHandler}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it should be |
||
<img className='Unbx-product-card Unbx-image' src={imageUrl[0]} /> | ||
<p className='Unbx-product-card Unbx-product-name'>{productName}</p> | ||
<p className='Unbx-product-card Unbx-price'>{price}</p> | ||
<p className='Unbx-product-card Unbx-selling-price'>{sellingPrice}</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as the parent has the |
||
</a> | ||
{/* swatch content */} | ||
</div>) | ||
} | ||
|
||
ListProductCard.propTypes = { | ||
product: PropTypes.object.isRequired, | ||
fieldMap: PropTypes.object.isRequired, | ||
isVariant: PropTypes.bool.isRequired, | ||
variantMap: PropTypes.object.isRequired, | ||
unbxdProductCardClickHandler: PropTypes.func.isRequired | ||
} | ||
|
||
export default ListProductCard; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import GridProductCard from './GridProductCard'; | ||
import ListProductCard from './ListProductCard'; | ||
|
||
export { GridProductCard, ListProductCard }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
|
||
import { ProductContextConsumer } from './Context' | ||
|
||
import NoProducts from './NoProducts'; | ||
import ProductsWrapper from './ProductsWrapper'; | ||
|
||
|
||
|
||
const ProductsView = () => { | ||
return (<ProductContextConsumer>{({ isGrid, getSearchResults, ZeroResultsTemplate, ...props }) => { | ||
|
||
const { numberOfProducts = 0, products = [] } = getSearchResults() || {}; | ||
|
||
//return the prop based Zero results template | ||
if (numberOfProducts === 0 && ZeroResultsTemplate) { | ||
return !ZeroResultsTemplate.prototype.render | ||
? ZeroResultsTemplate() : <ZeroResultsTemplate />; | ||
} | ||
|
||
//return the default Zero results template | ||
if (numberOfProducts === 0) { | ||
return <NoProducts />; | ||
} | ||
|
||
//return the default product results template | ||
//we can make an object of props and destructure it. | ||
return (<ProductsWrapper isGrid={isGrid} products={products} {...props} />) | ||
|
||
}} | ||
</ProductContextConsumer>); | ||
} | ||
|
||
export default ProductsView; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this object required to be on state? Can we keep it as an instance variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that the changes are passed on to children.