Skip to content

Commit

Permalink
feat: add productCategory and productListingPage loader
Browse files Browse the repository at this point in the history
  • Loading branch information
yuriassuncx committed Nov 1, 2024
1 parent 2bf920b commit 3724358
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 7 deletions.
4 changes: 3 additions & 1 deletion vtex/loaders/intelligentSearch/productListingPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ const loader = async (
? filtersFromPathname(pageTypes)
: baseSelectedFacets;
const selected = withDefaultFacets(selectedFacets, ctx);
const fselected = selected.filter((f) => f.key !== "price");
const fselected = props.priceFacets
? selected
: selected.filter((f) => f.key !== "price");
const isInSeachFormat = Boolean(selected.length) || Boolean(args.query);
const pathQuery = queryFromPathname(isInSeachFormat, pageTypes, url.pathname);
const searchArgs = { ...args, query: args.query || pathQuery };
Expand Down
38 changes: 38 additions & 0 deletions woocommerce/loaders/product/productCategory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { RequestURLParam } from "../../../website/functions/requestToParam.ts";
import { AppContext } from "../../mod.ts";
import { Category } from "../../utils/types.ts";

export interface Props {
slug?: RequestURLParam;
}

/**
* @title WooCommerce Integration
* @description Product Category loader
*/
async function loader(
props: Props,
req: Request,
ctx: AppContext,
): Promise<Category | null> {
const { slug } = props;
const { api } = ctx;

const urlPathname = new URL(req.url).pathname;

const pathname = (slug || urlPathname).split("/").filter(Boolean).pop();

if (!pathname) return null;

const categories = await api["GET /wc/v3/products/categories"]({
slug,
}).then((res) => res.json());

const category = categories.find((item) => item.slug === pathname);

if (!category) return null;

return category;
}

export default loader;
92 changes: 92 additions & 0 deletions woocommerce/loaders/product/productListingPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { ProductListingPage } from "../../../commerce/types.ts";
import { AppContext } from "../../mod.ts";
import { toProduct } from "../../utils/transform.ts";
import { Order, OrderBy, Status, StockStatus } from "../../utils/types.ts";
import { WOOCOMMERCE_SORT_OPTIONS } from "../../utils/utils.ts";

export interface Props {
/**
* @description overrides the query term at url
*/
query?: string;
/**
* @default 1
*/
page: number;
/**
* @title Per Page
* @default 12
* @description Maximum number of items to be returned in result set. Default is 12.
*/
per_page: number;
order?: Order;
order_by?: OrderBy;
status?: Status;
stock_status?: StockStatus;
}

/**
* @title WooCommerce Integration
* @description Product Listing Page loader
*/
async function loader(
props: Props,
req: Request,
ctx: AppContext,
): Promise<ProductListingPage | null> {
const url = new URL(req.url);
const pathname = url.pathname.split("/").filter(Boolean).pop();

const { page = 1, per_page = 12, query } = props;
const { api } = ctx;

const category = await ctx.invoke.woocommerce.loaders.product.productCategory(
{
slug: pathname,
},
);

const products = await api["GET /wc/v3/products"]({
...props,
page,
per_page,
category: !query ? category?.id?.toString() : undefined,
search: query,
}).then((res) => res.json());

if (!products) return null;

const totalPages = Math.ceil((category?.count ?? 0) / props.per_page);
const notHasNextPage = totalPages == page;

return {
"@type": "ProductListingPage",
products: products.map((product) => toProduct(product)),
sortOptions: WOOCOMMERCE_SORT_OPTIONS,
filters: [],
pageInfo: {
previousPage: page == 1 ? undefined : Number(page + 1).toString(),
currentPage: page,
nextPage: notHasNextPage ? undefined : Number(page + 1).toString(),
},
breadcrumb: {
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem" as const,
name: category?.name,
position: 1,
item: new URL(category?.slug ?? "").href,
},
],
numberOfItems: category?.count ?? 0,
},
seo: {
title: query || category?.name || pathname?.replaceAll("-", " ") || "",
description: category?.description ?? "",
canonical: pathname || req.url,
},
};
}

export default loader;
16 changes: 10 additions & 6 deletions woocommerce/manifest.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
// This file SHOULD be checked into source version control.
// This file is automatically updated during development when running `dev.ts`.

import * as $$$0 from "./loaders/product/productDetailsPage.ts";
import * as $$$1 from "./loaders/product/productList.ts";
import * as $$$2 from "./loaders/proxy.ts";
import * as $$$0 from "./loaders/product/productCategory.ts";
import * as $$$1 from "./loaders/product/productDetailsPage.ts";
import * as $$$2 from "./loaders/product/productList.ts";
import * as $$$3 from "./loaders/product/productListingPage.ts";
import * as $$$4 from "./loaders/proxy.ts";

const manifest = {
"loaders": {
"woocommerce/loaders/product/productDetailsPage.ts": $$$0,
"woocommerce/loaders/product/productList.ts": $$$1,
"woocommerce/loaders/proxy.ts": $$$2,
"woocommerce/loaders/product/productCategory.ts": $$$0,
"woocommerce/loaders/product/productDetailsPage.ts": $$$1,
"woocommerce/loaders/product/productList.ts": $$$2,
"woocommerce/loaders/product/productListingPage.ts": $$$3,
"woocommerce/loaders/proxy.ts": $$$4,
},
"name": "woocommerce",
"baseUrl": import.meta.url,
Expand Down
8 changes: 8 additions & 0 deletions woocommerce/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SortOption } from "../../commerce/types.ts";

export const WOOCOMMERCE_SORT_OPTIONS: SortOption[] = [
{ value: "date", label: "Data" },
{ value: "price", label: "Preço" },
{ value: "popularity", label: "Popularidade" },
{ value: "rating", label: "Média de Classificação" },
];

0 comments on commit 3724358

Please sign in to comment.