Skip to content

Commit

Permalink
Merge pull request #16 from deco-sites/karla-tec3
Browse files Browse the repository at this point in the history
feat: search page
  • Loading branch information
karlaoshikawa authored Oct 15, 2024
2 parents 8d1d567 + 28e5c4c commit 7be0d9a
Show file tree
Hide file tree
Showing 10 changed files with 697 additions and 228 deletions.
3 changes: 3 additions & 0 deletions .deco/blocks/Preview%20%2Fsections%2FSearchText.tsx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"__resolveType": "site/sections/SearchText.tsx"
}
114 changes: 114 additions & 0 deletions .deco/blocks/pages-CATEGORIA%2520EXEMPLO-887962.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"name": "CATEGORIA EXEMPLO",
"path": "/example",
"sections": [
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "commerce/sections/Seo/SeoPLPV2.tsx",
"jsonLD": {
"__resolveType": "vnda/loaders/productListingPage.ts",
"count": 16,
"tags": [],
"filterOperator": {
"type_tags": "and",
"property1": "and",
"property2": "and",
"property3": "and"
},
"slug": {
"__resolveType": "website/functions/requestToParam.ts",
"param": "slug"
}
}
}
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "Header"
}
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "site/sections/WideBanner.tsx",
"images": {
"desktop": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/9d9003ed-0705-43dd-8ea5-201a4a4969ad/quem-somos-banner.png",
"mobile": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/9d9003ed-0705-43dd-8ea5-201a4a4969ad/quem-somos-banner.png"
},
"alt": "categoria"
}
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "site/sections/Product/SearchResult.tsx",
"page": {
"__resolveType": "vnda/loaders/productListingPage.ts",
"count": 16,
"tags": [],
"filterOperator": {
"type_tags": "and",
"property1": "and",
"property2": "and",
"property3": "and"
},
"slug": {
"__resolveType": "website/functions/requestToParam.ts",
"param": "slug"
}
},
"layout": {
"columns": {
"mobile": 2,
"desktop": 4
},
"variant": "aside",
"pagination": "pagination"
},
"startingPage": 1,
"button": [
{
"image": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/49d34224-85e1-448b-80ba-24361df54712/4blocks.svg"
},
{
"image": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/d070e980-9aeb-4ead-9a1f-e6e64a76b8a2/6blocks.svg"
},
{
"image": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/628f2b43-2164-499b-bf9c-27eaefc78ae6/8blocks.svg"
}
],
"buttons": [
{
"icone": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/49d34224-85e1-448b-80ba-24361df54712/4blocks.svg"
},
{
"icone": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/d070e980-9aeb-4ead-9a1f-e6e64a76b8a2/6blocks.svg"
},
{
"icone": "https://deco-sites-assets.s3.sa-east-1.amazonaws.com/arena-center/628f2b43-2164-499b-bf9c-27eaefc78ae6/8blocks.svg"
}
]
}
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "site/sections/SearchText.tsx",
"description": "<p><strong>Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.</p>",
"title": "Lorem Ipsum"
}
},
{
"__resolveType": "website/sections/Rendering/Lazy.tsx",
"section": {
"__resolveType": "Footer"
}
}
],
"seo": {
"__resolveType": "website/sections/Seo/SeoV2.tsx"
},
"__resolveType": "website/pages/Page.tsx"
}
6 changes: 3 additions & 3 deletions components/WideBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ function Banner({ images, href, alt }: Props) {
return (
<a class="relative mx-auto w-screen hidden md:block" href={href}>
<Picture>
<Source media="(max-width: 640px)" src={images.mobile} width={390} />
<Source media="(max-width: 640px)" src={images.mobile || images.desktop} width={390} />
<Source
media="(min-width: 640px)"
src={images.desktop}
width={1200}
width={1440}
height={176}
loading={"lazy"}
/>
<img
src={images.desktop}
alt={alt}
loading={"lazy"}
class=" w-screen max-w-[1440px] px-6 mt-2 h-auto object-cover mx-auto"
class=" w-full max-w-[1440px] px-6 mt-2 h-auto object-cover mx-auto"
/>
</Picture>
</a>
Expand Down
233 changes: 233 additions & 0 deletions components/product/ProductCardSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import type { Product } from "apps/commerce/types.ts";
import { mapProductToAnalyticsItem } from "apps/commerce/utils/productToAnalyticsItem.ts";
import Image from "apps/website/components/Image.tsx";
import { clx } from "../../sdk/clx.ts";
import { formatPrice } from "../../sdk/format.ts";
import { relative } from "../../sdk/url.ts";
import { useOffer } from "../../sdk/useOffer.ts";
import { useSendEvent } from "../../sdk/useSendEvent.ts";
import { useVariantPossibilities } from "../../sdk/useVariantPossiblities.ts";
import WishlistButton from "../wishlist/WishlistButton.tsx";
import AddToCartButton from "./AddToCartButton.tsx";
import { Ring } from "./ProductVariantSelector.tsx";
import { useId } from "../../sdk/useId.ts";

interface Props {
product: Product;
/** Preload card image */
preload?: boolean;

/** @description used for analytics event */
itemListName?: string;

/** @description index of the product card in the list */
index?: number;

class?: string;
}

const WIDTH = 295;
const HEIGHT = 378;
const ASPECT_RATIO = `${WIDTH} / ${HEIGHT}`;

function ProductCard({
product,
preload,
itemListName,
index,
class: _class,
}: Props) {
const id = useId();

const { url, image: images, offers, isVariantOf } = product;
const hasVariant = isVariantOf?.hasVariant ?? [];
const title = isVariantOf?.name ?? product.name;
const [front, back] = images ?? [];

const { listPrice, price, seller = "1", availability } = useOffer(offers);
const inStock = availability === "https://schema.org/InStock";
const possibilities = useVariantPossibilities(hasVariant, product);
const firstSkuVariations = Object.entries(possibilities)?.[0];
const variants = Object.entries(firstSkuVariations?.[1] ?? {});
const relativeUrl = relative(url);
const percent = listPrice && price
? Math.round(((listPrice - price) / listPrice) * 100)
: 0;

const item = mapProductToAnalyticsItem({ product, price, listPrice, index });

{/* Add click event to dataLayer */}
const event = useSendEvent({
on: "click",
event: {
name: "select_item" as const,
params: {
item_list_name: itemListName,
items: [item],
},
},
});

//Added it to check the variant name in the SKU Selector later, so it doesn't render the SKU to "shoes size" in the Product Card
const firstVariantName = firstSkuVariations?.[0]?.toLowerCase();
const shoeSizeVariant = "shoe size";

return (
<div
{...event}
class={clx(
"card card-compact group text-sm min-w-[295px] min-h-[498px]",
_class
)}
>
<figure
class={clx(
"relative bg-base-100 min-w-[295px] min-h-[498px]",
"rounded border border-transparent",
"group-hover:border-primary"
)}
style={{ aspectRatio: ASPECT_RATIO }}
>
{/* Product Images */}
<a
href={relativeUrl}
aria-label="view product"
class={clx(
"absolute top-0 left-0",
"grid grid-cols-1 grid-rows-1",
"w-full",
!inStock && "opacity-70"
)}
>
<Image
src={front.url!}
alt={front.alternateName}
width={295}
height={378}
style={{ aspectRatio: ASPECT_RATIO }}
class={clx(
"object-contain",
"rounded w-full",
"col-span-full row-span-full"
)}
preload={preload}
loading={preload ? "eager" : "lazy"}
decoding="async"
/>
<Image
src={back?.url ?? front.url!}
alt={back?.alternateName ?? front.alternateName}
width={295}
height={378}
style={{ aspectRatio: ASPECT_RATIO }}
class={clx(
"object-contain",
"rounded w-full",
"col-span-full row-span-full",
"transition-opacity opacity-0 lg:group-hover:opacity-100"
)}
loading="lazy"
decoding="async"
/>
</a>

{/* Wishlist button */}
{/* <div class="absolute top-0 left-0 w-full flex items-center justify-between">
<span
class={clx(
"text-sm/4 font-normal text-black bg-error bg-opacity-15 text-center rounded-badge px-2 py-1",
inStock && "opacity-0"
)}
>
Notify me
</span>
</div> */}

{/* Discounts */}
<span
class={clx(
"absolute top-2 left-2",
"text-[12px] font-normal text-base-100 bg-primary text-center rounded-[4px] px-2 py-1",
(percent < 1 || !inStock) && "opacity-0"
)}
>
{percent} % off
</span>

{/* <div class="absolute bottom-0 right-0">
<WishlistButton item={item} variant="icon" />
</div> */}
</figure>

<a href={relativeUrl} class="pt-4">
<span class="font-medium text-sm">{title}</span>

<div class="flex gap-2 pt-2">
{listPrice && (
<span class="line-through font-normal text-gray-600 text-[10px]">
{formatPrice(listPrice, offers?.priceCurrency)}
</span>
)}
<span class="font-semibold text-secondary text-[12px]">
{formatPrice(price, offers?.priceCurrency)}
</span>
</div>
</a>

{/* SKU Selector */}
{/* {variants.length > 1 && firstVariantName !== shoeSizeVariant && (
<ul class="flex items-center justify-start gap-2 pt-4 pb-1 pl-1 overflow-x-auto">
{variants
.map(([value, link]) => [value, relative(link)] as const)
.map(([value, link]) => (
<li>
<a href={link} class="cursor-pointer">
<input
class="hidden peer"
type="radio"
name={`${id}-${firstSkuVariations?.[0]}`}
checked={link === relativeUrl}
/>
<Ring value={value} checked={link === relativeUrl} />
</a>
</li>
))}
</ul>
)} */}

<div class="flex-grow" />

<div>
{inStock ? (
<AddToCartButton
product={product}
seller={seller}
item={item}
class={clx(
"btn",
"btn-outline justify-center border-gray-300 !text-sm !font-medium px-0 no-animation w-full",
"hover:!bg-primary",
"hover:!text-base-100"
)}
/>
) : (
<a
href={relativeUrl}
class={clx(
"btn",
"btn-outline justify-start border-none !text-sm !font-medium px-0 no-animation w-full h-29",
"hover:!bg-transparent",
"disabled:!bg-transparent disabled:!opacity-75",
"btn-error hover:!text-error disabled:!text-error"
)}
>
Fora de estoque
</a>
)}
</div>
</div>
);
}

export default ProductCard;
Loading

0 comments on commit 7be0d9a

Please sign in to comment.