From 462cccd1fe02a75d42a4c3999a46e3c1e271cdd0 Mon Sep 17 00:00:00 2001 From: Robert Field Date: Mon, 30 Oct 2023 13:10:14 +0100 Subject: [PATCH] feat: d2c next app dir (#102) * feat: added SITE_NAME environment var * feat: removed icons * feat: updated app directory new pages and components * feat: latest changes for d2c app directory * chore: changeset * refactor: remove console log * fix: removed extra package.json content * feat: latest examples d2c starter kit app directory * feat: latest lock file * test: cart tests no longer had these files - expected * fix: replaced missing if for search modal * test: resolved tests after changes * feat: latest examples * chore: generated latest examples * feat: package fixes * feat: copied over fix for cookie issue * feat: instantsearch fix * feat: latest examples * feat: bumped to next 14 * feat: bumped react types version * feat: latest examples * feat: use workspace * chore: changeset --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/fluffy-donuts-jump.md | 6 + .changeset/ninety-seas-joke.md | 6 + examples/algolia/next.config.js | 13 +- examples/algolia/package.json | 46 +- examples/algolia/public/150-placeholder.png | Bin 1088 -> 0 bytes examples/algolia/public/icons/empty.svg | 113 ----- examples/algolia/public/icons/ep-icon.svg | 4 - examples/algolia/public/icons/ep-logo.svg | 13 - examples/algolia/public/icons/github.svg | 1 - examples/algolia/src/app/about/page.tsx | 5 + examples/algolia/src/app/cart/page.tsx | 42 ++ .../configuration-error/page.tsx} | 60 ++- examples/algolia/src/app/error.tsx | 31 ++ examples/algolia/src/app/faq/page.tsx | 5 + examples/algolia/src/app/layout.tsx | 59 +++ .../algolia/src/app/not-found.tsx | 3 +- examples/algolia/src/app/page.tsx | 38 ++ .../src/app/products/[productId]/page.tsx | 48 ++ .../products/[productId]/product-display.tsx | 39 ++ examples/algolia/src/app/providers.tsx | 17 + .../src/app/search/[[...node]]/layout.tsx | 11 + .../src/app/search/[[...node]]/page.tsx | 13 + examples/algolia/src/app/search/search.tsx | 77 +++ examples/algolia/src/app/shipping/page.tsx | 5 + examples/algolia/src/app/terms/page.tsx | 5 + .../src/components/{search => }/NoImage.tsx | 4 +- examples/algolia/src/components/Spinner.tsx | 4 +- .../algolia/src/components/breadcrumb.tsx | 30 +- .../src/components/cart/CartItemList.tsx | 38 +- .../src/components/cart/CartOrderSummary.tsx | 4 +- .../featured-products/FeaturedProducts.tsx | 125 ++--- .../fetchFeaturedProducts.ts | 12 +- .../algolia/src/components/footer/Footer.tsx | 62 +-- .../algolia/src/components/header/Header.tsx | 32 +- .../src/components/header/cart/CartMenu.tsx | 5 +- .../components/header/cart/ModalCartItem.tsx | 36 +- .../header/navigation/MobileNavBar.tsx | 55 +-- .../header/navigation/MobileNavBarButton.tsx | 33 ++ .../components/header/navigation/NavBar.tsx | 49 +- .../header/navigation/NavBarPopover.tsx | 44 ++ .../header/navigation/NavItemContent.tsx | 35 +- .../components/header/navigation/NavMenu.tsx | 1 + .../algolia/src/components/icons/cart.tsx | 16 + .../algolia/src/components/icons/ep-icon.tsx | 20 + .../algolia/src/components/icons/ep-logo.tsx | 31 ++ .../src/components/icons/github-icon.tsx | 16 + .../src/components/layouts/MainLayout.tsx | 32 -- .../src/components/product-modal/Product.tsx | 2 +- .../src/components/product/CartActions.tsx | 2 +- .../components/product/ProductContainer.tsx | 30 +- .../src/components/product/ProductDetails.tsx | 2 +- .../components/product/ProductExtensions.tsx | 5 +- .../src/components/product/ProductSummary.tsx | 2 +- .../product/bundles/ProductComponent.tsx | 25 +- .../product/carousel/HorizontalCarousel.tsx | 24 +- .../carousel/ProductCarousel.module.css | 1 - .../product/carousel/ProductCarousel.tsx | 2 +- .../carousel/ProductHighlightCarousel.tsx | 11 +- .../product/variations/ProductVariations.tsx | 9 +- .../promotion-banner/PromotionBanner.tsx | 3 +- .../search/CustomHierarchicalMenu.tsx | 153 ------ .../algolia/src/components/search/Hit.tsx | 38 +- .../algolia/src/components/search/Hits.tsx | 4 +- .../src/components/search/MobileFilters.tsx | 50 +- .../src/components/search/NodeMenu.tsx | 77 +++ .../src/components/search/Pagination.tsx | 2 +- .../src/components/search/SearchBox.tsx | 42 -- .../src/components/search/SearchModal.tsx | 38 +- .../src/components/search/SearchPage.tsx | 56 --- .../src/components/search/SearchResults.tsx | 50 +- .../PriceRangeSliderWrapper.tsx | 2 +- .../product-specification/BrandRefinement.tsx | 2 +- .../product-specification/ColorRefinement.tsx | 2 +- .../OnSaleRefinement.tsx | 2 +- .../ProductSpecification.tsx | 4 +- .../algolia/src/components/toast/toaster.tsx | 1 + .../algolia/src/lib/algolia-search-routing.ts | 202 +++++--- .../algolia/src/lib/build-site-navigation.ts | 4 +- .../algolia/src/lib/cart-cookie-client.ts | 17 + .../algolia/src/lib/cart-cookie-server.ts | 18 + examples/algolia/src/lib/cart-cookie.ts | 46 -- .../lib/connect-products-with-main-images.ts | 29 ++ examples/algolia/src/lib/cookie-constants.ts | 3 + .../algolia/src/lib/epcc-implicit-client.ts | 66 +-- .../lib/epcc-server-side-implicit-client.ts | 48 ++ examples/algolia/src/lib/get-main-layout.tsx | 10 - examples/algolia/src/lib/get-store-context.ts | 19 + .../src/lib/middleware/apply-set-cookie.ts | 31 ++ .../lib/middleware/cart-cookie-middleware.ts | 7 +- .../middleware/implicit-auth-middleware.ts | 8 +- examples/algolia/src/lib/product-context.ts | 10 + examples/algolia/src/lib/product-util.ts | 35 +- .../src/lib/providers/store-provider.tsx | 8 +- examples/algolia/src/lib/search-constants.ts | 3 + examples/algolia/src/lib/search-props.tsx | 54 --- examples/algolia/src/lib/sort-by-items.ts | 13 + examples/algolia/src/lib/store-wrapper-ssg.ts | 76 --- examples/algolia/src/lib/store-wrapper-ssr.ts | 66 --- .../src/lib/types/search-query-params.ts | 2 +- .../src/lib/use-next-router-handler.ts | 138 ------ examples/algolia/src/pages/500.tsx | 14 - examples/algolia/src/pages/_app.tsx | 42 -- examples/algolia/src/pages/about.tsx | 8 - examples/algolia/src/pages/cart.tsx | 36 -- examples/algolia/src/pages/faq.tsx | 8 - examples/algolia/src/pages/index.tsx | 68 --- .../src/pages/products/[productId].tsx | 120 ----- .../algolia/src/pages/search/[...node].tsx | 59 --- examples/algolia/src/pages/search/index.tsx | 37 -- examples/algolia/src/pages/shipping.tsx | 8 - examples/algolia/src/pages/terms.tsx | 8 - examples/algolia/src/services/cart.ts | 5 +- examples/algolia/src/services/hierarchy.ts | 22 +- examples/algolia/src/services/products.ts | 21 +- examples/algolia/tailwind.config.ts | 20 + examples/algolia/tsconfig.json | 14 +- examples/basic/.env.example | 3 +- examples/basic/next.config.js | 13 +- examples/basic/package.json | 22 +- examples/basic/public/150-placeholder.png | Bin 1088 -> 0 bytes examples/basic/public/icons/empty.svg | 113 ----- examples/basic/public/icons/ep-icon.svg | 4 - examples/basic/public/icons/ep-logo.svg | 13 - examples/basic/public/icons/github.svg | 1 - examples/basic/src/app/about/page.tsx | 5 + examples/basic/src/app/cart/page.tsx | 42 ++ .../app/checkout/[cartId]/cart-display.tsx | 68 +-- .../basic/src/app/checkout/[cartId]/page.tsx | 28 ++ .../src/app/configuration-error/page.tsx | 60 ++- examples/basic/src/app/error.tsx | 31 ++ examples/basic/src/app/faq/page.tsx | 5 + examples/basic/src/app/layout.tsx | 59 +++ .../404.tsx => basic/src/app/not-found.tsx} | 3 +- examples/basic/src/app/page.tsx | 38 ++ .../src/app/products/[productId]/page.tsx | 48 ++ .../products/[productId]/product-display.tsx | 39 ++ examples/basic/src/app/providers.tsx | 17 + examples/basic/src/app/shipping/page.tsx | 5 + examples/basic/src/app/terms/page.tsx | 5 + examples/basic/src/components/NoImage.tsx | 12 + examples/basic/src/components/Spinner.tsx | 4 +- .../src/components/cart/CartItemList.tsx | 38 +- .../src/components/cart/CartOrderSummary.tsx | 4 +- .../src/components/checkout/OrderComplete.tsx | 25 +- .../src/components/checkout/OrderSummary.tsx | 14 +- .../form-schema/checkout-form-schema.ts | 44 +- .../checkout/payments/CheckoutForm.tsx | 8 +- .../featured-products/FeaturedProducts.tsx | 125 ++--- .../fetchFeaturedProducts.ts | 12 +- .../basic/src/components/footer/Footer.tsx | 62 +-- .../basic/src/components/header/Header.tsx | 30 +- .../src/components/header/cart/CartMenu.tsx | 5 +- .../components/header/cart/ModalCartItem.tsx | 36 +- .../header/navigation/MobileNavBar.tsx | 55 +-- .../header/navigation/MobileNavBarButton.tsx | 33 ++ .../components/header/navigation/NavBar.tsx | 49 +- .../header/navigation/NavBarPopover.tsx | 44 ++ .../header/navigation/NavItemContent.tsx | 35 +- .../components/header/navigation/NavMenu.tsx | 1 + examples/basic/src/components/icons/cart.tsx | 16 + .../basic/src/components/icons/ep-icon.tsx | 20 + .../basic/src/components/icons/ep-logo.tsx | 31 ++ .../src/components/icons/github-icon.tsx | 16 + .../src/components/layouts/MainLayout.tsx | 32 -- .../src/components/product/CartActions.tsx | 2 +- .../components/product/ProductContainer.tsx | 30 +- .../src/components/product/ProductDetails.tsx | 2 +- .../components/product/ProductExtensions.tsx | 5 +- .../src/components/product/ProductSummary.tsx | 2 +- .../product/bundles/ProductComponent.tsx | 25 +- .../product/carousel/HorizontalCarousel.tsx | 24 +- .../carousel/ProductCarousel.module.css | 1 - .../product/carousel/ProductCarousel.tsx | 2 +- .../carousel/ProductHighlightCarousel.tsx | 11 +- .../product/variations/ProductVariations.tsx | 9 +- .../promotion-banner/PromotionBanner.tsx | 3 +- .../basic/src/components/toast/toaster.tsx | 1 + .../basic/src/lib/build-site-navigation.ts | 4 +- examples/basic/src/lib/cart-cookie-client.ts | 17 + examples/basic/src/lib/cart-cookie-server.ts | 18 + examples/basic/src/lib/cart-cookie.ts | 46 -- .../lib/connect-products-with-main-images.ts | 29 ++ examples/basic/src/lib/cookie-constants.ts | 3 + .../basic/src/lib/epcc-implicit-client.ts | 66 +-- .../lib/epcc-server-side-implicit-client.ts | 48 ++ examples/basic/src/lib/get-main-layout.tsx | 10 - examples/basic/src/lib/get-store-context.ts | 19 + .../src/lib/middleware/apply-set-cookie.ts | 31 ++ .../lib/middleware/cart-cookie-middleware.ts | 7 +- .../middleware/implicit-auth-middleware.ts | 8 +- examples/basic/src/lib/product-context.ts | 10 + examples/basic/src/lib/product-util.ts | 35 +- .../src/lib/providers/store-provider.tsx | 8 +- examples/basic/src/lib/store-wrapper-ssg.ts | 76 --- examples/basic/src/lib/store-wrapper-ssr.ts | 66 --- examples/basic/src/pages/500.tsx | 14 - examples/basic/src/pages/_app.tsx | 42 -- examples/basic/src/pages/about.tsx | 8 - examples/basic/src/pages/cart.tsx | 36 -- examples/basic/src/pages/faq.tsx | 8 - examples/basic/src/pages/index.tsx | 68 --- .../basic/src/pages/products/[productId].tsx | 120 ----- examples/basic/src/pages/shipping.tsx | 8 - examples/basic/src/pages/terms.tsx | 8 - examples/basic/src/services/cart.ts | 5 +- examples/basic/src/services/checkout.ts | 19 +- examples/basic/src/services/hierarchy.ts | 22 +- examples/basic/src/services/products.ts | 21 +- examples/basic/tailwind.config.ts | 20 + examples/basic/tsconfig.json | 14 +- .../__tests__/application.test.ts | 35 +- .../d2c-schematics/__tests__/cart.test.ts | 5 +- packages/d2c-schematics/__tests__/d2c.test.ts | 16 +- .../d2c-schematics/__tests__/header.test.ts | 2 + .../d2c-schematics/__tests__/home.test.ts | 8 +- .../__tests__/product-details-page.test.ts | 4 +- .../files/public/150-placeholder.png | Bin 1088 -> 0 bytes .../application/files/public/icons/empty.svg | 113 ----- .../files/public/icons/ep-icon.svg | 4 - .../files/public/icons/ep-logo.svg | 13 - .../application/files/public/icons/github.svg | 1 - .../files/src/app/about/page.tsx.template | 5 + .../app/configuration-error/page.tsx.template | 60 ++- .../files/src/app/error.tsx.template | 31 ++ .../files/src/app/faq/page.tsx.template | 5 + .../files/src/app/layout.tsx.template | 59 +++ .../files/src/app/not-found.tsx.template | 3 +- .../files/src/app/providers.tsx.template | 17 + .../files/src/app/shipping/page.tsx.template | 5 + .../files/src/app/terms/page.tsx.template | 5 + .../files/src/components/Spinner.tsx.template | 4 +- .../src/components/icons/ep-icon.tsx.template | 20 + .../src/components/icons/ep-logo.tsx.template | 31 ++ .../components/icons/github-icon.tsx.template | 16 + .../layouts/MainLayout.tsx.template | 32 -- .../src/components/toast/toaster.tsx.template | 1 + .../src/lib/build-site-navigation.ts.template | 4 +- .../src/lib/cookie-constants.ts.template | 3 + .../src/lib/epcc-implicit-client.ts.template | 66 +-- ...cc-server-side-implicit-client.ts.template | 48 ++ .../src/lib/get-main-layout.tsx.template | 10 - .../src/lib/get-store-context.ts.template | 19 + .../middleware/apply-set-cookie.ts.template | 31 ++ .../cart-cookie-middleware.ts.template | 7 +- .../implicit-auth-middleware.ts.template | 8 +- .../lib/providers/store-provider.tsx.template | 8 +- .../src/lib/store-wrapper-ssg.ts.template | 76 --- .../files/src/pages/500.tsx.template | 14 - .../files/src/pages/_app.tsx.template | 42 -- .../files/src/pages/about.tsx.template | 8 - .../files/src/pages/faq.tsx.template | 8 - .../files/src/pages/shipping.tsx.template | 8 - .../files/src/pages/terms.tsx.template | 8 - .../files/src/services/hierarchy.ts.template | 22 +- .../cart/files/src/app/cart/page.tsx.template | 42 ++ .../components/cart/CartItemList.tsx.template | 38 +- .../cart/CartOrderSummary.tsx.template | 4 +- .../src/components/icons/cart.tsx.template | 16 + .../src/lib/cart-cookie-client.ts.template | 17 + .../src/lib/cart-cookie-server.ts.template | 18 + .../files/src/lib/cart-cookie.ts.template | 46 -- .../src/lib/store-wrapper-ssr.ts.template | 66 --- .../cart/files/src/pages/cart.tsx.template | 36 -- .../cart/files/src/services/cart.ts.template | 5 +- .../[cartId]/cart-display.tsx.template | 68 +-- .../app/checkout/[cartId]/page.tsx.template | 28 ++ .../checkout/OrderComplete.tsx.template | 25 +- .../checkout/OrderSummary.tsx.template | 14 +- .../checkout-form-schema.ts.template | 44 +- .../files/src/services/checkout.ts.template | 19 +- packages/d2c-schematics/d2c/index.ts | 1 - .../payments/CheckoutForm.tsx.template | 8 +- .../FeaturedProducts.tsx.template | 125 ++--- .../fetchFeaturedProducts.ts.template | 12 +- .../src/components/footer/Footer.tsx.template | 62 +-- .../src/components/header/Header.tsx.template | 32 +- .../header/cart/CartMenu.tsx.template | 5 +- .../header/cart/ModalCartItem.tsx.template | 36 +- .../navigation/MobileNavBar.tsx.template | 55 +-- .../MobileNavBarButton.tsx.template | 33 ++ .../header/navigation/NavBar.tsx.template | 49 +- .../navigation/NavBarPopover.tsx.template | 44 ++ .../navigation/NavItemContent.tsx.template | 35 +- .../header/navigation/NavMenu.tsx.template | 1 + .../home/files/src/app/page.tsx.template | 38 ++ .../home/files/src/pages/index.tsx.template | 68 --- .../products/[productId]/page.tsx.template | 48 ++ .../[productId]/product-display.tsx.template | 39 ++ .../src/components}/NoImage.tsx.template | 4 +- .../product/CartActions.tsx.template | 2 +- .../product/ProductContainer.tsx.template | 30 +- .../product/ProductDetails.tsx.template | 2 +- .../product/ProductExtensions.tsx.template | 5 +- .../product/ProductSummary.tsx.template | 2 +- .../bundles/ProductComponent.tsx.template | 25 +- .../carousel/HorizontalCarousel.tsx.template | 24 +- .../ProductCarousel.module.css.template | 1 - .../carousel/ProductCarousel.tsx.template | 2 +- .../ProductHighlightCarousel.tsx.template | 11 +- .../variations/ProductVariations.tsx.template | 9 +- ...nect-products-with-main-images.ts.template | 29 ++ .../files/src/lib/product-context.ts.template | 10 + .../files/src/lib/product-util.ts.template | 35 +- .../pages/products/[productId].tsx.template | 120 ----- .../files/src/services/products.ts.template | 21 +- .../search/[[...node]]/layout.tsx.template | 11 + .../app/search/[[...node]]/page.tsx.template | 13 + .../files/src/app/search/search.tsx.template | 77 +++ .../CustomHierarchicalMenu.tsx.template | 153 ------ .../src/components/search/Hit.tsx.template | 38 +- .../src/components/search/Hits.tsx.template | 4 +- .../search/MobileFilters.tsx.template | 50 +- .../components/search/NodeMenu.tsx.template | 77 +++ .../components/search/Pagination.tsx.template | 2 +- .../components/search/SearchBox.tsx.template | 42 -- .../search/SearchModal.tsx.template | 38 +- .../components/search/SearchPage.tsx.template | 56 --- .../search/SearchResults.tsx.template | 50 +- .../PriceRangeSliderWrapper.tsx.template | 2 +- .../BrandRefinement.tsx.template | 2 +- .../ColorRefinement.tsx.template | 2 +- .../OnSaleRefinement.tsx.template | 2 +- .../ProductSpecification.tsx.template | 4 +- .../lib/algolia-search-routing.ts.template | 202 +++++--- .../src/lib/search-constants.ts.template | 3 + .../files/src/lib/search-props.tsx.template | 54 --- .../files/src/lib/sort-by-items.ts.template | 13 + .../lib/types/search-query-params.ts.template | 2 +- .../lib/use-next-router-handler.ts.template | 138 ------ .../src/pages/search/[...node].tsx.template | 59 --- .../files/src/pages/search/index.tsx.template | 37 -- .../product-list-page-algolia/index.ts | 17 +- .../src/components/breadcrumb.tsx.template | 30 +- .../product-modal/Product.tsx.template | 2 +- .../PromotionBanner.tsx.template | 3 +- .../d2c-schematics/utility/latest-versions.ts | 6 - .../utility/latest-versions/package.json | 27 +- .../files/__dot__env.example.template | 3 +- .../workspace/files/__dot__env.local.template | 3 +- .../workspace/files/__dot__env.test.template | 3 +- .../workspace/files/next.config.js.template | 13 +- .../workspace/files/package.json.template | 10 +- .../files/tailwind.config.ts.template | 20 + .../workspace/files/tsconfig.json.template | 14 +- packages/d2c-schematics/workspace/index.ts | 2 - packages/react-shopper-hooks/package.json | 4 +- pnpm-lock.yaml | 454 +++++++++--------- 347 files changed, 4389 insertions(+), 5539 deletions(-) create mode 100644 .changeset/fluffy-donuts-jump.md create mode 100644 .changeset/ninety-seas-joke.md delete mode 100644 examples/algolia/public/150-placeholder.png delete mode 100644 examples/algolia/public/icons/empty.svg delete mode 100644 examples/algolia/public/icons/ep-icon.svg delete mode 100644 examples/algolia/public/icons/ep-logo.svg delete mode 100644 examples/algolia/public/icons/github.svg create mode 100644 examples/algolia/src/app/about/page.tsx create mode 100644 examples/algolia/src/app/cart/page.tsx rename examples/algolia/src/{pages/configuration-error.tsx => app/configuration-error/page.tsx} (60%) create mode 100644 examples/algolia/src/app/error.tsx create mode 100644 examples/algolia/src/app/faq/page.tsx create mode 100644 examples/algolia/src/app/layout.tsx rename packages/d2c-schematics/application/files/src/pages/404.tsx.template => examples/algolia/src/app/not-found.tsx (90%) create mode 100644 examples/algolia/src/app/page.tsx create mode 100644 examples/algolia/src/app/products/[productId]/page.tsx create mode 100644 examples/algolia/src/app/products/[productId]/product-display.tsx create mode 100644 examples/algolia/src/app/providers.tsx create mode 100644 examples/algolia/src/app/search/[[...node]]/layout.tsx create mode 100644 examples/algolia/src/app/search/[[...node]]/page.tsx create mode 100644 examples/algolia/src/app/search/search.tsx create mode 100644 examples/algolia/src/app/shipping/page.tsx create mode 100644 examples/algolia/src/app/terms/page.tsx rename examples/algolia/src/components/{search => }/NoImage.tsx (58%) create mode 100644 examples/algolia/src/components/header/navigation/MobileNavBarButton.tsx create mode 100644 examples/algolia/src/components/header/navigation/NavBarPopover.tsx create mode 100644 examples/algolia/src/components/icons/cart.tsx create mode 100644 examples/algolia/src/components/icons/ep-icon.tsx create mode 100644 examples/algolia/src/components/icons/ep-logo.tsx create mode 100644 examples/algolia/src/components/icons/github-icon.tsx delete mode 100644 examples/algolia/src/components/layouts/MainLayout.tsx delete mode 100644 examples/algolia/src/components/search/CustomHierarchicalMenu.tsx create mode 100644 examples/algolia/src/components/search/NodeMenu.tsx delete mode 100644 examples/algolia/src/components/search/SearchBox.tsx delete mode 100644 examples/algolia/src/components/search/SearchPage.tsx rename packages/d2c-schematics/product-list-page-algolia/files/src/components/search/product-specification/BrandRefirement.tsx.template => examples/algolia/src/components/search/product-specification/BrandRefinement.tsx (92%) rename packages/d2c-schematics/product-list-page-algolia/files/src/components/search/product-specification/OnSaleRefirement.tsx.template => examples/algolia/src/components/search/product-specification/OnSaleRefinement.tsx (93%) create mode 100644 examples/algolia/src/lib/cart-cookie-client.ts create mode 100644 examples/algolia/src/lib/cart-cookie-server.ts delete mode 100644 examples/algolia/src/lib/cart-cookie.ts create mode 100644 examples/algolia/src/lib/connect-products-with-main-images.ts create mode 100644 examples/algolia/src/lib/cookie-constants.ts create mode 100644 examples/algolia/src/lib/epcc-server-side-implicit-client.ts delete mode 100644 examples/algolia/src/lib/get-main-layout.tsx create mode 100644 examples/algolia/src/lib/get-store-context.ts create mode 100644 examples/algolia/src/lib/middleware/apply-set-cookie.ts create mode 100644 examples/algolia/src/lib/product-context.ts create mode 100644 examples/algolia/src/lib/search-constants.ts delete mode 100644 examples/algolia/src/lib/search-props.tsx create mode 100644 examples/algolia/src/lib/sort-by-items.ts delete mode 100644 examples/algolia/src/lib/store-wrapper-ssg.ts delete mode 100644 examples/algolia/src/lib/store-wrapper-ssr.ts delete mode 100644 examples/algolia/src/lib/use-next-router-handler.ts delete mode 100644 examples/algolia/src/pages/500.tsx delete mode 100644 examples/algolia/src/pages/_app.tsx delete mode 100644 examples/algolia/src/pages/about.tsx delete mode 100644 examples/algolia/src/pages/cart.tsx delete mode 100644 examples/algolia/src/pages/faq.tsx delete mode 100644 examples/algolia/src/pages/index.tsx delete mode 100644 examples/algolia/src/pages/products/[productId].tsx delete mode 100644 examples/algolia/src/pages/search/[...node].tsx delete mode 100644 examples/algolia/src/pages/search/index.tsx delete mode 100644 examples/algolia/src/pages/shipping.tsx delete mode 100644 examples/algolia/src/pages/terms.tsx delete mode 100644 examples/basic/public/150-placeholder.png delete mode 100644 examples/basic/public/icons/empty.svg delete mode 100644 examples/basic/public/icons/ep-icon.svg delete mode 100644 examples/basic/public/icons/ep-logo.svg delete mode 100644 examples/basic/public/icons/github.svg create mode 100644 examples/basic/src/app/about/page.tsx create mode 100644 examples/basic/src/app/cart/page.tsx rename packages/d2c-schematics/checkout/files/src/pages/checkout/[cartId].tsx.template => examples/basic/src/app/checkout/[cartId]/cart-display.tsx (56%) create mode 100644 examples/basic/src/app/checkout/[cartId]/page.tsx rename packages/d2c-schematics/application/files/src/pages/configuration-error.tsx.template => examples/basic/src/app/configuration-error/page.tsx (60%) create mode 100644 examples/basic/src/app/error.tsx create mode 100644 examples/basic/src/app/faq/page.tsx create mode 100644 examples/basic/src/app/layout.tsx rename examples/{algolia/src/pages/404.tsx => basic/src/app/not-found.tsx} (90%) create mode 100644 examples/basic/src/app/page.tsx create mode 100644 examples/basic/src/app/products/[productId]/page.tsx create mode 100644 examples/basic/src/app/products/[productId]/product-display.tsx create mode 100644 examples/basic/src/app/providers.tsx create mode 100644 examples/basic/src/app/shipping/page.tsx create mode 100644 examples/basic/src/app/terms/page.tsx create mode 100644 examples/basic/src/components/NoImage.tsx create mode 100644 examples/basic/src/components/header/navigation/MobileNavBarButton.tsx create mode 100644 examples/basic/src/components/header/navigation/NavBarPopover.tsx create mode 100644 examples/basic/src/components/icons/cart.tsx create mode 100644 examples/basic/src/components/icons/ep-icon.tsx create mode 100644 examples/basic/src/components/icons/ep-logo.tsx create mode 100644 examples/basic/src/components/icons/github-icon.tsx delete mode 100644 examples/basic/src/components/layouts/MainLayout.tsx create mode 100644 examples/basic/src/lib/cart-cookie-client.ts create mode 100644 examples/basic/src/lib/cart-cookie-server.ts delete mode 100644 examples/basic/src/lib/cart-cookie.ts create mode 100644 examples/basic/src/lib/connect-products-with-main-images.ts create mode 100644 examples/basic/src/lib/cookie-constants.ts create mode 100644 examples/basic/src/lib/epcc-server-side-implicit-client.ts delete mode 100644 examples/basic/src/lib/get-main-layout.tsx create mode 100644 examples/basic/src/lib/get-store-context.ts create mode 100644 examples/basic/src/lib/middleware/apply-set-cookie.ts create mode 100644 examples/basic/src/lib/product-context.ts delete mode 100644 examples/basic/src/lib/store-wrapper-ssg.ts delete mode 100644 examples/basic/src/lib/store-wrapper-ssr.ts delete mode 100644 examples/basic/src/pages/500.tsx delete mode 100644 examples/basic/src/pages/_app.tsx delete mode 100644 examples/basic/src/pages/about.tsx delete mode 100644 examples/basic/src/pages/cart.tsx delete mode 100644 examples/basic/src/pages/faq.tsx delete mode 100644 examples/basic/src/pages/index.tsx delete mode 100644 examples/basic/src/pages/products/[productId].tsx delete mode 100644 examples/basic/src/pages/shipping.tsx delete mode 100644 examples/basic/src/pages/terms.tsx delete mode 100644 packages/d2c-schematics/application/files/public/150-placeholder.png delete mode 100644 packages/d2c-schematics/application/files/public/icons/empty.svg delete mode 100644 packages/d2c-schematics/application/files/public/icons/ep-icon.svg delete mode 100644 packages/d2c-schematics/application/files/public/icons/ep-logo.svg delete mode 100644 packages/d2c-schematics/application/files/public/icons/github.svg create mode 100644 packages/d2c-schematics/application/files/src/app/about/page.tsx.template rename examples/basic/src/pages/configuration-error.tsx => packages/d2c-schematics/application/files/src/app/configuration-error/page.tsx.template (60%) create mode 100644 packages/d2c-schematics/application/files/src/app/error.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/app/faq/page.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/app/layout.tsx.template rename examples/basic/src/pages/404.tsx => packages/d2c-schematics/application/files/src/app/not-found.tsx.template (90%) create mode 100644 packages/d2c-schematics/application/files/src/app/providers.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/app/shipping/page.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/app/terms/page.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/components/icons/ep-icon.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/components/icons/ep-logo.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/components/icons/github-icon.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/components/layouts/MainLayout.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/lib/cookie-constants.ts.template create mode 100644 packages/d2c-schematics/application/files/src/lib/epcc-server-side-implicit-client.ts.template delete mode 100644 packages/d2c-schematics/application/files/src/lib/get-main-layout.tsx.template create mode 100644 packages/d2c-schematics/application/files/src/lib/get-store-context.ts.template create mode 100644 packages/d2c-schematics/application/files/src/lib/middleware/apply-set-cookie.ts.template delete mode 100644 packages/d2c-schematics/application/files/src/lib/store-wrapper-ssg.ts.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/500.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/_app.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/about.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/faq.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/shipping.tsx.template delete mode 100644 packages/d2c-schematics/application/files/src/pages/terms.tsx.template create mode 100644 packages/d2c-schematics/cart/files/src/app/cart/page.tsx.template create mode 100644 packages/d2c-schematics/cart/files/src/components/icons/cart.tsx.template create mode 100644 packages/d2c-schematics/cart/files/src/lib/cart-cookie-client.ts.template create mode 100644 packages/d2c-schematics/cart/files/src/lib/cart-cookie-server.ts.template delete mode 100644 packages/d2c-schematics/cart/files/src/lib/cart-cookie.ts.template delete mode 100644 packages/d2c-schematics/cart/files/src/lib/store-wrapper-ssr.ts.template delete mode 100644 packages/d2c-schematics/cart/files/src/pages/cart.tsx.template rename examples/basic/src/pages/checkout/[cartId].tsx => packages/d2c-schematics/checkout/files/src/app/checkout/[cartId]/cart-display.tsx.template (56%) create mode 100644 packages/d2c-schematics/checkout/files/src/app/checkout/[cartId]/page.tsx.template create mode 100644 packages/d2c-schematics/header/files/src/components/header/navigation/MobileNavBarButton.tsx.template create mode 100644 packages/d2c-schematics/header/files/src/components/header/navigation/NavBarPopover.tsx.template create mode 100644 packages/d2c-schematics/home/files/src/app/page.tsx.template delete mode 100644 packages/d2c-schematics/home/files/src/pages/index.tsx.template create mode 100644 packages/d2c-schematics/product-details-page/files/src/app/products/[productId]/page.tsx.template create mode 100644 packages/d2c-schematics/product-details-page/files/src/app/products/[productId]/product-display.tsx.template rename packages/d2c-schematics/{product-list-page-algolia/files/src/components/search => product-details-page/files/src/components}/NoImage.tsx.template (58%) create mode 100644 packages/d2c-schematics/product-details-page/files/src/lib/connect-products-with-main-images.ts.template create mode 100644 packages/d2c-schematics/product-details-page/files/src/lib/product-context.ts.template delete mode 100644 packages/d2c-schematics/product-details-page/files/src/pages/products/[productId].tsx.template create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/app/search/[[...node]]/layout.tsx.template create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/app/search/[[...node]]/page.tsx.template create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/app/search/search.tsx.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/components/search/CustomHierarchicalMenu.tsx.template create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/components/search/NodeMenu.tsx.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/components/search/SearchBox.tsx.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/components/search/SearchPage.tsx.template rename examples/algolia/src/components/search/product-specification/BrandRefirement.tsx => packages/d2c-schematics/product-list-page-algolia/files/src/components/search/product-specification/BrandRefinement.tsx.template (92%) rename examples/algolia/src/components/search/product-specification/OnSaleRefirement.tsx => packages/d2c-schematics/product-list-page-algolia/files/src/components/search/product-specification/OnSaleRefinement.tsx.template (93%) create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/lib/search-constants.ts.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/lib/search-props.tsx.template create mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/lib/sort-by-items.ts.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/lib/use-next-router-handler.ts.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/pages/search/[...node].tsx.template delete mode 100644 packages/d2c-schematics/product-list-page-algolia/files/src/pages/search/index.tsx.template diff --git a/.changeset/fluffy-donuts-jump.md b/.changeset/fluffy-donuts-jump.md new file mode 100644 index 00000000..b1a1aad8 --- /dev/null +++ b/.changeset/fluffy-donuts-jump.md @@ -0,0 +1,6 @@ +--- +"@elasticpath/react-shopper-hooks": patch +"@elasticpath/d2c-schematics": patch +--- + +bumped react types version diff --git a/.changeset/ninety-seas-joke.md b/.changeset/ninety-seas-joke.md new file mode 100644 index 00000000..48364af9 --- /dev/null +++ b/.changeset/ninety-seas-joke.md @@ -0,0 +1,6 @@ +--- +"@elasticpath/d2c-schematics": minor +"composable-cli": patch +--- + +Migrated D2C starter kit to Next.js 13 App directory routing diff --git a/examples/algolia/next.config.js b/examples/algolia/next.config.js index 0ccb3ba7..d825be37 100644 --- a/examples/algolia/next.config.js +++ b/examples/algolia/next.config.js @@ -5,7 +5,13 @@ **/ const nextConfig = { images: { - domains: ["files-eu.epusercontent.com", "files-na.epusercontent.com"], + formats: ["image/avif", "image/webp"], + remotePatterns: [ + { + protocol: "https", + hostname: "**.epusercontent.com", + }, + ], }, i18n: { locales: ["en"], @@ -16,11 +22,6 @@ const nextConfig = { ...config.resolve.fallback, fs: false, }; - config.module.rules.push({ - test: /\.svg$/i, - issuer: /\.[jt]sx?$/, - use: ["@svgr/webpack"], - }); return config; }, diff --git a/examples/algolia/package.json b/examples/algolia/package.json index 0164ac44..37e946ac 100644 --- a/examples/algolia/package.json +++ b/examples/algolia/package.json @@ -21,56 +21,58 @@ }, "dependencies": { "@algolia/react-instantsearch-widget-color-refinement-list": "^1.4.7", - "@elasticpath/react-shopper-hooks": "0.5.1", + "@elasticpath/react-shopper-hooks": "workspace:^0.5.1", + "@elasticpath/shopper-common": "workspace:^0.1.1", "@headlessui/react": "^1.7.17", "@heroicons/react": "^2.0.18", "@moltin/sdk": "^25.0.2", "algoliasearch": "^4.14.2", "clsx": "^1.2.1", - "cookies-next": "^2.1.1", - "dequal": "^2.0.3", + "cookies-next": "^4.0.0", "focus-visible": "^5.2.0", "formik": "^2.2.9", - "next": "^12.2.5", + "instantsearch.js": "4.59.0", + "next": "^14.0.0", "pure-react-carousel": "^1.29.0", "rc-slider": "^10.3.0", "react": "^18.2.0", "react-device-detect": "^2.2.2", "react-dom": "^18.2.0", - "react-instantsearch-hooks-server": "6.38.1", - "react-instantsearch-hooks-web": "6.38.1", + "react-instantsearch": "^7.2.0", + "react-instantsearch-nextjs": "^0.1.2", "react-toastify": "^9.1.3", + "server-only": "^0.0.1", "zod": "^3.22.4", "zod-formik-adapter": "^1.2.0" }, "devDependencies": { "@babel/core": "^7.18.10", - "@next/bundle-analyzer": "13.0.4", - "@playwright/test": "^1.28.1", + "@next/bundle-analyzer": "^14.0.0", + "@next/env": "^14.0.0", "@svgr/webpack": "^6.3.1", - "@testing-library/jest-dom": "^6.1.3", - "@testing-library/react": "^14.0.0", "@types/node": "18.7.3", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.0", - "@types/react-toastify": "^4.1.0", - "@vitest/coverage-istanbul": "^0.34.5", - "autoprefixer": "^10.4.14", + "@types/react": "^18.2.33", + "@types/react-dom": "^18.2.14", "babel-loader": "^8.2.5", "eslint": "^8.49.0", - "eslint-config-next": "^13.5.2", + "eslint-config-next": "^14.0.0", "eslint-config-prettier": "^9.0.0", + "encoding": "^0.1.13", "eslint-plugin-react": "^7.33.2", - "instantsearch.js": "4.56.8", + "vite": "^4.2.1", + "vitest": "^0.34.5", + "@vitest/coverage-istanbul": "^0.34.5", + "@testing-library/jest-dom": "^6.1.3", + "@testing-library/react": "^14.0.0", + "@playwright/test": "^1.28.1", "lint-staged": "^13.0.3", - "postcss": "^8.4.30", "prettier": "^3.0.3", "prettier-eslint": "^15.0.1", "prettier-eslint-cli": "^7.1.0", - "prettier-plugin-tailwindcss": "^0.5.4", - "tailwindcss": "^3.3.3", "typescript": "^5.2.2", - "vite": "^4.2.1", - "vitest": "^0.34.5" + "tailwindcss": "^3.3.3", + "autoprefixer": "^10.4.14", + "postcss": "^8.4.30", + "prettier-plugin-tailwindcss": "^0.5.4" } } \ No newline at end of file diff --git a/examples/algolia/public/150-placeholder.png b/examples/algolia/public/150-placeholder.png deleted file mode 100644 index 61cd0d979eea707b812ee5d8bb902ea6e460d36b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1088 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm2}o{Eezui?frZ`E#WAE}&f6P~{-3-g+8$~y zWz~`BaT4HGo3twN>Hq({IyWRe7f)nL3OJ&$rA(t(?Ce8`)$1Zyt8R*!@RG5t=s?q%ae2-r2SNhv)!sC3sRDE)1=B(S_n-xwx z|7<@$+{;&Oa@5*s=b!T)&M=$ZeKcufL_+Vs?o0kVV)T43@7cTe?9-y#-~Z>!*4~d_ zfBoY&wH5=O!zO3vmd-hwb~mrwZvOG<{r&y?{QO=kS=`k1|MqT)(VKqy>HP1HzwX+< ze|nG@S8LT?x%G3W1aTxv9DC+@*x-=Cou9MS)zzC1K6v&l&20AB=bvA{&i1`5Br$i- z7yH)zU5h-tGG{G&Z1J}2_lp-NO7ALgv-#PbIdm1%rTq2cgKzsPmA*N^B>(8y%T4#G(>IlZ?}@z?YX}n zKUSW8I&}3_6?c%Pe<`!l_Vgch@4uS0_2?f|2ao^& diff --git a/examples/algolia/public/icons/empty.svg b/examples/algolia/public/icons/empty.svg deleted file mode 100644 index 48a29670..00000000 --- a/examples/algolia/public/icons/empty.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/algolia/public/icons/ep-icon.svg b/examples/algolia/public/icons/ep-icon.svg deleted file mode 100644 index 6250de53..00000000 --- a/examples/algolia/public/icons/ep-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/algolia/public/icons/ep-logo.svg b/examples/algolia/public/icons/ep-logo.svg deleted file mode 100644 index c2498f42..00000000 --- a/examples/algolia/public/icons/ep-logo.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/examples/algolia/public/icons/github.svg b/examples/algolia/public/icons/github.svg deleted file mode 100644 index 21a72e8c..00000000 --- a/examples/algolia/public/icons/github.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/algolia/src/app/about/page.tsx b/examples/algolia/src/app/about/page.tsx new file mode 100644 index 00000000..edda2df8 --- /dev/null +++ b/examples/algolia/src/app/about/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../components/shared/blurb"; + +export default function About() { + return ; +} diff --git a/examples/algolia/src/app/cart/page.tsx b/examples/algolia/src/app/cart/page.tsx new file mode 100644 index 00000000..4dc53f4b --- /dev/null +++ b/examples/algolia/src/app/cart/page.tsx @@ -0,0 +1,42 @@ +"use client"; +import Cart from "../../components/cart/Cart"; +import CartIcon from "../../components/icons/cart"; +import { useCart } from "@elasticpath/react-shopper-hooks"; +import { resolveShoppingCartProps } from "../../lib/resolve-shopping-cart-props"; +import Link from "next/link"; + +export default function CartPage() { + const { removeCartItem, state } = useCart(); + const shoppingCartProps = resolveShoppingCartProps(state, removeCartItem); + + return ( +
+ {shoppingCartProps && ( + <> +

Your Shopping Cart

+ + + )} + {(state.kind === "empty-cart-state" || + state.kind === "uninitialised-cart-state" || + state.kind === "loading-cart-state") && ( +
+ +

+ Empty Cart +

+

Your cart is empty

+
+ + Start shopping + +
+
+ )} +
+ ); +} diff --git a/examples/algolia/src/pages/configuration-error.tsx b/examples/algolia/src/app/configuration-error/page.tsx similarity index 60% rename from examples/algolia/src/pages/configuration-error.tsx rename to examples/algolia/src/app/configuration-error/page.tsx index cc321880..5b9a5dba 100644 --- a/examples/algolia/src/pages/configuration-error.tsx +++ b/examples/algolia/src/app/configuration-error/page.tsx @@ -1,22 +1,35 @@ import Link from "next/link"; -import { GetServerSideProps, NextPage } from "next"; +import { Metadata } from "next"; -interface IConfigurationError { - from?: string; - issues?: Record; -} +export const metadata: Metadata = { + title: "Configuration Error", + description: "Configuration error page", +}; + +type Props = { + searchParams: { [key: string]: string | string[] | undefined }; +}; + +export default function ConfigurationErrorPage({ searchParams }: Props) { + const { + "missing-env-variable": missingEnvVariables, + authentication, + from, + } = searchParams; + + const issues: { [key: string]: string | string[] } = { + ...(missingEnvVariables && { missingEnvVariables }), + ...(authentication && { authentication }), + }; + const fromProcessed = Array.isArray(from) ? from[0] : from; -export const ConfigurationError: NextPage = ({ - issues, - from, -}: IConfigurationError) => { return (
There is a problem with the stores setup Refresh @@ -38,9 +51,9 @@ export const ConfigurationError: NextPage = ({
    {(Array.isArray(issue) ? issue : [issue]).map( - (messsage) => ( -
  • - {decodeURIComponent(messsage)} + (message) => ( +
  • + {decodeURIComponent(message)}
  • ), )} @@ -53,23 +66,4 @@ export const ConfigurationError: NextPage = ({
); -}; - -export default ConfigurationError; - -export const getServerSideProps: GetServerSideProps = async ({ query }) => { - const { - "missing-env-variable": missingEnvVariables, - authentication, - from, - } = query; - return { - props: { - issues: { - ...(missingEnvVariables && { missingEnvVariables }), - ...(authentication && { authentication }), - }, - from: Array.isArray(from) ? from[0] : from, - }, - }; -}; +} diff --git a/examples/algolia/src/app/error.tsx b/examples/algolia/src/app/error.tsx new file mode 100644 index 00000000..f4724026 --- /dev/null +++ b/examples/algolia/src/app/error.tsx @@ -0,0 +1,31 @@ +"use client"; +import Link from "next/link"; + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ( + + +
+ + {error.digest} - Internal server error. + + + Back to home + + +
+ + + ); +} diff --git a/examples/algolia/src/app/faq/page.tsx b/examples/algolia/src/app/faq/page.tsx new file mode 100644 index 00000000..7aac9fba --- /dev/null +++ b/examples/algolia/src/app/faq/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../components/shared/blurb"; + +export default function FAQ() { + return ; +} diff --git a/examples/algolia/src/app/layout.tsx b/examples/algolia/src/app/layout.tsx new file mode 100644 index 00000000..b4b06802 --- /dev/null +++ b/examples/algolia/src/app/layout.tsx @@ -0,0 +1,59 @@ +import { Inter } from "next/font/google"; +import { ReactNode, Suspense } from "react"; +import "../styles/globals.css"; +import Header from "../components/header/Header"; +import { getStoreContext } from "../lib/get-store-context"; +import { getServerSideImplicitClient } from "../lib/epcc-server-side-implicit-client"; +import { Providers } from "./providers"; +import { Toaster } from "../components/toast/toaster"; +import Footer from "../components/footer/Footer"; + +const { SITE_NAME } = process.env; +const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + : "http://localhost:3000"; + +export const metadata = { + metadataBase: new URL(baseUrl), + title: { + default: SITE_NAME!, + template: `%s | ${SITE_NAME}`, + }, + robots: { + follow: true, + index: true, + }, +}; + +const inter = Inter({ + subsets: ["latin"], + display: "swap", + variable: "--font-inter", +}); + +export default async function RootLayout({ + children, +}: { + children: ReactNode; +}) { + const client = getServerSideImplicitClient(); + const storeContext = await getStoreContext(client); + + return ( + + + {/* headless ui needs this div - https://github.com/tailwindlabs/headlessui/issues/2752#issuecomment-1745272229 */} +
+ +
+ + +
{children}
+
+
+ +
+ + + ); +} diff --git a/packages/d2c-schematics/application/files/src/pages/404.tsx.template b/examples/algolia/src/app/not-found.tsx similarity index 90% rename from packages/d2c-schematics/application/files/src/pages/404.tsx.template rename to examples/algolia/src/app/not-found.tsx index 84e2e0e5..d97d88f4 100644 --- a/packages/d2c-schematics/application/files/src/pages/404.tsx.template +++ b/examples/algolia/src/app/not-found.tsx @@ -1,6 +1,5 @@ import Link from "next/link"; - -export default function Custom404() { +export default function NotFound() { return (
diff --git a/examples/algolia/src/app/page.tsx b/examples/algolia/src/app/page.tsx new file mode 100644 index 00000000..dfd06746 --- /dev/null +++ b/examples/algolia/src/app/page.tsx @@ -0,0 +1,38 @@ +import PromotionBanner from "../components/promotion-banner/PromotionBanner"; +import FeaturedProducts from "../components/featured-products/FeaturedProducts"; +import { Suspense } from "react"; + +export default async function Home() { + const promotion = { + title: "Your Elastic Path storefront", + description: + "This marks the beginning, embark on the journey of crafting something truly extraordinary, uniquely yours.", + }; + + return ( +
+ +
+
+
+ + + +
+
+
+
+ ); +} diff --git a/examples/algolia/src/app/products/[productId]/page.tsx b/examples/algolia/src/app/products/[productId]/page.tsx new file mode 100644 index 00000000..f0a54aed --- /dev/null +++ b/examples/algolia/src/app/products/[productId]/page.tsx @@ -0,0 +1,48 @@ +import { Metadata } from "next"; +import { ProductDisplay } from "./product-display"; +import { getServerSideImplicitClient } from "../../../lib/epcc-server-side-implicit-client"; +import { getProductById } from "../../../services/products"; +import { notFound } from "next/navigation"; +import { parseProductResponse } from "@elasticpath/shopper-common"; + +export const dynamic = "force-dynamic"; + +type Props = { + params: { productId: string }; +}; + +export async function generateMetadata({ + params: { productId }, +}: Props): Promise { + const client = getServerSideImplicitClient(); + const product = await getProductById(productId, client); + + if (!product) { + notFound(); + } + + return { + title: product.data.attributes.name, + description: product.data.attributes.description, + }; +} + +export default async function ProductPage({ params }: Props) { + const client = getServerSideImplicitClient(); + const product = await getProductById(params.productId, client); + + if (!product) { + notFound(); + } + + const shopperProduct = await parseProductResponse(product, client); + + return ( +
+ +
+ ); +} diff --git a/examples/algolia/src/app/products/[productId]/product-display.tsx b/examples/algolia/src/app/products/[productId]/product-display.tsx new file mode 100644 index 00000000..2664951b --- /dev/null +++ b/examples/algolia/src/app/products/[productId]/product-display.tsx @@ -0,0 +1,39 @@ +"use client"; +import React, { ReactElement, useState } from "react"; +import { ShopperProduct } from "@elasticpath/react-shopper-hooks"; +import { VariationProductDetail } from "../../../components/product/variations/VariationProduct"; +import BundleProductDetail from "../../../components/product/bundles/BundleProduct"; +import { ProductContext } from "../../../lib/product-context"; +import SimpleProductDetail from "../../../components/product/SimpleProduct"; + +export function ProductDisplay({ + product, +}: { + product: ShopperProduct; +}): ReactElement { + const [isChangingSku, setIsChangingSku] = useState(false); + + return ( + + {resolveProductDetailComponent(product)} + + ); +} + +function resolveProductDetailComponent(product: ShopperProduct): JSX.Element { + switch (product.kind) { + case "base-product": + return ; + case "child-product": + return ; + case "simple-product": + return ; + case "bundle-product": + return ; + } +} diff --git a/examples/algolia/src/app/providers.tsx b/examples/algolia/src/app/providers.tsx new file mode 100644 index 00000000..5bcdc503 --- /dev/null +++ b/examples/algolia/src/app/providers.tsx @@ -0,0 +1,17 @@ +"use client"; + +import StoreNextJSProvider from "../lib/providers/store-provider"; +import { ReactNode } from "react"; +import { StoreContext } from "@elasticpath/react-shopper-hooks"; + +export function Providers({ + children, + store, +}: { + children: ReactNode; + store: StoreContext; +}) { + return ( + {children} + ); +} diff --git a/examples/algolia/src/app/search/[[...node]]/layout.tsx b/examples/algolia/src/app/search/[[...node]]/layout.tsx new file mode 100644 index 00000000..9e1fb2bd --- /dev/null +++ b/examples/algolia/src/app/search/[[...node]]/layout.tsx @@ -0,0 +1,11 @@ +import { ReactNode } from "react"; +import Breadcrumb from "../../../components/breadcrumb"; + +export default function SearchLayout({ children }: { children: ReactNode }) { + return ( +
+ + {children} +
+ ); +} diff --git a/examples/algolia/src/app/search/[[...node]]/page.tsx b/examples/algolia/src/app/search/[[...node]]/page.tsx new file mode 100644 index 00000000..a3450b11 --- /dev/null +++ b/examples/algolia/src/app/search/[[...node]]/page.tsx @@ -0,0 +1,13 @@ +import { Search } from "../search"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Search", + description: "Search for products", +}; + +export const dynamic = "force-dynamic"; + +export default function SearchPage() { + return ; +} diff --git a/examples/algolia/src/app/search/search.tsx b/examples/algolia/src/app/search/search.tsx new file mode 100644 index 00000000..c0f077f0 --- /dev/null +++ b/examples/algolia/src/app/search/search.tsx @@ -0,0 +1,77 @@ +"use client"; +import { searchClient } from "../../lib/search-client"; +import { InstantSearchNext } from "react-instantsearch-nextjs"; +import { algoliaEnvData } from "../../lib/resolve-algolia-env"; +import { resolveAlgoliaRouting } from "../../lib/algolia-search-routing"; +import SearchResults from "../../components/search/SearchResults"; +import React from "react"; +import { buildBreadcrumbLookup } from "../../lib/build-breadcrumb-lookup"; +import { useStore } from "@elasticpath/react-shopper-hooks"; +import { + HierarchicalMenuProps, + PaginationProps, + RangeInputProps, + RefinementListProps, + SearchBoxProps, + SortByProps, + useHierarchicalMenu, + usePagination, + useRange, + useRefinementList, + useSearchBox, + useSortBy, +} from "react-instantsearch"; +import { sortByItems } from "../../lib/sort-by-items"; +import { hierarchicalAttributes } from "../../lib/hierarchical-attributes"; + +export function Search() { + const { nav } = useStore(); + const lookup = buildBreadcrumbLookup(nav ?? []); + + return ( + + {/* Virtual widgets are here as a workaround for this issue https://github.com/algolia/instantsearch/issues/5890 */} + + + + + + + + + ); +} + +function VirtualHierarchicalMenu(props: HierarchicalMenuProps) { + useHierarchicalMenu(props); + return null; +} +function VirtualSearchBox(props: SearchBoxProps) { + useSearchBox(props); + return null; +} +function VirtualPagination(props: PaginationProps) { + usePagination(props); + return null; +} +function VirtualSortBy(props: SortByProps) { + useSortBy(props); + return null; +} + +function VirtualRangeInput(props: RangeInputProps) { + useRange(props); + return null; +} + +function VirtualRefinementList(props: RefinementListProps) { + useRefinementList(props); + return null; +} diff --git a/examples/algolia/src/app/shipping/page.tsx b/examples/algolia/src/app/shipping/page.tsx new file mode 100644 index 00000000..7be31b80 --- /dev/null +++ b/examples/algolia/src/app/shipping/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../components/shared/blurb"; + +export default function Shipping() { + return ; +} diff --git a/examples/algolia/src/app/terms/page.tsx b/examples/algolia/src/app/terms/page.tsx new file mode 100644 index 00000000..8efeb5e7 --- /dev/null +++ b/examples/algolia/src/app/terms/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../components/shared/blurb"; + +export default function Terms() { + return ; +} diff --git a/examples/algolia/src/components/search/NoImage.tsx b/examples/algolia/src/components/NoImage.tsx similarity index 58% rename from examples/algolia/src/components/search/NoImage.tsx rename to examples/algolia/src/components/NoImage.tsx index 8b90b5f8..bf84f253 100644 --- a/examples/algolia/src/components/search/NoImage.tsx +++ b/examples/algolia/src/components/NoImage.tsx @@ -3,8 +3,8 @@ import { EyeSlashIcon } from "@heroicons/react/24/solid"; export const NoImage = (): JSX.Element => { return ( -
- +
+
); }; diff --git a/examples/algolia/src/components/Spinner.tsx b/examples/algolia/src/components/Spinner.tsx index 916be6ba..9bd90a3e 100644 --- a/examples/algolia/src/components/Spinner.tsx +++ b/examples/algolia/src/components/Spinner.tsx @@ -10,9 +10,7 @@ const Spinner = (props: IProps) => { aria-hidden="true" className={`${props.absolute ? "absolute right-0 top-0" : "relative"} ${ props.width - } ${ - props.height - } animate-spin fill-brand-primary text-gray-200 dark:text-gray-600`} + } ${props.height} animate-spin fill-brand-secondary text-brand-primary`} viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg" diff --git a/examples/algolia/src/components/breadcrumb.tsx b/examples/algolia/src/components/breadcrumb.tsx index 91da88f2..950c0130 100644 --- a/examples/algolia/src/components/breadcrumb.tsx +++ b/examples/algolia/src/components/breadcrumb.tsx @@ -1,23 +1,31 @@ -import { BreadcrumbEntry } from "../lib/create-breadcrumb"; +"use client"; +import { createBreadcrumb } from "../lib/create-breadcrumb"; import Link from "next/link"; +import { useStore } from "@elasticpath/react-shopper-hooks"; +import { buildBreadcrumbLookup } from "../lib/build-breadcrumb-lookup"; +import { usePathname } from "next/navigation"; -interface IBreadcrumb { - entries: BreadcrumbEntry[]; -} +export default function Breadcrumb(): JSX.Element { + const { nav } = useStore(); + const pathname = usePathname(); + const lookup = buildBreadcrumbLookup(nav ?? []); + const nodes = pathname.replace("/search/", "")?.split("/"); + const crumbs = createBreadcrumb(nodes, lookup); -export default function Breadcrumb({ entries }: IBreadcrumb): JSX.Element { return (
    - {entries.length > 1 && - entries.map((entry, index, array) => ( + {crumbs.length > 1 && + crumbs.map((entry, index, array) => (
  1. {array.length === index + 1 ? ( {entry.label} ) : ( - - - {entry.label} - + + {entry.label} )} {array.length !== index + 1 && /} diff --git a/examples/algolia/src/components/cart/CartItemList.tsx b/examples/algolia/src/components/cart/CartItemList.tsx index 99fb1052..71c8c0dc 100644 --- a/examples/algolia/src/components/cart/CartItemList.tsx +++ b/examples/algolia/src/components/cart/CartItemList.tsx @@ -19,22 +19,26 @@ export function CartItemList({
    {items.map((item) => (
    -
    +
    {item.image?.href && ( {item.name} )}
    -
    +
    {item.name} @@ -42,16 +46,18 @@ export function CartItemList({ {item.meta.display_price.without_tax.unit.formatted}
    - - { - handleRemoveItem(item.id); - }} - /> +
    + + { + handleRemoveItem(item.id); + }} + /> +
    ))}
    diff --git a/examples/algolia/src/components/cart/CartOrderSummary.tsx b/examples/algolia/src/components/cart/CartOrderSummary.tsx index 077fa4b8..891304ef 100644 --- a/examples/algolia/src/components/cart/CartOrderSummary.tsx +++ b/examples/algolia/src/components/cart/CartOrderSummary.tsx @@ -68,10 +68,10 @@ export function CartOrderSummary({
    - + - +
    diff --git a/examples/algolia/src/components/featured-products/FeaturedProducts.tsx b/examples/algolia/src/components/featured-products/FeaturedProducts.tsx index 2fd5ea4c..d8ca7240 100644 --- a/examples/algolia/src/components/featured-products/FeaturedProducts.tsx +++ b/examples/algolia/src/components/featured-products/FeaturedProducts.tsx @@ -1,13 +1,12 @@ -import React, { useCallback, useEffect, useState } from "react"; -import type { ProductResponseWithImage } from "../../lib/types/product-types"; -import { connectProductsWithMainImages } from "../../lib/product-util"; -import { getProducts } from "../../services/products"; +"use server"; import clsx from "clsx"; import Link from "next/link"; import { ArrowRightIcon, EyeSlashIcon } from "@heroicons/react/24/outline"; import Image from "next/image"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { fetchFeaturedProducts } from "./fetchFeaturedProducts"; -interface IFeaturedProductsBaseProps { +interface IFeaturedProductsProps { title: string; linkProps?: { link: string; @@ -15,48 +14,12 @@ interface IFeaturedProductsBaseProps { }; } -interface IFeaturedProductsProvidedProps extends IFeaturedProductsBaseProps { - type: "provided"; - products: ProductResponseWithImage[]; -} - -interface IFeaturedProductsFetchProps extends IFeaturedProductsBaseProps { - type: "fetch"; -} - -type IFeaturedProductsProps = - | IFeaturedProductsFetchProps - | IFeaturedProductsProvidedProps; - -const FeaturedProducts = (props: IFeaturedProductsProps): JSX.Element => { - const { type, title, linkProps } = props; - - const [products, setProducts] = useState( - type === "provided" ? props.products : [], - ); - - const fetchNodeProducts = useCallback(async () => { - if (type === "fetch") { - const { data, included } = await getProducts(); - let products = data.slice(0, 4); - if (included?.main_images) { - products = connectProductsWithMainImages( - products, - included.main_images, - ); - } - setProducts(products); - } - }, [type]); - - useEffect(() => { - try { - fetchNodeProducts(); - } catch (error) { - console.error(error); - throw error; - } - }, [fetchNodeProducts]); +export default async function FeaturedProducts({ + title, + linkProps, +}: IFeaturedProductsProps) { + const client = getServerSideImplicitClient(); + const products = await fetchFeaturedProducts(client); return (
    { "max-w-7xl my-0 mx-auto", )} > -
    +

    {title}

    {linkProps && ( @@ -80,42 +43,44 @@ const FeaturedProducts = (props: IFeaturedProductsProps): JSX.Element => { )}
    -
    +
      {products.map((product) => ( - -
      - {product.main_image?.link.href ? ( - {product.main_image?.file_name - ) : ( -
      - + +
    • +
      +
      + {product.main_image?.link.href ? ( + {product.main_image?.file_name!} + ) : ( +
      + +
      + )}
      - )} - -

      +

      +

      {product.attributes.name} - -

      +

      +

      {product.meta.display_price?.without_tax.formatted} -

      -
    • +

      + ))} -
      +
    ); -}; - -export default FeaturedProducts; +} diff --git a/examples/algolia/src/components/featured-products/fetchFeaturedProducts.ts b/examples/algolia/src/components/featured-products/fetchFeaturedProducts.ts index 7f2c0bb9..9a5679e6 100644 --- a/examples/algolia/src/components/featured-products/fetchFeaturedProducts.ts +++ b/examples/algolia/src/components/featured-products/fetchFeaturedProducts.ts @@ -1,10 +1,14 @@ -// Fetching the first 4 products of in the catalog to display in the featured-products component -import { connectProductsWithMainImages } from "../../lib/product-util"; import { getProducts } from "../../services/products"; +import { Moltin } from "@moltin/sdk"; +import { ProductResponseWithImage } from "../../lib/types/product-types"; +import { connectProductsWithMainImages } from "../../lib/connect-products-with-main-images"; -export const fetchFeaturedProducts = async () => { +// Fetching the first 4 products of in the catalog to display in the featured-products component +export const fetchFeaturedProducts = async ( + client: Moltin, +): Promise => { const { data: productsResponse, included: productsIncluded } = - await getProducts(); + await getProducts(client); return productsIncluded?.main_images ? connectProductsWithMainImages( diff --git a/examples/algolia/src/components/footer/Footer.tsx b/examples/algolia/src/components/footer/Footer.tsx index f5eae085..46759f53 100644 --- a/examples/algolia/src/components/footer/Footer.tsx +++ b/examples/algolia/src/components/footer/Footer.tsx @@ -1,32 +1,32 @@ -import GithubIcon from "../../../public/icons/github.svg"; -import EpLogo from "../../../public/icons/ep-logo.svg"; import Link from "next/link"; import { PhoneIcon, InformationCircleIcon } from "@heroicons/react/24/solid"; +import { GitHubIcon } from "../icons/github-icon"; +import EpLogo from "../icons/ep-logo"; const Footer = (): JSX.Element => (
    - +
    - - Home + + Home - - Shipping + + Shipping - - FAQ + + FAQ
    - - About + + About - - Terms + + Terms
    @@ -37,41 +37,31 @@ const Footer = (): JSX.Element => ( className="flex items-center justify-center" passHref > - - {" "} - - + {" "} + - - {" "} - - + {" "} + - - - +
    diff --git a/examples/algolia/src/components/header/Header.tsx b/examples/algolia/src/components/header/Header.tsx index 1f7bddff..5460e83a 100644 --- a/examples/algolia/src/components/header/Header.tsx +++ b/examples/algolia/src/components/header/Header.tsx @@ -1,33 +1,29 @@ -import { NavigationNode } from "../../lib/build-site-navigation"; -import SearchModal from "../search/SearchModal"; import MobileNavBar from "./navigation/MobileNavBar"; -import EpIcon from "../../../public/icons/ep-icon.svg"; +import SearchModal from "../search/SearchModal"; import NavBar from "./navigation/NavBar"; import Link from "next/link"; import CartMenu from "./cart/CartMenu"; +import EpIcon from "../icons/ep-icon"; +import { Suspense } from "react"; -interface IHeader { - nav: NavigationNode[]; -} - -const Header = ({ nav }: IHeader): JSX.Element => { - const headerPadding = 4; - +const Header = (): JSX.Element => { return (
    - + + +
    - - -
    - -
    -
    + +
    - + +
    + +
    +
    diff --git a/examples/algolia/src/components/header/cart/CartMenu.tsx b/examples/algolia/src/components/header/cart/CartMenu.tsx index c6d59dad..84234349 100644 --- a/examples/algolia/src/components/header/cart/CartMenu.tsx +++ b/examples/algolia/src/components/header/cart/CartMenu.tsx @@ -1,3 +1,4 @@ +"use client"; import Link from "next/link"; import ModalCartItems from "./ModalCartItem"; import { @@ -92,7 +93,7 @@ function CartPopoverFooter({ const hasCartItems = state.kind === "present-cart-state"; return (
    - + diff --git a/examples/algolia/src/components/header/navigation/MobileNavBar.tsx b/examples/algolia/src/components/header/navigation/MobileNavBar.tsx index 3c313b88..93156749 100644 --- a/examples/algolia/src/components/header/navigation/MobileNavBar.tsx +++ b/examples/algolia/src/components/header/navigation/MobileNavBar.tsx @@ -1,53 +1,24 @@ +"use server"; import Link from "next/link"; -import { NavigationNode } from "../../../lib/build-site-navigation"; - -// TODO conditionally include the search modal - include search? -// import SearchModal from "../../search/SearchModal"; import CartMenu from "../cart/CartMenu"; -import EpIcon from "../../../../public/icons/ep-icon.svg"; -import { useState } from "react"; -import NavMenu from "./NavMenu"; - -interface IMobileNavBar { - nav: NavigationNode[]; -} +import EpIcon from "../../icons/ep-icon"; +import { MobileNavBarButton } from "./MobileNavBarButton"; +import { getServerSideImplicitClient } from "../../../lib/epcc-server-side-implicit-client"; +import { buildSiteNavigation } from "../../../lib/build-site-navigation"; -const MobileNavBar = ({ nav }: IMobileNavBar): JSX.Element => { - const [showMenu, setShowMenu] = useState(false); +export default async function MobileNavBar() { + const client = getServerSideImplicitClient(); + const nav = await buildSiteNavigation(client); return (
    - {/* React */}
    - - +
    - - -
    - -
    -
    + +
    @@ -58,6 +29,4 @@ const MobileNavBar = ({ nav }: IMobileNavBar): JSX.Element => {
    ); -}; - -export default MobileNavBar; +} diff --git a/examples/algolia/src/components/header/navigation/MobileNavBarButton.tsx b/examples/algolia/src/components/header/navigation/MobileNavBarButton.tsx new file mode 100644 index 00000000..7e9392c6 --- /dev/null +++ b/examples/algolia/src/components/header/navigation/MobileNavBarButton.tsx @@ -0,0 +1,33 @@ +"use client"; +import { useState } from "react"; +import NavMenu from "./NavMenu"; +import { NavigationNode } from "@elasticpath/react-shopper-hooks"; + +export function MobileNavBarButton({ nav }: { nav: NavigationNode[] }) { + const [showMenu, setShowMenu] = useState(false); + + return ( + <> + + + + ); +} diff --git a/examples/algolia/src/components/header/navigation/NavBar.tsx b/examples/algolia/src/components/header/navigation/NavBar.tsx index 752abf74..a18dd638 100644 --- a/examples/algolia/src/components/header/navigation/NavBar.tsx +++ b/examples/algolia/src/components/header/navigation/NavBar.tsx @@ -1,48 +1,17 @@ -import { Popover, Transition } from "@headlessui/react"; -import { Fragment } from "react"; -import type { NavigationNode } from "../../../lib/build-site-navigation"; -import NavItemContent from "./NavItemContent"; +"use server"; +import { NavBarPopover } from "./NavBarPopover"; +import { getServerSideImplicitClient } from "../../../lib/epcc-server-side-implicit-client"; +import { buildSiteNavigation } from "@elasticpath/shopper-common"; -interface INavBar { - nav: NavigationNode[]; - headerPadding: number; -} +export default async function NavBar() { + const client = getServerSideImplicitClient(); + const nav = await buildSiteNavigation(client); -const NavBar = ({ nav }: INavBar): JSX.Element => { return (
    - {nav && - nav.map((item: NavigationNode, index) => ( - - {({ close }) => ( - <> - - {item.name} - - - - -
    - -
    -
    -
    - - )} -
    - ))} +
    ); -}; - -export default NavBar; +} diff --git a/examples/algolia/src/components/header/navigation/NavBarPopover.tsx b/examples/algolia/src/components/header/navigation/NavBarPopover.tsx new file mode 100644 index 00000000..b7b445c3 --- /dev/null +++ b/examples/algolia/src/components/header/navigation/NavBarPopover.tsx @@ -0,0 +1,44 @@ +"use client"; +import { Popover, Transition } from "@headlessui/react"; +import { Fragment, ReactElement } from "react"; +import NavItemContent from "./NavItemContent"; +import { NavigationNode } from "../../../lib/build-site-navigation"; + +export function NavBarPopover({ + nav, +}: { + nav: NavigationNode[]; +}): ReactElement { + return ( + <> + {nav && + nav.map((item: NavigationNode) => ( + + {({ close }) => ( + <> + + {item.name} + + + + +
    + +
    +
    +
    + + )} +
    + ))} + + ); +} diff --git a/examples/algolia/src/components/header/navigation/NavItemContent.tsx b/examples/algolia/src/components/header/navigation/NavItemContent.tsx index b25eee2c..de3ee02c 100644 --- a/examples/algolia/src/components/header/navigation/NavItemContent.tsx +++ b/examples/algolia/src/components/header/navigation/NavItemContent.tsx @@ -13,16 +13,23 @@ const NavItemContent = ({ item, onClose }: IProps): JSX.Element => {
    {item.name} {item.children.map((child: NavigationNode) => ( - - onClose()}> - {child.name} - + onClose()} + > + {child.name} ))} - - onClose()}> - Browse All - + onClose()} + > + Browse All
    ); @@ -37,17 +44,13 @@ const NavItemContent = ({ item, onClose }: IProps): JSX.Element => {

    onClose()} > - onClose()} - > - Browse All {item.name} - - + Browse All {item.name} +
    ); diff --git a/examples/algolia/src/components/header/navigation/NavMenu.tsx b/examples/algolia/src/components/header/navigation/NavMenu.tsx index 9469860c..c22dd9ca 100644 --- a/examples/algolia/src/components/header/navigation/NavMenu.tsx +++ b/examples/algolia/src/components/header/navigation/NavMenu.tsx @@ -1,3 +1,4 @@ +"use client"; import { Dispatch, SetStateAction, Fragment, useState } from "react"; import { Transition, Dialog, Disclosure } from "@headlessui/react"; import { NavigationNode } from "@elasticpath/react-shopper-hooks"; diff --git a/examples/algolia/src/components/icons/cart.tsx b/examples/algolia/src/components/icons/cart.tsx new file mode 100644 index 00000000..bbb0fe34 --- /dev/null +++ b/examples/algolia/src/components/icons/cart.tsx @@ -0,0 +1,16 @@ +import clsx from "clsx"; +import { SVGProps } from "react"; + +export default function Cart(props: SVGProps) { + return ( + + + + + ); +} diff --git a/examples/algolia/src/components/icons/ep-icon.tsx b/examples/algolia/src/components/icons/ep-icon.tsx new file mode 100644 index 00000000..ea703d5d --- /dev/null +++ b/examples/algolia/src/components/icons/ep-icon.tsx @@ -0,0 +1,20 @@ +import clsx from "clsx"; +import { SVGProps } from "react"; + +export default function EpIcon(props: SVGProps) { + return ( + + + + ); +} diff --git a/examples/algolia/src/components/icons/ep-logo.tsx b/examples/algolia/src/components/icons/ep-logo.tsx new file mode 100644 index 00000000..21bf4d4f --- /dev/null +++ b/examples/algolia/src/components/icons/ep-logo.tsx @@ -0,0 +1,31 @@ +import clsx from "clsx"; +import { SVGProps } from "react"; + +export default function EpLogo(props: SVGProps) { + return ( + + + + + + + + + + + + ); +} diff --git a/examples/algolia/src/components/icons/github-icon.tsx b/examples/algolia/src/components/icons/github-icon.tsx new file mode 100644 index 00000000..5b4ef518 --- /dev/null +++ b/examples/algolia/src/components/icons/github-icon.tsx @@ -0,0 +1,16 @@ +import * as React from "react"; +import { SVGProps } from "react"; +import clsx from "clsx"; +export function GitHubIcon(props: SVGProps) { + return ( + + + + ); +} diff --git a/examples/algolia/src/components/layouts/MainLayout.tsx b/examples/algolia/src/components/layouts/MainLayout.tsx deleted file mode 100644 index 3160598e..00000000 --- a/examples/algolia/src/components/layouts/MainLayout.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import Header from "../header/Header"; -import Footer from "../footer/Footer"; -import type { ReactNode } from "react"; -import type { NavigationNode } from "../../lib/build-site-navigation"; -import { Toaster } from "../toast/toaster"; -import Head from "next/head"; -export const MAIN_LAYOUT_TITLE = "D2C Starter Kit"; - -interface IMainLayout { - nav?: NavigationNode[]; - children: ReactNode; -} - -const MainLayout = ({ nav = [], children }: IMainLayout): JSX.Element => { - return ( - <> - - {MAIN_LAYOUT_TITLE} - - - -
    - {children} -