Untitled

mail@pastecode.io avatar
unknown
javascript
10 days ago
4.2 kB
0
Indexable
Never
import {fetchAPI, useSendGAEvent} from '~/utils';
import type {LoaderArgs} from '@shopify/remix-oxygen';
import {defer} from '@shopify/remix-oxygen';
import {useLoaderData} from '@remix-run/react';
import {useRef} from 'react';
import {EventNames} from '~/utils/googleAnalytics';
import ProductListListingPage from './components/ProductListListingPage';
import { MemoizedFields, MetaobjectResponse } from './types/listingPageTypes';
import PageHeaderListingPage from './components/PageHeaderListingPage';
import { TProductInfo } from '~/types';

export async function loader({ params, context, request }: LoaderArgs) {
  const { handle } = params;
  const url = new URL(request.url);
  let category: any = [];

  try {
    const [reqCollection, reqVideo] = await Promise.all([
      fetchAPI('/api/shopify/custom-menu-metaobject', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          first: 26,
          type: 'custom_menu',
          handle,
          language: params.language ? params.language.toUpperCase() : 'IT',
          country: 'IT',
        }),
      }, context, request),

      fetchAPI('/api/shopify/metaobjects-new', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          first: 26,
          type: 'custom_menu',
          language: params.language ? params.language.toUpperCase() : 'IT',
          country: 'IT',
        }),
      }, context, request),
    ]);

    if (reqVideo.status == 200) {
      const metaobject: MetaobjectResponse = await reqVideo.json() as MetaobjectResponse;

      const categoryData = metaobject.metaobjects.edges.find(
        (el) => el.node.handle === handle,
      );
      category = categoryData?.node || [];
    } else {
      throw new Response(null, { status: 404, statusText: 'Not Found' });
    }

    if (reqCollection.status == 200) {
      const check: any = await reqCollection.json();
      if (check) {
        const categoryWithCollections = {
          ...category,
          fields: [
            ...category.fields.filter((el: any) => el.key !== 'collection'),
            { ...check?.fields?.find((item: any) => item.key === 'collection') },
          ],
        };
        category = categoryWithCollections;
      }
    } else {
      throw new Error(`Error fetching collection: ${reqCollection.statusText}`);
    }
  } catch (error) {
    console.error(error);
    throw new Error('E101: Errore nel recuperare le informazioni.');
  }

  return defer({ category });
}

const ListingPage = () => {
  const {category} = useLoaderData<typeof loader>();

  const valuesRef = useRef<null | {
    memoizedFields: MemoizedFields;
    products: TProductInfo[];
    hasVideo: boolean;
  }>(null);
  
  if (valuesRef.current === null) {
    const getField = (key: string) => category.fields.find((e: any) => e.key === key);
    
    const fields = {
      titolo_menu: getField('titolo_menu'),
      video: getField('video'),
      video_mobile: getField('video_mobile'),
      titolo_pagina: getField('titolo'),
      titolo_lista: getField('titolo_lista'),
      descrizione_pagina: getField('descrizione'),
      collection: getField('collection'),
    };
  
    valuesRef.current = {
      memoizedFields: fields,
      products: fields.collection?.reference?.products?.nodes || [],
      hasVideo: Boolean(fields.video?.reference?.sources?.[0]?.url)
    };
  }
  
  const { memoizedFields, products, hasVideo } = valuesRef.current;

  useSendGAEvent(EventNames.ViewItemList, {
    item_list_id: memoizedFields.titolo_lista?.value ?? 'custom menu products',
    items: products,
  });

  return (
    <div className="w-full bg-background" data-element="preferiti-di-cristina-listing-page">
      <div className="container-site mx-auto relative">
        {memoizedFields.titolo_pagina && <PageHeaderListingPage memoizedFields={memoizedFields} hasVideo={hasVideo} category={category} />}
        <ProductListListingPage products={products} titolo_lista={memoizedFields.titolo_lista} />
      </div>
    </div>
  );
};

export default ListingPage;
Leave a Comment