Created
October 6, 2019 06:16
-
-
Save bhargav2496/b641ed2dd7ffb334c2b19d52d8748560 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PureComponent } from 'react' | |
import { connect } from 'react-redux' | |
import _ from 'lodash' | |
import { Trans } from 'react-i18next' | |
import config from 'config' | |
import { | |
ProductGrid, QuickView, FilterDropdown, Pagination, LeftColumn, Spinner, | |
} from 'components' | |
import { withRouter } from 'react-router-dom' | |
import { user_role, component_price } from '../../../domain/configHandler/ssoUrls' | |
import { | |
getSubstring, | |
capsFirst, | |
handleGetToken, | |
setBrandFilter, | |
getBrandFilter, | |
resetBrandFilter, | |
setCategoryFilter, | |
getCategoryFilter, | |
resetCategoryFilter, | |
setDeviceFilter, | |
getDeviceFilter, | |
resetDeviceFilter, | |
hasAccesToPrice, | |
setOfferfilter, | |
} from '../../../domain/helper' | |
import ApiService from '../../../services/ApiService' | |
import CustomApiService from '../../../services/CustomApiService' | |
import TotalCountApiService from '../../../services/TotalCountApiService' | |
import { UrlParserForProductListing } from '../../../domain/UrlParser' | |
import { sellerProductCurrency } from '../../../domain/configHandler/bestSeller' | |
import { | |
productPerPage, | |
noProductFOund, | |
categoryRouter, | |
brandRouter, | |
offerRouter, | |
defaultProductEndPoint, | |
customProductEndPoint, | |
quickView, | |
categoryJunctionTableEndpint, | |
offerJunctionTableEndpint, | |
productPerRow, | |
totalProductCountText, | |
selectedProductCountText, | |
} from '../../../domain/configHandler/productListing' | |
import { | |
Rightsidebar, BreadCrumbBar, TotalCount, BreadCrumb, Sort, Row, NoProduct, Leftsidebar, | |
} from './style' | |
let sortValue = 'name' | |
let categoryProductIds = [] | |
let deviceProductIds = [] | |
let offerProductIds = [] | |
let refinedCategory = '' | |
let refinedBrand = '' | |
let refinedOffer = '' | |
let params | |
let totalProduct = 0 | |
let items | |
let startProduct | |
let endProduct | |
class ProductListing extends PureComponent { | |
state = { | |
quickViewIndex: null, | |
} | |
startLimit = 0 | |
endLimit = productPerPage() | |
componentDidMount() { | |
let loc = '' | |
/* This is when user manually change from the URL i.e. when URL is not Clicked from Menu */ | |
const manualUrlChange = window.location.href | |
this.getTotalCountOfProduct() | |
/* When URL is changed from Menu */ | |
this.props.history.listen((location) => { | |
loc = UrlParserForProductListing(location.pathname) | |
if (loc.length > 1) { | |
this.functionCallHandlerOnUrlChange(loc) | |
} else { | |
/* If user clicked on category/offer i.e user wants to see all products of category/offer */ | |
refinedCategory = '' | |
refinedOffer = '' | |
refinedBrand = '' | |
resetCategoryFilter() | |
resetBrandFilter() | |
this.loadProduct() | |
} | |
}) | |
if (manualUrlChange.length > 0) { | |
loc = UrlParserForProductListing(manualUrlChange) | |
if (loc.length > 1) { | |
this.functionCallHandlerOnUrlChange(loc) | |
} else { | |
/* If user clicked on category/offer i.e user wants to see all products of category/offer by hitting URL manually */ | |
refinedCategory = '' | |
refinedOffer = '' | |
refinedBrand = '' | |
resetCategoryFilter() | |
resetBrandFilter() | |
this.loadProduct() | |
} | |
} | |
this.loadProduct() | |
} | |
/* Based on URL parsing condition function is called */ | |
functionCallHandlerOnUrlChange = (loc) => { | |
const [firstParam, secondParam] = loc | |
/* If the url is baseurl/category */ | |
if (firstParam === categoryRouter()) { | |
refinedCategory = secondParam | |
refinedOffer = '' | |
refinedBrand = '' | |
resetCategoryFilter() | |
resetBrandFilter() | |
this.getProductIdByCategoryId(refinedCategory) | |
/* If the url is baseurl/brand */ | |
} else if (firstParam === brandRouter()) { | |
refinedCategory = '' | |
refinedOffer = '' | |
refinedBrand = secondParam | |
resetBrandFilter() | |
resetCategoryFilter() | |
resetDeviceFilter() | |
setBrandFilter(refinedBrand) | |
this.loadProduct() | |
/* If the url is baseurl/offer */ | |
} else if (firstParam === offerRouter()) { | |
refinedCategory = '' | |
refinedOffer = secondParam | |
refinedBrand = '' | |
resetBrandFilter() | |
resetCategoryFilter() | |
this.getProductIdByOffer() | |
} | |
} | |
/* The custom endpoint is not returning total count by sending meta. | |
Calling default product service for getting total count */ | |
getTotalCountOfProduct = async () => { | |
const apiUrl = defaultProductEndPoint() | |
const token = handleGetToken() | |
const params = { | |
access_token: token, | |
fields: '*.*', | |
meta: '*', | |
} | |
totalProduct = await TotalCountApiService({ url: apiUrl, params }) | |
} | |
// Calling API for getting data | |
loadProduct = async () => { | |
const apiUrl = customProductEndPoint() | |
/* Filters */ | |
/* If all filters are applied together */ | |
if ( | |
categoryProductIds.length > 0 | |
&& getBrandFilter().length === 0 | |
&& deviceProductIds.length === 0 | |
&& offerProductIds.length === 0 | |
) { | |
params = this.formCategoryFilterParam() | |
} else if ( | |
getBrandFilter() === null | |
|| (getBrandFilter() === '' | |
&& categoryProductIds.length === 0 | |
&& deviceProductIds.length === 0 | |
&& offerProductIds.length === 0) | |
) { | |
params = this.formDefaultParam() | |
} else if ( | |
(getBrandFilter() !== null && getBrandFilter().length > 0 && getCategoryFilter() === '') | |
|| (getCategoryFilter() !== '' && getDeviceFilter() === '') | |
) { | |
params = this.formBrandFilterParam() | |
items = await CustomApiService({ url: apiUrl, params }) | |
this.props.onSave(items) | |
this.setState({ | |
totalProduct: items.length, | |
}) | |
} else if ( | |
getBrandFilter() !== null | |
&& (getBrandFilter().length > 0 || getBrandFilter().length === 1) | |
&& getCategoryFilter().length > 0 | |
&& deviceProductIds.length === 0 | |
) { | |
params = this.formCategoryAndBrandParam() | |
items = await CustomApiService({ url: apiUrl, params }) | |
this.props.onSave(items) | |
} else if ( | |
getBrandFilter() !== null | |
&& getBrandFilter().length > 0 | |
&& deviceProductIds.length > 0 | |
&& categoryProductIds.length === 0 | |
) { | |
params = this.formDeviceAndBrandParam() | |
} else if (offerProductIds.length > 0 && deviceProductIds.length === 0) { | |
/* If offer is clicked from URL */ | |
params = this.formOfferParam() | |
items = await CustomApiService({ url: apiUrl, params }) | |
this.props.onSave(items) | |
} else if (deviceProductIds.length > 0) { | |
params = this.formDeviceFilterParam() | |
items = await CustomApiService({ url: apiUrl, params }) | |
this.props.onSave(items) | |
} | |
items = await CustomApiService({ url: apiUrl, params }) | |
this.props.onSave(items) | |
this.setState({ | |
totalProduct: items.length, | |
}) | |
} | |
/* default params i.e if no value is selected */ | |
formDefaultParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
meta: '*', | |
'filter[channel.slug][eq]': user_role(), | |
offset: this.startLimit, | |
limit: this.endLimit + 6, | |
} | |
return params | |
} | |
/* params for all filters */ | |
formAllFilterParam = () => { | |
params = '' | |
params = { | |
// sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[manufacturer.slug][in]': getBrandFilter(), | |
'filter[id][in]': `${getCategoryFilter()},${getDeviceFilter()}`, | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: this.endLimit, | |
} | |
return params | |
} | |
/* params for brand filter */ | |
formBrandFilterParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[manufacturer.slug][eq]': getBrandFilter(), | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
/* Params for category filter */ | |
formCategoryFilterParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[id][in]': getCategoryFilter(), | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
/* Params for device filter */ | |
formDeviceFilterParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[id][in]': getDeviceFilter(), | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
/* params for category and brand */ | |
formCategoryAndBrandParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[manufacturer.slug][in]': getBrandFilter(), | |
'filter[id][in]': getCategoryFilter(), | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
/* Param for device and brand */ | |
formDeviceAndBrandParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[id][in]': getDeviceFilter(), | |
'filter[manufacturer.slug][in]': getBrandFilter(), | |
'filter[channel.slug][eq]': user_role(), | |
meta: '*', | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
/* Params for offer */ | |
formOfferParam = () => { | |
params = '' | |
params = { | |
sort: sortValue, | |
access_token: handleGetToken(), | |
fields: '*.*', | |
'filter[id][in]': offerProductIds.toString(), | |
'filter[channel.slug][eq]': user_role(), | |
offset: this.startLimit, | |
limit: 25, | |
} | |
return params | |
} | |
// Method for showing quick view in product grid | |
quickView = (index) => { | |
if (quickView() === 'enabled') { | |
this.setState({ | |
quickViewIndex: index, | |
}) | |
} else { | |
this.setState({ | |
quickViewIndex: false, | |
}) | |
} | |
} | |
// Method for removing quick view from product grid | |
removeQuickViewOnMouseOut = () => { | |
this.setState({ | |
quickViewIndex: false, | |
}) | |
} | |
// Sort product list with dropdown | |
filterDropdown = async (value) => { | |
sortValue = value | |
this.loadProduct() | |
} | |
// Get product Id from junction table for category for M2M mapping | |
getProductIdByCategoryId = async (target) => { | |
if (target.value) { | |
setCategoryFilter(target.value) | |
const apiUrl = categoryJunctionTableEndpint() | |
const token = handleGetToken() | |
const params = { | |
access_token: token, | |
fields: '*.*', | |
'filter[category_id.slug][eq]': getCategoryFilter(), | |
} | |
const getProductId = await ApiService({ url: apiUrl, params }) | |
const newFilterArray = [] | |
_.map(getProductId, (product) => { | |
if ( | |
product.product_id.id !== null | |
&& !categoryProductIds.includes(product.product_id.id) | |
&& target.checked === true | |
) { | |
categoryProductIds.push(product.product_id.id) | |
} else if ( | |
product.product_id !== null | |
&& categoryProductIds.includes(product.product_id.id) | |
&& target.checked === false | |
) { | |
newFilterArray.push(product.product_id.id) | |
} else if (product.product_id !== null) { | |
categoryProductIds.push(product.product_id.id) | |
} | |
}) | |
if (newFilterArray.length > 0 && categoryProductIds.length > 0) { | |
const intersectionResult = _.intersection(categoryProductIds, newFilterArray) | |
categoryProductIds = [...intersectionResult] | |
} | |
setCategoryFilter(categoryProductIds) | |
this.loadProduct() | |
} | |
if (target) { | |
setCategoryFilter(target) | |
const apiUrl = categoryJunctionTableEndpint() | |
const token = handleGetToken() | |
const params = { | |
access_token: token, | |
fields: '*.*', | |
'filter[category_id.slug][eq]': getCategoryFilter(), | |
} | |
const getProductId = await ApiService({ url: apiUrl, params }) | |
const newFilterArray = [] | |
_.map(getProductId, (product) => { | |
if (product.product_id.id !== null && !categoryProductIds.includes(product.product_id.id)) { | |
categoryProductIds.push(product.product_id.id) | |
} else if (product.product_id !== null && categoryProductIds.includes(product.product_id.id)) { | |
newFilterArray.push(product.product_id.id) | |
} else if (product.product_id !== null) { | |
categoryProductIds.push(product.product_id.id) | |
} | |
}) | |
if (newFilterArray.length > 0 && categoryProductIds.length > 0) { | |
const intersectionResult = _.intersection(categoryProductIds, newFilterArray) | |
categoryProductIds = [...intersectionResult] | |
} | |
setCategoryFilter(categoryProductIds) | |
this.loadProduct() | |
} | |
} | |
// Get product Id from junction table for offer for M2M mapping | |
getProductIdByOffer = async () => { | |
const apiUrl = offerJunctionTableEndpint() | |
const token = handleGetToken() | |
const params = { | |
access_token: token, | |
fields: '*.*', | |
'filter[offer_id.slug][in]': refinedOffer, | |
} | |
const getProductId = await ApiService({ url: apiUrl, params }) | |
offerProductIds = [] | |
_.map(getProductId, (product) => { | |
if (product.product_id !== null) { | |
offerProductIds.push(product.product_id.id) | |
} | |
}) | |
setOfferfilter(offerProductIds) | |
this.loadProduct() | |
} | |
// Get product Id from junction table for device for M2M mapping and store it into localstorage | |
getProductIdByDeviceId = async (target) => { | |
if (target !== undefined) { | |
if (target.value.length > 0 && target.checked === true) { | |
setDeviceFilter(target.value) | |
} | |
} | |
const apiUrl = config.left_filter.end_points.DEVIJUNCPROD | |
const token = handleGetToken() | |
const params = { | |
access_token: token, | |
fields: '*.*', | |
// 'filter[channel.slug][eq]': 'ws', | |
'filter[device_id.name][in]': getDeviceFilter(), | |
} | |
const getProductId = await ApiService({ url: apiUrl, params }) | |
const newFilterArray = [] | |
_.map(getProductId, (product) => { | |
if (product.product_id !== null && !deviceProductIds.includes(product.product_id.id) && target.checked === true) { | |
deviceProductIds.push(product.product_id.id) | |
} else if ( | |
product.product_id !== null | |
&& deviceProductIds.includes(product.product_id.id) | |
&& target.checked === false | |
) { | |
newFilterArray.push(product.product_id.id) | |
} | |
}) | |
if (newFilterArray.length > 1 && deviceProductIds.length > 0) { | |
const intersectionResult = _.intersection(deviceProductIds, newFilterArray) | |
deviceProductIds = [...intersectionResult] | |
} | |
setDeviceFilter(deviceProductIds) | |
this.loadProduct() | |
} | |
/* Page click handler method of pagination */ | |
handlePageChange = (data) => { | |
const { selected } = data | |
this.startLimit = Math.ceil(selected * productPerPage()) | |
this.endLimit = Math.ceil(productPerPage()) | |
startProduct = Math.ceil(selected * productPerPage()) | |
endProduct = Math.ceil(startProduct + productPerPage()) | |
this.setState(() => { | |
this.loadProduct() | |
}) | |
} | |
showPrice = (itemvalue, value) => { | |
if (itemvalue.prices != null && hasAccesToPrice(value, component_price()) === true) { | |
return itemvalue.prices[0].dealer_price | |
} | |
if (hasAccesToPrice(value, component_price()) === false) { | |
return itemvalue.prices[0].price_rrp | |
} | |
if (itemvalue.prices != null && hasAccesToPrice(value, component_price()) === null) { | |
return ( | |
<div> | |
<span> | |
{' '} | |
RRP | |
{' '} | |
{itemvalue.prices[0].dealer_price} | |
{' '} | |
{sellerProductCurrency()} | |
{' '} | |
/ UVP | |
{' '} | |
{itemvalue.prices[0].price_rrp} | |
{' '} | |
{sellerProductCurrency()} | |
{' '} | |
</span> | |
</div> | |
) | |
} | |
return <Spinner /> | |
} | |
render() { | |
let productItems = null | |
let pagination | |
if (typeof this.props.categoryProduct !== 'undefined' && Array.isArray(this.props.categoryProduct)) { | |
pagination = ( | |
<Pagination | |
perPage={ | |
this.props.categoryProduct.length > productPerPage() ? productPerPage() : this.props.categoryProduct.length | |
} | |
handlePageClick={this.handlePageChange} | |
data={this.props.categoryProduct} | |
pageCount={this.state ? this.state.totalProduct / productPerPage() : totalProduct / productPerPage()} | |
/> | |
) | |
productItems = _.map(this.props.categoryProduct, (item, index) => { | |
const offerFlag = item && item.offer && item.offer[0] ? item.offer[0].status : false | |
const bsClass = `col-xs-12 col-sm-6 col-md-${productPerRow()} col-lg-${productPerRow()}` | |
return ( | |
<div className={bsClass} key={index}> | |
<ProductGrid | |
eTriggered={this.getFilterValue} | |
title={getSubstring(item.name, 0, 18)} | |
price={this.showPrice(item, this.props.useracces.role.acces)} | |
image={item.images !== null ? item.images[0].thumbnails : 'No image'} | |
button={<Trans>{capsFirst(config.product_list.button_text)}</Trans>} | |
productId={item.id} | |
link={item.id} | |
currency={config.product_list.currency} | |
hover={() => this.quickView(index)} | |
hoverOut={() => this.removeQuickViewOnMouseOut()} | |
quickViewLink={item.id} | |
clicked={item} | |
articleNumber={item.article_number} | |
strikeOut={item.discount} | |
createdDate={item.created_on} | |
dealFlag={offerFlag} | |
/> | |
{this.state.quickViewIndex === index ? ( | |
<QuickView | |
buttonName={capsFirst(config.product_list.quick_view_button_text)} | |
mouseIn={() => this.quickView(index)} | |
mouseOut={() => this.removeQuickViewOnMouseOut()} | |
/> | |
) : null} | |
</div> | |
) | |
}) | |
} else { | |
productItems = ( | |
<NoProduct> | |
{' '} | |
' | |
{noProductFOund()} | |
' | |
{' '} | |
</NoProduct> | |
) | |
} | |
return ( | |
<div> | |
<Leftsidebar> | |
<LeftColumn | |
brandClicked={this.loadProduct} | |
catClicked={event => this.getProductIdByCategoryId(event.target)} | |
deviceClick={event => this.getProductIdByDeviceId(event.target)} | |
/> | |
</Leftsidebar> | |
<Rightsidebar> | |
<BreadCrumbBar> | |
<BreadCrumb> | |
<TotalCount> | |
{<Trans>{totalProductCountText()}</Trans>} | |
: ( | |
{typeof startProduct !== 'undefined' ? startProduct + 1 : 1} | |
{' - '} | |
{typeof endProduct !== 'undefined' ? endProduct : this.state.totalProduct} | |
, | |
{<Trans>{selectedProductCountText()}</Trans>} | |
{' '} | |
{totalProduct !== undefined || totalProduct !== '' || this.state.totalProduct !== '' | |
? this.state.totalProduct | |
: totalProduct} | |
) | |
</TotalCount> | |
<Sort> | |
<FilterDropdown clicked={event => this.filterDropdown(event.target.value)} /> | |
</Sort> | |
</BreadCrumb> | |
</BreadCrumbBar> | |
<Row className="row">{productItems}</Row> | |
{pagination} | |
</Rightsidebar> | |
</div> | |
) | |
} | |
} | |
const mapStateToProps = (state) => { | |
return { | |
categoryProduct: state.categoryProduct.categoryProduct, | |
useracces: state, | |
} | |
} | |
const mapDispatchToProps = (dispatch) => { | |
return { | |
onSave: (categoryProduct) => { | |
dispatch({ | |
type: 'STORE_CATPRODUCT', | |
payload: categoryProduct, | |
}) | |
}, | |
} | |
} | |
export default connect( | |
mapStateToProps, | |
mapDispatchToProps | |
)(withRouter(ProductListing)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment