/*
Licensed Materials - Property of IBM
694906H
(c) Copyright IBM Corp. 2020 All Rights Reserved
US Government Users Restricted Rights - Use, duplication or disclosure restricted
by GSA ADP Schedule Contract with IBM Corp.
*/
/* eslint-disable react/jsx-props-no-spreading, no-else-return, react/forbid-prop-types */
import React, { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { LayoutSpacing } from '@exo/frontend-components-core';
import { Grid, Row, Column, Breadcrumb, Tag } from '@exo/frontend-components-base';
import { useSessionContext } from '@exo/frontend-common-session-context';
import { SearchForm } from '@exo/frontend-components-agro';
import { CmsContainer, CmsSpot } from '@exo/frontend-content-api';
import {
makeCategoryUrlFactory,
useFacetState,
CategoryBreadcrumbContainer,
CategoryFiltersContainer,
CategoryRef,
CategoryNavigationContainer
} from '@exo/frontend-features-catalog-logic';
import {
ProductView,
CategoryNavigation,
Filters,
ListingSortBy,
ListingTypeToggle,
BackgroundMKT,
FilterSidePanelMemo
} from '../../index';
import {
usePagination,
useFilters,
useRegion,
useCartSideMenu,
useFilterSideMenu
} from '@exo/contexts';
import { CatalogConfig } from '../../catalogConfig';
import { SearchListingContainerByCatAndName } from '../../../../../../../packages/features/catalog/catalog-logic/client/smart-components/SearchListingContainerByCatAndName/SearchListingContainerByCatAndName';
import * as S from './CategoryPage.styles';
import { useShopDetails } from '@exo/frontend-features-sellerDetails-logic';
import { Loading } from 'carbon-components-react';
import { ChatbotBox } from '@exo/frontend-onboarding-logic/client/index';
import { Filter24 } from '@carbon/icons-react';
import { ListingByNumber } from '../../components/ListingByNumber/ListingByNumber';
export const CategoryPage = ({
catalogConfig,
categoryId,
miraklShopIds,
regionList,
miraklRegion,
categoryPath,
params,
term
}: Props) => {
const [numberItems, setNumberItems] = useState<any>(10);
const [shopId, setShopId] = useState<string>();
const [lenghtOffers, setLenghtOffers] = useState<number>();
const [totalPages, setTotalPages] = useState<number>(0);
const [countItems, setCountItems] = useState<number>(0);
const sessionContext = useSessionContext();
const facetState = useFacetState({
key: categoryId,
baseFacets: catalogConfig.baseFacets,
baseSort: catalogConfig.baseSort,
baseSelectedFacets: params?.selectedFilters ? [params.selectedFilters] : []
});
const { pageInfo: pagination, setPagination } = usePagination();
const { setSearchFilters } = useFilters();
const { region, setSelectedRegion } = useRegion();
let shopIds;
useEffect(() => {
setSearchFilters({
term: term,
miraklShopIds: shopId,
categoryId: categoryId.id!,
miraklRegion: miraklRegion,
regionList: regionList
});
}, [term, miraklRegion, regionList, shopId, categoryId]);
if (!region?.miraklShopIds) {
shopIds;
} else {
shopIds = [region?.miraklShopIds];
}
const DEFAULT_FILTER_PRODUCT = [
{ id: 'RELEVANCE', text: 'Relevância' },
{ id: 'NAME', text: 'De A a Z' },
{ id: 'NAME_DESCENDING', text: 'De Z a A' },
{ id: 'PRICE_ASCENDING', text: 'Menor preço' },
{ id: 'PRICE_DESCENDING', text: 'Maior preço' }
];
const DEFAULT_FILTER_PAGINATION = [
{ id: '10', text: 'Itens por página: 10' },
{ id: '20', text: 'Itens por página: 20' },
{ id: '30', text: 'Itens por página: 30' }
];
const { pathname } = useLocation();
const categoryUrlFactory = makeCategoryUrlFactory();
const getLabelText = (facetName: string, label: string) => `${facetName} : ${label}`;
const currency = sessionContext.currency ?? catalogConfig.defaultCurrency;
const { data: mpShopData, loading: mpShopLoading } = useShopDetails({
shopId: miraklShopIds ? parseInt(miraklShopIds) : undefined
});
const removeFacet = () => {
const { miraklShopName, miraklShopIds: testeId, ...rest } = region!;
setSelectedRegion({
...rest
});
window.location.reload();
};
const onSetQtdProducts = i => {
setNumberItems(Number(i));
setPagination({
...pagination,
pageSize: Number(i)
});
};
const { setCartSideMenu } = useCartSideMenu();
const { filterSideMenu, setFilterSideMenu } = useFilterSideMenu();
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
};
useEffect(() => {
if (!mpShopLoading) {
if (mpShopData?.mpShop?.eav_option_id && miraklShopIds) {
setShopId(mpShopData?.mpShop?.eav_option_id?.toString());
}
}
}, [mpShopLoading]);
useEffect(() => {
if (!miraklShopIds) {
setShopId(undefined);
}
}, [miraklShopIds]);
useEffect(() => {
setPagination({
...pagination,
totalPages: totalPages,
totalCount: countItems
});
}, [totalPages, countItems]);
useEffect(() => {
setPagination({
...pagination
});
}, [categoryId]);
function getCurrentDimension() {
return {
width: window.innerWidth,
height: window.innerHeight
};
}
const [screenSize, setScreenSize] = useState(getCurrentDimension());
useEffect(() => {
const updateDimension = () => {
setScreenSize(getCurrentDimension());
};
window.addEventListener('resize', updateDimension);
if (screenSize.width > 1055) {
setFilterSideMenu({ openSideMenu: false });
}
return () => {
window.removeEventListener('resize', updateDimension);
};
}, [screenSize]);
return (
<>
<S.Container>
<LayoutSpacing size="sm" />
<BackgroundMKT />
<Grid>
<Row>
<Column>
<LayoutSpacing size="xs" />
<S.SearchContainer>
<div className="searchContainer">
<SearchForm />
</div>
</S.SearchContainer>
</Column>
</Row>
<Row>
<Column>
<CategoryBreadcrumbContainer
categoryId={categoryId}
categoryUrlFactory={categoryUrlFactory}
render={args => <Breadcrumb {...args} />}
renderLoading={() => <Breadcrumb.Skeleton />}
/>
<S.ListingBySort>
<div className="titleSearchMobile">
{term === '' ||
term === '""' ||
term === 'undefined' ||
term === undefined ? null : (
<p>Resultado para: "{term}"</p>
)}
</div>
<div className="filter-market-mobile">
{region?.miraklShopName && (
<S.Tags>
<Tag
onClick={() => removeFacet()}
key={`tag-${region?.miraklShopName}`}
label={getLabelText('Buscando por loja', region?.miraklShopName)}
/>
</S.Tags>
)}
</div>
</S.ListingBySort>
</Column>
</Row>
<CmsContainer name="cat">
<CmsSpot
name="hero"
render={content => (
<Row>
<Column>
{content}
<LayoutSpacing size="sm" />
</Column>
</Row>
)}
/>
<Row>
<LayoutSpacing size="xs" />
<Column lg={'25%'}>
<S.FilterContainer>
<div className="containerFilters">
{/* CATEGORIA PRINCIPAL */}
<CategoryNavigationContainer
categoryPath={categoryPath}
render={args => (
<CategoryNavigation
{...args}
categoryUrlFactory={categoryUrlFactory}
pathname={pathname}
/>
)}
renderLoading={() => <CategoryNavigation.Skeleton />}
/>
{/* FILTRO DINAMICO */}
<CategoryFiltersContainer
categoryId={categoryId}
currency={currency!}
selectedFacets={facetState?.state?.selectedFacets}
hasPriceFilters={catalogConfig.filters?.includesPrice}
term={term}
render={args => (
<Filters
{...args}
onToggleFacet={facetState.ops.toggleFacet}
onReplaceFacets={facetState.ops.replaceFacets}
onRemoveFacet={facetState.ops.removeFacet}
/>
)}
renderLoading={() => <Filters.Skeleton />}
/>
</div>
</S.FilterContainer>
</Column>
<Column lg={'75%'}>
<S.ListingBySort>
<div className="titleSearch">
{term === '' ||
term === '""' ||
term === 'undefined' ||
term === undefined ? null : (
<p>Resultado para: "{term}"</p>
)}
</div>
<Row>
<Column sm={'100%'}>
<div className="container-filters-sort">
<div className="qtd-offers">{lenghtOffers} produtos</div>
<div className="qtd-filter">
<S.ContainerWrap>
{/* FILTRO DE PAGINAÇÃO */}
<ListingByNumber
onChange={e => onSetQtdProducts(e)}
numberSelect={pagination.pageSize.toString()}
data={DEFAULT_FILTER_PAGINATION}
/>
<S.Divisors />
<S.TitleItems>
1 - {numberItems} de {lenghtOffers} item(s)
</S.TitleItems>
<S.Divisors />
</S.ContainerWrap>
</div>
<ListingTypeToggle
onChange={facetState.ops.setDisplayMode}
mode={facetState.state?.displayMode}
/>
<S.ShortFilter>
<div className="shortfilterLeft">
<S.DivisorsRight />
</div>
</S.ShortFilter>
<S.ShortFilter>
<div className="shortfilter">
<ListingSortBy
onChange={facetState.ops.setSort}
sort={facetState.state?.sort}
data={DEFAULT_FILTER_PRODUCT}
/>
</div>
</S.ShortFilter>
<S.DivisorsRight />
<button
className="filter-button"
type="button"
onClick={() => setFilterSideMenu({ openSideMenu: true })}
>
<Filter24 /> Filtros
</button>
<div className="listing-sort">
{/* FILTRO DOS PRODUTOS */}
<ListingSortBy
onChange={facetState.ops.setSort}
sort={facetState.state?.sort}
data={DEFAULT_FILTER_PRODUCT}
/>
</div>
<div className="divisor-market-right">
<S.DivisorsRight />
</div>
<div className="container-market">
{region?.miraklShopName && (
<S.Tags>
<Tag
onClick={() => removeFacet()}
key={`tag-${region?.miraklShopName}`}
label={getLabelText('Buscando por loja', region?.miraklShopName)}
/>
</S.Tags>
)}
</div>
</div>
</Column>
</Row>
</S.ListingBySort>
<LayoutSpacing size="xs" />
<Row>
<Column sm={'100%'}>
<div className="verde" />
{!mpShopLoading && (
<SearchListingContainerByCatAndName
categoryId={categoryId}
miraklShopIds={shopId}
regionList={regionList}
miraklRegion={miraklRegion}
term={term}
sort={facetState.state?.sort}
selectedFacets={[
...facetState.state?.baseFacets,
...(facetState.state?.selectedFacets ?? [])
]}
shopIds={shopIds}
storeId={sessionContext?.storeId}
currency={currency!}
useAvailability={catalogConfig.plp?.availability}
useReviews={catalogConfig.plp?.reviews}
renderLoading={() => {
return <Loading />;
}}
// qualquer coisa voltar pro render abaixo
render={({
hasMore,
productData,
onLoadMore,
pageInfo,
hasOfferByRegion
}) => {
const offers = productData?.filter(product => {
return product;
});
setTotalPages(pageInfo?.total_pages);
setCountItems(pageInfo?.total_count);
//stacktrace erro
setLenghtOffers(offers?.length);
return (
<>
<S.ContainerWrapMobile>
<ListingByNumber
onChange={e => onSetQtdProducts(e)}
numberSelect={pagination.pageSize.toString()}
data={DEFAULT_FILTER_PAGINATION}
/>
<S.DivisorsDown />
<S.TitleItems>
1 - {numberItems} de {lenghtOffers} item(s)
</S.TitleItems>
</S.ContainerWrapMobile>
{/* CATALOGO DE PRODUTOS */}
<ProductView
qtdProducts={numberItems}
mode={facetState.state?.displayMode}
productData={offers}
onLoadMore={onLoadMore}
hasMore={hasMore}
openSideMenu={setCartSideMenu}
hasOfferByRegion={hasOfferByRegion}
/>
</>
);
}}
/>
)}
<LayoutSpacing size="sm" />
</Column>
</Row>
</Column>
</Row>
<CmsSpot
name="footer"
render={content => (
<Row>
<Column>{content}</Column>
</Row>
)}
/>
</CmsContainer>
<LayoutSpacing size="xl" />
</Grid>
<FilterSidePanelMemo
isOpen={filterSideMenu?.openSideMenu}
position="right"
isCloseOnOverlayClick
onClose={() => setFilterSideMenu({ openSideMenu: false })}
elevation={9999}
>
<div className="containerFiltersMob">
<CategoryNavigationContainer
categoryPath={categoryPath}
render={args => (
<CategoryNavigation
{...args}
categoryUrlFactory={categoryUrlFactory}
pathname={pathname}
/>
)}
renderLoading={() => <CategoryNavigation.Skeleton />}
/>
<CategoryFiltersContainer
categoryId={categoryId}
currency={currency!}
selectedFacets={facetState?.state?.selectedFacets}
hasPriceFilters={catalogConfig.filters?.includesPrice}
term={term}
render={args => (
<Filters
{...args}
onToggleFacet={facetState.ops.toggleFacet}
onReplaceFacets={facetState.ops.replaceFacets}
onRemoveFacet={facetState.ops.removeFacet}
/>
)}
renderLoading={() => <Filters.Skeleton />}
/>
</div>
</FilterSidePanelMemo>
<div className="chatBtn">
<ChatbotBox />
</div>
</S.Container>
<S.ZoneButton>
<S.BackToTop onClick={() => scrollToTop()}> Voltar ao topo</S.BackToTop>
</S.ZoneButton>
</>
);
};
type Props = {
categoryId: CategoryRef;
miraklShopIds?: string;
regionList?: string[];
miraklRegion?: string[];
term: string;
categoryPath: CategoryRef[];
catalogConfig: CatalogConfig;
params?: {
selectedFilters?: string;
};
};