mirror of
https://github.com/vercel/commerce.git
synced 2025-05-19 16:07:01 +00:00
tweaks to product mocks
This commit is contained in:
parent
176fc0ea42
commit
e513d3b490
@ -6,7 +6,7 @@ import { Suspense } from 'react';
|
||||
export const runtime = 'edge';
|
||||
|
||||
export const metadata = {
|
||||
description: 'High-performance ecommerce store built with Next.js, Vercel, and Shopify.',
|
||||
description: 'High-performance ecommerce store built with Next.js, Vercel.',
|
||||
openGraph: {
|
||||
type: 'website'
|
||||
}
|
||||
|
@ -4,29 +4,30 @@ import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export const addItem = async (variantId: string | undefined): Promise<String | undefined> => {
|
||||
let cartId = cookies().get('cartId')?.value;
|
||||
let cart;
|
||||
|
||||
if (cartId) {
|
||||
cart = await getCart(cartId);
|
||||
}
|
||||
|
||||
if (!cartId || !cart) {
|
||||
cart = await createCart();
|
||||
cartId = cart.id;
|
||||
// TODO: this is not working under older Next.js versions
|
||||
// cookies().set('cartId', cartId);
|
||||
}
|
||||
|
||||
if (!variantId) {
|
||||
return 'Missing product variant ID';
|
||||
}
|
||||
|
||||
try {
|
||||
await addToCart(cartId, [{ merchandiseId: variantId, quantity: 1 }]);
|
||||
} catch (e) {
|
||||
return 'Error adding item to cart';
|
||||
}
|
||||
// let cartId = cookies().get('cartId')?.value;
|
||||
// let cart;
|
||||
//
|
||||
// if (cartId) {
|
||||
// cart = await getCart(cartId);
|
||||
// }
|
||||
//
|
||||
// if (!cartId || !cart) {
|
||||
// cart = await createCart();
|
||||
// cartId = cart.id;
|
||||
// // TODO: this is not working under older Next.js versions
|
||||
// // cookies().set('cartId', cartId);
|
||||
// }
|
||||
//
|
||||
// if (!variantId) {
|
||||
// return 'Missing product variant ID';
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// await addToCart(cartId, [{ merchandiseId: variantId, quantity: 1 }]);
|
||||
// } catch (e) {
|
||||
// return 'Error adding item to cart';
|
||||
// }
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const removeItem = async (lineId: string): Promise<String | undefined> => {
|
||||
|
@ -31,7 +31,7 @@ export function GridTileImage({
|
||||
{props.src ? (
|
||||
// eslint-disable-next-line jsx-a11y/alt-text -- `alt` is inherited from `props`, which is being enforced with TypeScript
|
||||
<Image
|
||||
className={clsx('relative h-full w-full object-contain', {
|
||||
className={clsx('relative h-full w-full object-cover', {
|
||||
'transition duration-300 ease-in-out group-hover:scale-105': isInteractive
|
||||
})}
|
||||
{...props}
|
||||
|
@ -5,7 +5,10 @@ import LogoSquare from 'components/logo-square';
|
||||
import { getMenu } from 'lib/shopify';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
const { COMPANY_NAME, SITE_NAME } = process.env;
|
||||
// const { COMPANY_NAME, SITE_NAME } = process.env;
|
||||
|
||||
const COMPANY_NAME = 'WKND';
|
||||
const SITE_NAME = 'WKND Adventures Commerce';
|
||||
|
||||
export default async function Footer() {
|
||||
const currentYear = new Date().getFullYear();
|
||||
@ -37,17 +40,17 @@ export default async function Footer() {
|
||||
>
|
||||
<FooterMenu menu={menu} />
|
||||
</Suspense>
|
||||
<div className="md:ml-auto">
|
||||
<a
|
||||
className="flex h-8 w-max flex-none items-center justify-center rounded-md border border-neutral-200 bg-white text-xs text-black dark:border-neutral-700 dark:bg-black dark:text-white"
|
||||
aria-label="Deploy on Vercel"
|
||||
href="https://vercel.com/templates/next.js/nextjs-commerce"
|
||||
>
|
||||
<span className="px-3">▲</span>
|
||||
<hr className="h-full border-r border-neutral-200 dark:border-neutral-700" />
|
||||
<span className="px-3">Deploy</span>
|
||||
</a>
|
||||
</div>
|
||||
{/*<div className="md:ml-auto">*/}
|
||||
{/* <a*/}
|
||||
{/* className="flex h-8 w-max flex-none items-center justify-center rounded-md border border-neutral-200 bg-white text-xs text-black dark:border-neutral-700 dark:bg-black dark:text-white"*/}
|
||||
{/* aria-label="Deploy on Vercel"*/}
|
||||
{/* href="https://vercel.com/templates/next.js/nextjs-commerce"*/}
|
||||
{/* >*/}
|
||||
{/* <span className="px-3">▲</span>*/}
|
||||
{/* <hr className="h-full border-r border-neutral-200 dark:border-neutral-700" />*/}
|
||||
{/* <span className="px-3">Deploy</span>*/}
|
||||
{/* </a>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
<div className="border-t border-neutral-200 py-6 text-sm dark:border-neutral-700">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col items-center gap-1 px-4 md:flex-row md:gap-0 md:px-4 xl:px-0">
|
||||
@ -57,12 +60,12 @@ export default async function Footer() {
|
||||
</p>
|
||||
<hr className="mx-4 hidden h-4 w-[1px] border-l border-neutral-400 md:inline-block" />
|
||||
<p>Designed in California</p>
|
||||
<p className="md:ml-auto">
|
||||
Crafted by{' '}
|
||||
<a href="https://vercel.com" className="text-black dark:text-white">
|
||||
▲ Vercel
|
||||
</a>
|
||||
</p>
|
||||
{/*<p className="md:ml-auto">*/}
|
||||
{/* Crafted by{' '}*/}
|
||||
{/* <a href="https://vercel.com" className="text-black dark:text-white">*/}
|
||||
{/* ▲ Vercel*/}
|
||||
{/* </a>*/}
|
||||
{/*</p>*/}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -31,7 +31,7 @@ export function Gallery({ images }: { images: { src: string; altText: string }[]
|
||||
<div className="relative aspect-square h-full max-h-[550px] w-full overflow-hidden">
|
||||
{images[imageIndex] && (
|
||||
<Image
|
||||
className="h-full w-full object-contain"
|
||||
className="h-full w-full object-cover"
|
||||
fill
|
||||
sizes="(min-width: 1024px) 66vw, 100vw"
|
||||
alt={images[imageIndex]?.altText as string}
|
||||
|
@ -1,5 +1,3 @@
|
||||
import * as console from 'console';
|
||||
|
||||
const baseImagePath = 'https://publish-p64257-e147834-cmstg.adobeaemcloud.com/';
|
||||
|
||||
const adventures = [
|
||||
@ -571,7 +569,7 @@ export function transformToProduct(adventure: any): Product {
|
||||
width: adventure.primaryImage.width,
|
||||
height: adventure.primaryImage.height
|
||||
},
|
||||
images: [], // Only one image is provided, so not including that in the images array
|
||||
images: [],
|
||||
seo: {
|
||||
title: adventure.title,
|
||||
description: adventure.description.html
|
||||
@ -581,16 +579,107 @@ export function transformToProduct(adventure: any): Product {
|
||||
updatedAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
product.variants.push(variant);
|
||||
product.images.push(product.featuredImage);
|
||||
|
||||
return product;
|
||||
}
|
||||
|
||||
export const adventureProducts = adventures.map(transformToProduct);
|
||||
export const adventureProducts: Product[] = adventures.map(transformToProduct) as Product[];
|
||||
|
||||
export const adventureProductNodes = adventureProducts.map((product) => ({
|
||||
node: product
|
||||
}));
|
||||
|
||||
// console.log(adventureProductNodes);
|
||||
export function getProductNodesByKeyword(keyword: string | undefined): { node: Product }[] {
|
||||
return getProductsByKeyword(keyword).map((product) => ({
|
||||
node: product
|
||||
}));
|
||||
}
|
||||
|
||||
// const product = transformToProduct(adventure);
|
||||
// console.log(product);
|
||||
export function getProductByHandle(handle: string): Product | undefined {
|
||||
const res = adventureProducts.find((product) => product.handle === handle);
|
||||
return res;
|
||||
}
|
||||
|
||||
export function getProductsByKeyword(keyword: string | undefined): Product[] {
|
||||
//if keyword is empty, return all products
|
||||
if (!keyword || keyword === undefined) {
|
||||
return adventureProducts;
|
||||
}
|
||||
|
||||
keyword = keyword || '';
|
||||
|
||||
if (keyword.includes('all')) {
|
||||
return adventureProducts;
|
||||
}
|
||||
|
||||
if (keyword.includes('hidden-homepage-featured-items')) {
|
||||
// @ts-ignore
|
||||
return [
|
||||
adventureProducts[0] as Product,
|
||||
adventureProducts[1] as Product,
|
||||
adventureProducts[2] as Product
|
||||
];
|
||||
}
|
||||
|
||||
if (keyword.includes('hidden-homepage-carousel')) {
|
||||
// @ts-ignore
|
||||
return [
|
||||
adventureProducts[4] as Product,
|
||||
adventureProducts[5] as Product,
|
||||
adventureProducts[6] as Product,
|
||||
adventureProducts[7] as Product,
|
||||
adventureProducts[8] as Product
|
||||
];
|
||||
}
|
||||
|
||||
//if keyword contains a dash, split it into an array of words, and use the first word
|
||||
if (keyword.includes('-')) {
|
||||
// @ts-ignore
|
||||
keyword = keyword.split('-')[0];
|
||||
}
|
||||
|
||||
keyword = keyword || '';
|
||||
keyword = keyword.toLowerCase();
|
||||
|
||||
if (keyword.includes('winter')) {
|
||||
return adventureProducts.filter(
|
||||
(product) =>
|
||||
product.title.toLowerCase().includes('ski') ||
|
||||
product.title.toLowerCase().includes('winter')
|
||||
);
|
||||
}
|
||||
|
||||
if (keyword.includes('summer')) {
|
||||
return adventureProducts.filter(
|
||||
(product) =>
|
||||
product.title.toLowerCase().includes('surf') ||
|
||||
product.title.toLowerCase().includes('climbing') ||
|
||||
product.title.toLowerCase().includes('summer') ||
|
||||
product.title.toLowerCase().includes('hiking') ||
|
||||
product.title.toLowerCase().includes('camping') ||
|
||||
product.title.toLowerCase().includes('rafting') ||
|
||||
product.title.toLowerCase().includes('tasting') ||
|
||||
product.title.toLowerCase().includes('cycling') ||
|
||||
product.title.toLowerCase().includes('gastro') ||
|
||||
product.title.toLowerCase().includes('backpacking')
|
||||
);
|
||||
}
|
||||
|
||||
if (keyword.includes('europe')) {
|
||||
return adventureProducts.filter(
|
||||
(product) =>
|
||||
product.title.toLowerCase().includes('tuscany') ||
|
||||
product.title.toLowerCase().includes('marais') ||
|
||||
product.title.toLowerCase().includes('basel') ||
|
||||
product.title.toLowerCase().includes('mont')
|
||||
);
|
||||
}
|
||||
|
||||
return adventureProducts.filter(
|
||||
(product) =>
|
||||
product.title.toLowerCase().includes(<string>keyword) ||
|
||||
product.description.toLowerCase().includes(<string>keyword)
|
||||
);
|
||||
}
|
||||
|
@ -7,8 +7,11 @@ import {
|
||||
mockShopifyProduct,
|
||||
mockCartItem,
|
||||
mockShopifyCart,
|
||||
mockShopifyCollection,
|
||||
mockPage
|
||||
winterCollection,
|
||||
summerCollection,
|
||||
europeCollection,
|
||||
mockPage,
|
||||
collections
|
||||
} from './mock';
|
||||
import {
|
||||
Cart,
|
||||
@ -26,7 +29,7 @@ import {
|
||||
import { getCollectionsQuery } from './queries/collection';
|
||||
import { TAGS } from '../constants';
|
||||
import { shopifyFetch } from './index_old';
|
||||
import { adventureProductNodes } from './adventures';
|
||||
import { adventureProductNodes, getProductByHandle, getProductNodesByKeyword } from './adventures';
|
||||
|
||||
const HIDDEN_PRODUCT_TAG = 'hidden';
|
||||
|
||||
@ -39,8 +42,13 @@ const mockFetchResponse = (data) => ({
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
const removeEdgesAndNodes = (connection) =>
|
||||
connection?.edges ? connection?.edges.map((edge) => edge.node) : [];
|
||||
const removeEdgesAndNodes = (connection) => {
|
||||
if (!connection?.edges) {
|
||||
return connection;
|
||||
}
|
||||
|
||||
return connection?.edges ? connection?.edges.map((edge: any) => edge.node) : [];
|
||||
};
|
||||
|
||||
export const createCart = async (): Promise<Cart> => {
|
||||
const res = mockFetchResponse({
|
||||
@ -93,7 +101,7 @@ export const getCart = async (cartId: string): Promise<Cart | undefined> => {
|
||||
|
||||
export const getCollection = async (handle: string): Promise<Collection | undefined> => {
|
||||
const res = mockFetchResponse({
|
||||
collection: mockShopifyCollection
|
||||
collection: collections.find((collection) => collection.handle === handle)
|
||||
});
|
||||
return reshapeCollection(res.body.data.collection);
|
||||
};
|
||||
@ -110,8 +118,7 @@ export const getCollectionProducts = async ({
|
||||
const res = mockFetchResponse({
|
||||
collection: {
|
||||
products: {
|
||||
edges: adventureProductNodes
|
||||
// edges: [{ node: mockShopifyProduct }]
|
||||
edges: getProductNodesByKeyword(collection)
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -125,7 +132,7 @@ export async function getCollections(): Promise<Collection[]> {
|
||||
// });
|
||||
const res = mockFetchResponse({
|
||||
collections: {
|
||||
edges: [{ node: mockShopifyCollection }]
|
||||
edges: [{ node: winterCollection }, { node: summerCollection }, { node: europeCollection }]
|
||||
}
|
||||
});
|
||||
const shopifyCollections = removeEdgesAndNodes(res.body?.data?.collections);
|
||||
@ -138,7 +145,7 @@ export async function getCollections(): Promise<Collection[]> {
|
||||
title: 'All',
|
||||
description: 'All products'
|
||||
},
|
||||
path: '/search',
|
||||
path: '/search/',
|
||||
updatedAt: new Date().toISOString()
|
||||
},
|
||||
// Filter out the `hidden` collections.
|
||||
@ -156,8 +163,20 @@ export const getMenu = async (handle: string): Promise<Menu[]> => {
|
||||
menu: {
|
||||
items: [
|
||||
{
|
||||
title: 'Sample Menu',
|
||||
path: 'https://example.com/sample-menu'
|
||||
title: 'All',
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
title: 'Summer',
|
||||
path: '/search/summer-collection'
|
||||
},
|
||||
{
|
||||
title: 'Winter',
|
||||
path: '/search/winter-collection'
|
||||
},
|
||||
{
|
||||
title: 'Europe',
|
||||
path: '/search/europe-collection'
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -183,14 +202,19 @@ export const getPages = async (): Promise<Page[]> => {
|
||||
|
||||
export const getProduct = async (handle: string): Promise<Product | undefined> => {
|
||||
const res = mockFetchResponse({
|
||||
product: mockShopifyProduct
|
||||
product: getProductByHandle(handle)
|
||||
});
|
||||
return reshapeProduct(res.body.data.product, false);
|
||||
};
|
||||
|
||||
export const getProductRecommendations = async (productId: string): Promise<Product[]> => {
|
||||
const res = mockFetchResponse({
|
||||
productRecommendations: [mockShopifyProduct]
|
||||
productRecommendations: [
|
||||
getProductByHandle('climbing-new-zealand'),
|
||||
getProductByHandle('ski-touring-mont-blanc'),
|
||||
getProductByHandle('downhill-skiing-wyoming'),
|
||||
getProductByHandle('cycling-tuscany')
|
||||
]
|
||||
});
|
||||
return reshapeProducts(res.body.data.productRecommendations);
|
||||
};
|
||||
@ -206,7 +230,7 @@ export const getProducts = async ({
|
||||
}): Promise<Product[]> => {
|
||||
const res = mockFetchResponse({
|
||||
products: {
|
||||
edges: [{ node: mockShopifyProduct }]
|
||||
edges: getProductNodesByKeyword(query)
|
||||
}
|
||||
});
|
||||
return reshapeProducts(removeEdgesAndNodes(res.body.data.products));
|
||||
@ -254,11 +278,6 @@ const reshapeCollections = (collections: ShopifyCollection[]) => {
|
||||
};
|
||||
|
||||
const reshapeImages = (images: Connection<Image>, productTitle: string) => {
|
||||
try {
|
||||
console.log('images', images);
|
||||
} catch (e) {
|
||||
// console.log('error', e);
|
||||
}
|
||||
const flattened = removeEdgesAndNodes(images);
|
||||
|
||||
// @ts-ignore
|
||||
@ -272,7 +291,8 @@ const reshapeImages = (images: Connection<Image>, productTitle: string) => {
|
||||
};
|
||||
|
||||
const reshapeProduct = (product: ShopifyProduct, filterHiddenProducts: boolean = true) => {
|
||||
if (!product || (filterHiddenProducts && product.tags.includes(HIDDEN_PRODUCT_TAG))) {
|
||||
// if (!product || (filterHiddenProducts && product.tags.includes(HIDDEN_PRODUCT_TAG))) {
|
||||
if (!product) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
// Mock data for the defined types
|
||||
|
||||
const { adventureProducts } = require('./adventures');
|
||||
const mockMoney = {
|
||||
export const mockMoney = {
|
||||
amount: '100.00',
|
||||
currencyCode: 'USD'
|
||||
};
|
||||
|
||||
const mockImage = {
|
||||
export const mockImage = {
|
||||
url: 'https://ssc-sparkle.vercel.app/_next/image?url=https%3A%2F%2Fpublish-p64257-e147834-cmstg.adobeaemcloud.com%2Fcontent%2Fdam%2Faem-demo-assets%2Fen%2Fadventures%2Fcycling-tuscany%2FAdobeStock_261097343.jpeg&w=2048&q=75',
|
||||
altText: 'Sample Image',
|
||||
width: 500,
|
||||
height: 500
|
||||
};
|
||||
|
||||
const mockProductOption = {
|
||||
export const mockProductOption = {
|
||||
id: 'option1',
|
||||
name: 'Color',
|
||||
values: ['Red', 'Blue', 'Green']
|
||||
};
|
||||
|
||||
const mockProductVariant = {
|
||||
export const mockProductVariant = {
|
||||
id: 'variant1',
|
||||
title: 'Red Variant',
|
||||
availableForSale: true,
|
||||
@ -32,7 +32,7 @@ const mockProductVariant = {
|
||||
price: mockMoney
|
||||
};
|
||||
|
||||
const mockShopifyProduct = adventureProducts[0];
|
||||
export const mockShopifyProduct = adventureProducts[0];
|
||||
|
||||
// const mockShopifyProductOld = {
|
||||
// id: 'product1',
|
||||
@ -57,7 +57,7 @@ const mockShopifyProduct = adventureProducts[0];
|
||||
// updatedAt: '2023-08-10T00:00:00Z'
|
||||
// };
|
||||
|
||||
const mockCartItem = {
|
||||
export const mockCartItem = {
|
||||
id: 'item1',
|
||||
quantity: 1,
|
||||
cost: { totalAmount: mockMoney },
|
||||
@ -74,7 +74,7 @@ const mockCartItem = {
|
||||
}
|
||||
};
|
||||
|
||||
const mockShopifyCart = {
|
||||
export const mockShopifyCart = {
|
||||
id: 'cart1',
|
||||
checkoutUrl: 'https://example.com/checkout',
|
||||
cost: {
|
||||
@ -86,18 +86,40 @@ const mockShopifyCart = {
|
||||
totalQuantity: 1
|
||||
};
|
||||
|
||||
const mockShopifyCollection = {
|
||||
handle: 'sample-collection',
|
||||
title: 'Sample Collection',
|
||||
description: 'This is a sample collection.',
|
||||
export const winterCollection = {
|
||||
handle: 'winter-collection',
|
||||
title: 'Winter',
|
||||
description: 'Adventures for the winter.',
|
||||
seo: {
|
||||
title: 'Sample Collection',
|
||||
description: 'This is a sample collection.'
|
||||
title: 'Winter Collection',
|
||||
description: 'Adventures for the winter.'
|
||||
},
|
||||
updatedAt: '2023-08-10T00:00:00Z'
|
||||
};
|
||||
|
||||
const mockPage = {
|
||||
export const summerCollection = {
|
||||
handle: 'summer-collection',
|
||||
title: 'Summer',
|
||||
description: 'Adventures for the summer.',
|
||||
seo: {
|
||||
title: 'Summer Collection',
|
||||
description: 'Adventures for the summer.'
|
||||
},
|
||||
updatedAt: '2023-08-10T00:00:00Z'
|
||||
};
|
||||
|
||||
export const europeCollection = {
|
||||
handle: 'europe-collection',
|
||||
title: 'Europe',
|
||||
description: 'Adventures in Europe.',
|
||||
seo: {
|
||||
title: 'Europe Collection',
|
||||
description: 'Adventures in Europe.'
|
||||
},
|
||||
updatedAt: '2023-08-10T00:00:00Z'
|
||||
};
|
||||
|
||||
export const mockPage = {
|
||||
id: 'page1',
|
||||
title: 'Sample Page',
|
||||
handle: 'sample-page',
|
||||
@ -113,14 +135,18 @@ const mockPage = {
|
||||
|
||||
// Exporting the mock data
|
||||
|
||||
module.exports = {
|
||||
mockMoney,
|
||||
mockImage,
|
||||
mockProductOption,
|
||||
mockProductVariant,
|
||||
mockShopifyProduct,
|
||||
mockCartItem,
|
||||
mockShopifyCart,
|
||||
mockShopifyCollection,
|
||||
mockPage
|
||||
};
|
||||
export const collections = [winterCollection, summerCollection, europeCollection];
|
||||
//
|
||||
// module.exports = {
|
||||
// mockMoney,
|
||||
// mockImage,
|
||||
// mockProductOption,
|
||||
// mockProductVariant,
|
||||
// mockShopifyProduct,
|
||||
// mockCartItem,
|
||||
// mockShopifyCart,
|
||||
// winterCollection: winterCollection,
|
||||
// summerCollection: summerCollection,
|
||||
// europeCollection: europeCollection,
|
||||
// mockPage
|
||||
// };
|
||||
|
Loading…
x
Reference in New Issue
Block a user