diff --git a/app/page.tsx b/app/page.tsx index aefd19396..047f5d483 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -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' } diff --git a/components/cart/actions.ts b/components/cart/actions.ts index bd22ccc69..0451262dd 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -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 => { - 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 => { diff --git a/components/grid/tile.tsx b/components/grid/tile.tsx index f79a459f4..e0bdb187a 100644 --- a/components/grid/tile.tsx +++ b/components/grid/tile.tsx @@ -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 -
- - -
- Deploy -
-
+ {/*
*/} + {/* */} + {/* */} + {/*
*/} + {/* Deploy*/} + {/* */} + {/*
*/}
@@ -57,12 +60,12 @@ export default async function Footer() {


Designed in California

-

- Crafted by{' '} - - ▲ Vercel - -

+ {/*

*/} + {/* Crafted by{' '}*/} + {/* */} + {/* ▲ Vercel*/} + {/* */} + {/*

*/}
diff --git a/components/product/gallery.tsx b/components/product/gallery.tsx index 0b03557a5..b1a2433ed 100644 --- a/components/product/gallery.tsx +++ b/components/product/gallery.tsx @@ -31,7 +31,7 @@ export function Gallery({ images }: { images: { src: string; altText: string }[]
{images[imageIndex] && ( {images[imageIndex]?.altText ({ 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(keyword) || + product.description.toLowerCase().includes(keyword) + ); +} diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index 9d55fa91f..0a6eb97b7 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -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 => { const res = mockFetchResponse({ @@ -93,7 +101,7 @@ export const getCart = async (cartId: string): Promise => { export const getCollection = async (handle: string): Promise => { 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 { // }); 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 { 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: { 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 => { export const getProduct = async (handle: string): Promise => { const res = mockFetchResponse({ - product: mockShopifyProduct + product: getProductByHandle(handle) }); return reshapeProduct(res.body.data.product, false); }; export const getProductRecommendations = async (productId: string): Promise => { 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 => { 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, 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, 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; } diff --git a/lib/shopify/mock.js b/lib/shopify/mock.js index c00f0e90b..54f7ab8f5 100644 --- a/lib/shopify/mock.js +++ b/lib/shopify/mock.js @@ -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 +// };