Skip to content

Commit

Permalink
create routes
Browse files Browse the repository at this point in the history
  • Loading branch information
DuvCharles committed Nov 11, 2023
1 parent 6fc0745 commit a6c1482
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 25 deletions.
8 changes: 0 additions & 8 deletions app/api/revalidate/route.ts

This file was deleted.

2 changes: 1 addition & 1 deletion components/carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GridTileImage } from './grid/tile';

export async function Carousel() {
// Collections that start with `hidden-*` are hidden from the search page.
const products = await getCollectionProducts({ collection: 'hidden-homepage-carousel' });
const products = await getCollectionProducts({});

if (!products?.length) return null;

Expand Down
4 changes: 1 addition & 3 deletions components/grid/three-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ function ThreeItemGridItem({

export async function ThreeItemGrid() {
// Collections that start with `hidden-*` are hidden from the search page.
const homepageItems = await getCollectionProducts({
collection: 'hidden-homepage-featured-items'
});
const homepageItems = await getCollectionProducts({});

if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null;

Expand Down
4 changes: 4 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export const TAGS = {
products: 'products'
};

export const DEFAULT_OPTION = 'Default Title';

export const HIDDEN_PRODUCT_TAG = 'nextjs-frontend-hidden';

export const SYLIUS_API_ENDPOINT = '/api/v2/shop';

export const REST_METHODS = {
Expand Down
112 changes: 102 additions & 10 deletions lib/sylius/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { REST_METHODS, SYLIUS_API_ENDPOINT } from 'lib/constants';
import { normalizeCollection } from './normalizer/collection-normalizer';
import { normalizeProduct } from './normalizer/product-normalizer';
import { SyliusProduct, SyliusTaxon } from './sylius-types/product-types';
import { AddToCartPayload, GetCollectionProductsPayload, GetProductsPayload } from './types';

const DOMAIN = `${process.env.SYLIUS_STORE_DOMAIN}`;
const ENDPOINT = `${DOMAIN}${SYLIUS_API_ENDPOINT}`;
Expand All @@ -12,7 +16,8 @@ export default async function syliusRequest(
const options: RequestInit = {
method,
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
Accept: 'application/json'
}
};

Expand Down Expand Up @@ -45,11 +50,100 @@ export const getPages = () => [];
export const getPage = () => {};

// Products
export const getProducts = () => [];
export const getProduct = () => {};
export const getProductRecommendations = () => [];
export const getCollection = () => {};
export const getCollectionProducts = () => [];
export const getProducts = async (payload: GetProductsPayload) => {
const url = new URL(`${ENDPOINT}/products`);
if (payload.query) {
url.searchParams.set('translations.name', payload.query);
}
const orderBy = payload.reverse ? 'desc' : 'asc';

if (payload.sortKey) {
switch (payload.sortKey) {
case 'RELEVANCE':
break;
case 'BEST_SELLING':
break;
case 'CREATED_AT':
url.searchParams.set('order[createdAt]', orderBy);
break;
case 'PRICE':
url.searchParams.set('order[price]', orderBy);
break;
default:
break;
}
}

const data = await syliusRequest(REST_METHODS.GET, '/products' + url.search);
const syliusProducts = data.body;
const products = syliusProducts.map((syliusProduct: SyliusProduct) =>
normalizeProduct(syliusProduct)
);
return products;
};

export const getProduct = async (slug: string) => {
const data = await syliusRequest(REST_METHODS.GET, '/products-by-slug/' + slug);

const syliusProduct = data.body;
const product = normalizeProduct(syliusProduct);

return product;
};
export const getProductRecommendations = () => {
return [];
};
export const getCollections = async () => {
const data = await syliusRequest(REST_METHODS.GET, '/taxons');

const syliusTaxons = data.body;
const collections = syliusTaxons.map((syliusTaxon: SyliusTaxon) =>
normalizeCollection(syliusTaxon)
);

return collections;
};

export const getCollection = async (taxonCode: string) => {
const data = await syliusRequest(REST_METHODS.GET, '/taxons/' + taxonCode);

const syliusTaxon = data.body;
const collection = normalizeCollection(syliusTaxon);

return collection;
};

export const getCollectionProducts = async (payload: GetCollectionProductsPayload) => {
const url = new URL(`${ENDPOINT}/products`);
if (payload.collection) {
url.searchParams.set('productTaxons.taxon.code', payload.collection);
}
const orderBy = payload.reverse ? 'desc' : 'asc';

if (payload.sortKey) {
switch (payload.sortKey) {
case 'RELEVANCE':
break;
case 'BEST_SELLING':
break;
case 'CREATED_AT':
url.searchParams.set('order[createdAt]', orderBy);
break;
case 'PRICE':
url.searchParams.set('order[price]', orderBy);
break;
default:
break;
}
}

const data = await syliusRequest(REST_METHODS.GET, '/products' + url.search);
const syliusProducts = data.body;
const products = syliusProducts.map((syliusProduct: SyliusProduct) =>
normalizeProduct(syliusProduct)
);
return products;
};

// Cart
export const createCart = async () => {
Expand All @@ -70,9 +164,7 @@ export const updateCart = () => {};
// Site
export const getMenu = () => [
{
title: 'Home',
path: '/'
title: 'All',
path: '/search'
}
];

type AddToCartPayload = { merchandiseId: string; quantity: number };
14 changes: 14 additions & 0 deletions lib/sylius/normalizer/collection-normalizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { SyliusTaxon } from '../sylius-types/product-types';
import { Collection } from '../types';

export const normalizeCollection = (syliusTaxon: SyliusTaxon): Collection => {
return {
seo: {
title: syliusTaxon.name,
description: syliusTaxon.description
},
code: syliusTaxon.code,
title: syliusTaxon.name,
path: `/search/${syliusTaxon.code}`
};
};
4 changes: 4 additions & 0 deletions lib/sylius/normalizer/product-normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import {
import { Image, Money, Product, ProductOption, ProductVariant } from '../types';

export const normalizeProduct = (product: SyliusProduct): Product => ({
seo: {
title: product.name,
description: product.shortDescription
},
variants: product.variants.map((variant) => normalizeProductVariant(variant)),
images: product.images.map((image) => normalizeProductImage(image)),
id: product.id.toString(),
Expand Down
28 changes: 28 additions & 0 deletions lib/sylius/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export interface Money {
}

export interface Product {
seo?: {
title?: string;
description?: string;
};
variants: ProductVariant[];
images: Image[];
id: string;
Expand Down Expand Up @@ -79,3 +83,27 @@ export interface Menu {
title: string;
path: string;
}

export interface Collection {
seo?: {
title?: string;
description?: string;
};
code: string;
title: string;
path: string;
}

export interface GetCollectionProductsPayload {
collection?: string;
sortKey?: 'RELEVANCE' | 'BEST_SELLING' | 'CREATED_AT' | 'PRICE';
reverse?: boolean;
}

export interface GetProductsPayload {
sortKey?: 'RELEVANCE' | 'BEST_SELLING' | 'CREATED_AT' | 'PRICE';
reverse?: boolean;
query?: string;
}

export type AddToCartPayload = { merchandiseId: string; quantity: number };
11 changes: 11 additions & 0 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ReadonlyURLSearchParams } from 'next/navigation';

export const createUrl = (pathname: string, params: URLSearchParams | ReadonlyURLSearchParams) => {
const paramsString = params.toString();
const queryString = `${paramsString.length ? '?' : ''}${paramsString}`;

return `${pathname}${queryString}`;
};

export const ensureStartsWith = (stringToCheck: string, startsWith: string) =>
stringToCheck.startsWith(startsWith) ? stringToCheck : `${startsWith}${stringToCheck}`;
6 changes: 3 additions & 3 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ module.exports = {
formats: ['image/avif', 'image/webp'],
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.shopify.com',
pathname: '/s/files/**'
protocol: 'http',
hostname: 'localhost',
pathname: '/media/**'
}
]
},
Expand Down

0 comments on commit a6c1482

Please sign in to comment.