Untitled

 avatar
unknown
plain_text
2 years ago
18 kB
3
Indexable
/*
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;
  };
};