Untitled
unknown
javascript
a year ago
7.1 kB
13
Indexable
import {cn, fetchAPI, useSendGAEvent} from '~/utils';
import type {LoaderArgs} from '@shopify/remix-oxygen';
import {defer} from '@shopify/remix-oxygen';
import {useLoaderData, useParams} from '@remix-run/react';
import {
TCollectionsList,
TMetaobjectListing,
TProductInfo,
TSingleCollection,
} from '~/types';
import React, {useMemo} from 'react';
import {toHTML} from '~/ui/Utils/richtextToHTML';
import Breadcrumb from '~/ui/Breadcrumb';
import {ProductCardNew} from '~/components/product-card-new';
import ProductVideo from '~/ui/ProductVideo';
import {EventNames} from '~/utils/googleAnalytics';
export async function loader({params, context, request}: LoaderArgs) {
const {handle} = params;
const url = new URL(request.url);
// We call 2 API's, one correctly fetches the video, the other
// correctly fetches the product collection
try {
const reqCollection = await 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,
);
const reqVideo = await 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,
);
// eslint-disable-next-line no-var
var category: any = [];
if (reqVideo.status == 200) {
const metaobject = (await reqVideo.json()) as any;
const categoryData = metaobject.metaobjects.edges.find(
(el: any) => el.node.handle === handle,
);
category = categoryData?.node;
} else {
throw new Response(null, {
status: 404,
statusText: 'Not Found',
});
}
if (reqCollection.status == 200) {
const check = (await reqCollection.json()) as any;
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(JSON.stringify(reqCollection));
}
} 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 titolo_menu = category.fields.filter(
(e: any) => e.key == 'titolo_menu',
);
const video = category.fields.filter((e: any) => e.key == 'video');
const video_mobile = category.fields.filter(
(e: any) => e.key == 'video_mobile',
);
const titolo_pagina = category.fields.filter((e: any) => e.key == 'titolo');
const titolo_lista = category.fields.filter(
(e: any) => e.key == 'titolo_lista',
);
const descrizione_pagina = category.fields.filter(
(e: any) => e.key == 'descrizione',
);
const products = useMemo(() => {
const collection = category.fields.filter(
(e: any) => e.key == 'collection',
);
if (
collection.length > 0 &&
collection[0].reference &&
collection[0].reference.products &&
collection[0].reference.products.nodes
) {
return collection[0].reference.products.nodes;
}
return [];
}, []);
const hasVideo =
video.length > 0 &&
video[0].reference?.sources &&
video[0].reference.sources?.length > 0 &&
video[0].reference.sources[0]?.url;
useSendGAEvent(EventNames.ViewItemList, {
item_list_id: titolo_lista?.[0]?.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">
{titolo_pagina.length > 0 && (
<div className="w-full pb-10">
<Breadcrumb
items={[
{
label: titolo_pagina[0].value,
url: `/custom/${category.handle}`,
},
]}
/>
{/* Title, description and video (if present) */}
<div
className={cn(
'max-w-[1138px] mx-auto',
hasVideo ? 'flex flex-col gap-6 md:flex-row md:gap-4' : '',
)}
>
<div
className={cn(
'flex flex-col gap-2 font-light pb-6',
hasVideo ? 'md:max-w-[445px]' : '',
)}
>
{titolo_menu && titolo_menu.length > 0 && (
<span className="text-[14px] leading-[18px] font-bold text-rhodamine uppercase">
{titolo_menu[0].value}
</span>
)}
{titolo_pagina && titolo_pagina.length > 0 && (
<h3 className="bold">{titolo_pagina[0].value}</h3>
)}
{descrizione_pagina && descrizione_pagina.length > 0 && (
<div
className="text-left"
dangerouslySetInnerHTML={{
__html: toHTML(descrizione_pagina[0].value),
}}
></div>
)}
</div>
{hasVideo && (
<div className="flex items-center justify-center mx-auto w-[320px] xxxs:w-[359px] md:w-[670px]">
<ProductVideo
enabled={true}
video={video[0].reference.sources[0].url}
/>
</div>
)}
</div>
</div>
)}
<div className="container-account mx-auto">
<div className="flex flex-col md:flex-row justify-between mt-6 mb-[120px]">
{products.length > 0 && (
<div>
{titolo_lista.length > 0 && (
<h4 className="mb-6">{titolo_lista[0].value}</h4>
)}
<div className="grid grid-cols-2 md:grid-cols-3 2xl:grid-cols-4 gap-4 justify-center items-center">
{products.map((product: TProductInfo, index: number) => {
return (
<React.Fragment key={product.id}>
<ProductCardNew product={product} />
</React.Fragment>
);
})}
</div>
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default ListingPage;
Editor is loading...
Leave a Comment