From 9b71bd77fcb7e7fa8314b4d6494203f974c97a16 Mon Sep 17 00:00:00 2001 From: B Date: Thu, 4 Mar 2021 07:57:25 -0300 Subject: [PATCH] Agnostic UI (#199) * changes * Progress * Normalized Products output * Progress * Restored Index Agnostic * Progress * Reordering * Moved normalizer to BC function * Removed Futures * More Types * More Types * More Types * Fix useCallback * Progress, Changes types, readme and restoring functionality * Changes * TS Issues * Changes * Normalizer * Normalizing more operations * Normalizing more operations * changes * Merge Issues * Cleanup * change * changes * index.ts broke my tree shaking * slug * Normalized Options and Swatches * Restored Add to cart * Correct Variant Added to Cart * Normalizing Cart Responses * Changes * changes breaking * Adding immutable normalizer for Product * Cart Normalized * changes * Progress * More updates * Removed some comments * Add loading state for data hooks * Bug fix * Changed the way isEmpty works * Improve navbar performance * Added useResponse hook * added useResponse to useWhishlist * Added husky and lint-staged * Ran prettier fix * Added more cart types * Moved types.d.ts to the commerce folder * Minor changes * Moved normalizer to happen after fetch * updated useCart types * Updated normalizer for useData * Added new normalizer for the cart to the UI * More corrections for useCart * Updated cart update hooks * Removed import * Progress * Switch away from global types * Making multiple changes * Improved types for operations * Moved and updated cart types * Updated the useAddItem and useRemoveItem hooks * Minor life improvement * Minor change * Implement Shopify Provider * Update README.md * Update README.md * normalizations & missing files * Update index.ts * fixes * Update normalize.ts * fix: cart error on first load * shopify checkout redirect & api handler * Update get-checkout-id.ts * userAvatar * Fix: color option * Update normalize.ts * changes * Update next.config.js * start customer auth & signup * Update config.ts * Login, Sign Up, Log Out, and checkout & customer association * Automatic login after sign-up * Update handle-login.ts * MOving stuff around and adding temporal new files * changes * Replace use-cart with the new hook * Removed old hook * Improved HookHandler type * Moved types * Simplified useData types * Updated Fetcher type * Moved SwrOptions type * Removed duplicated fetcher * Moved provider to its own file * Added proper type for fetch input * Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic" This reverts commit 23c8ed7c2d48d30e74ad94216f9910650fadf30c, reversing changes made to bf50965a39ef0b1b956461ebe62070809fbe1d63. * change readme * Revert "Merge branch 'master' of https://github.com/vercel/commerce into agnostic" This reverts commit bf50965a39ef0b1b956461ebe62070809fbe1d63, reversing changes made to 0dad4ddedbf0bff2d0b5800ca469fda0073889ea. * Revert "Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic"" This reverts commit c9a43f1bce0572d0eff41f3af893be8bdb00bedd. * align with upstream changes * Updated how the hook input is handled * Add more options to the hook handler * Final touches to the hook handler type * Moved useWishlist to use new handler * Move useCustomer to the new hook * Added a default fetcher * query all products for vendors & paths, improve search * Update use-search.tsx * fix cart after upstream changes * Shopify Provider (#186) * Start of Shopify provider * add missing comment to documentation * add missing env vars to documentation * update reference to types file * Moved useSearch to the new hook * Removed old use-data lib * Removed generics for result and body * Removed normalizr * Wishlist * New changes and initial Features API * Fixed some types * Fixed more types * fixes after upstream changes * Fixed product types * Fixed another product type * Updated type * Fixed remaining issues with types * Added a MutationHandler * Moved the handlers to each hook * Moved the fetcher to its own file * Moved handler to each hook * Added initial version of useAddItem * Added better mutation types, and moved some hooks * Removed use-cart-actions * Added initial version of useAddItem * Updated types * Update use-add-item.tsx * changes * Changes * Reordering and changes * Adding Features APO * Adding wishlist api * Implementing FeaturesAPI with Wishlist * Removing bug with touchstart * Adding tyni typing * moved use-remove-item * Removed MutationHandler type * Moved more hooks and updated types to make them smaller * Moved data hooks to new format * Removed no longer required types * Removed useResponse helper * Updated useData type * Moved wishlist use-add-item * Moved wishlist use-remove-item to provider * Moved use-login and use-logout * Update use-signup * Removed use-action helper * Moved auth & cart hooks + several fixes * Updated cart item, fixed deprecations * Update next.config.js * Updates to wishlist feature * Moved the features to be environment variable only * More changes for wishlist config * Disable wishlist * Removed useWishlistActions * Updated readme * updates * typos * Updated the way the provider config is set * Removed features.ts * Removed bootstrap.js * Aligned with upstream changes * Updates * shopify: changes * shopify: changes * Update next.config.js * Shopify Provider Updates (#209) * Implement Shopify Provider * Update README.md * Update README.md * normalizations & missing files * Update index.ts * fixes * Update normalize.ts * fix: cart error on first load * shopify checkout redirect & api handler * Update get-checkout-id.ts * Fix: color option * Update normalize.ts * changes * Update next.config.js * start customer auth & signup * Update config.ts * Login, Sign Up, Log Out, and checkout & customer association * Automatic login after sign-up * Update handle-login.ts * changes * Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic" This reverts commit 23c8ed7c2d48d30e74ad94216f9910650fadf30c, reversing changes made to bf50965a39ef0b1b956461ebe62070809fbe1d63. * change readme * Revert "Merge branch 'master' of https://github.com/vercel/commerce into agnostic" This reverts commit bf50965a39ef0b1b956461ebe62070809fbe1d63, reversing changes made to 0dad4ddedbf0bff2d0b5800ca469fda0073889ea. * Revert "Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic"" This reverts commit c9a43f1bce0572d0eff41f3af893be8bdb00bedd. * align with upstream changes * query all products for vendors & paths, improve search * Update use-search.tsx * fix cart after upstream changes * fixes after upstream changes * Moved handler to each hook * Added initial version of useAddItem * Updated types * Update use-add-item.tsx * Moved auth & cart hooks + several fixes * Updated cart item, fixed deprecations * Update next.config.js * Aligned with upstream changes * Updates * Update next.config.js * Updated the commerce config structure * Removed @framework imports within framework providers * Fixed types * changes * Adding extra config * Adding shopify commit * Adding env templates to the providers * Ignore some types * Adding link for Cart * Adding customCheckout * multiple changes to fix the wishlist * Shopify Provier Updates (#212) * changes * Adding shopify commit * Changed to query page by id * Fixed page query, Changed use-search GraphQl query * Update use-search.tsx * remove unused util * Changed cookie expiration * Update tsconfig.json Co-authored-by: okbel * Bump and adding dependency * Adding color checks * Now colors work with lighter colors * Stable commerce.config.json * Updated main readme * Readme changes * Default to bigcommerce Co-authored-by: bc Co-authored-by: Luis Alvarez Co-authored-by: cond0r Co-authored-by: Peter Mekhaeil <4616064+petermekhaeil@users.noreply.github.com> --- .env.template | 6 +- .prettierrc | 6 + .vscode/extensions.json | 3 + README.md | 149 +- commerce.config.json | 7 + components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 2 +- components/cart/CartItem/CartItem.tsx | 65 +- .../cart/CartSidebarView/CartSidebarView.tsx | 45 +- components/common/Footer/Footer.tsx | 2 +- .../HomeAllProductsGrid.tsx | 23 +- components/common/I18nWidget/I18nWidget.tsx | 2 +- components/common/Layout/Layout.tsx | 14 +- components/common/Navbar/Navbar.tsx | 96 +- components/common/Navbar/NavbarRoot.tsx | 33 + components/common/UserNav/DropdownMenu.tsx | 3 +- components/common/UserNav/UserNav.tsx | 29 +- components/icons/CreditCard.tsx | 20 + components/icons/MapPin.tsx | 20 + components/icons/Vercel.tsx | 46 +- components/icons/index.ts | 2 + .../product/ProductCard/ProductCard.tsx | 143 +- .../product/ProductSlider/ProductSlider.tsx | 28 +- .../ProductView/ProductView.module.css | 2 +- .../product/ProductView/ProductView.tsx | 83 +- components/product/Swatch/Swatch.module.css | 1 + components/product/Swatch/Swatch.tsx | 2 +- components/product/helpers.ts | 56 +- components/ui/Container/Container.tsx | 6 +- components/ui/Marquee/Marquee.module.css | 11 +- components/ui/context.tsx | 16 +- components/ui/index.ts | 1 + .../WishlistButton/WishlistButton.tsx | 29 +- .../wishlist/WishlistCard/WishlistCard.tsx | 33 +- components/wishlist/index.ts | 1 + config/seo.json | 14 +- framework/bigcommerce/.env.template | 6 + framework/bigcommerce/README.md | 55 +- .../bigcommerce/api/cart/handlers/add-item.ts | 11 +- .../bigcommerce/api/cart/handlers/get-cart.ts | 9 +- .../api/cart/handlers/remove-item.ts | 1 - .../api/cart/handlers/update-item.ts | 1 - framework/bigcommerce/api/cart/index.ts | 62 +- .../api/catalog/handlers/get-products.ts | 14 +- framework/bigcommerce/api/catalog/products.ts | 8 +- .../api/customers/handlers/login.ts | 2 +- .../api/customers/handlers/signup.ts | 2 +- framework/bigcommerce/api/utils/parse-item.ts | 30 +- .../api/utils/set-product-locale-meta.ts | 2 +- .../api/wishlist/handlers/add-item.ts | 4 +- .../api/wishlist/handlers/get-wishlist.ts | 4 +- .../api/wishlist/handlers/remove-item.ts | 4 +- framework/bigcommerce/api/wishlist/index.ts | 11 +- framework/bigcommerce/auth/index.ts | 3 + .../{api/operations => auth}/login.ts | 10 +- framework/bigcommerce/auth/use-login.tsx | 40 + framework/bigcommerce/auth/use-logout.tsx | 25 + framework/bigcommerce/auth/use-signup.tsx | 44 + framework/bigcommerce/cart/index.ts | 4 + framework/bigcommerce/cart/use-add-item.tsx | 76 +- .../bigcommerce/cart/use-cart-actions.tsx | 13 - framework/bigcommerce/cart/use-cart.tsx | 81 +- .../bigcommerce/cart/use-remove-item.tsx | 102 +- .../bigcommerce/cart/use-update-item.tsx | 135 +- framework/bigcommerce/commerce.config.json | 6 + .../operations => common}/get-all-pages.ts | 6 +- .../{api/operations => common}/get-page.ts | 12 +- .../operations => common}/get-site-info.ts | 10 +- .../get-customer-id.ts | 4 +- .../get-customer-wishlist.ts | 13 +- framework/bigcommerce/customer/index.ts | 1 + .../bigcommerce/customer/use-customer.tsx | 24 + framework/bigcommerce/fetcher.ts | 41 + framework/bigcommerce/index.tsx | 44 +- framework/bigcommerce/lib/immutability.ts | 13 + framework/bigcommerce/lib/normalize.ts | 113 + framework/bigcommerce/next.config.js | 8 + .../get-all-product-paths.ts | 8 +- .../get-all-products.ts | 21 +- .../operations => product}/get-product.ts | 15 +- framework/bigcommerce/product/index.ts | 4 + framework/bigcommerce/product/use-price.tsx | 2 + framework/bigcommerce/product/use-search.tsx | 53 + framework/bigcommerce/products/use-search.tsx | 63 - framework/bigcommerce/provider.ts | 34 + framework/bigcommerce/types.ts | 58 + framework/bigcommerce/use-customer.tsx | 38 - framework/bigcommerce/use-login.tsx | 54 - framework/bigcommerce/use-logout.tsx | 38 - framework/bigcommerce/use-price.tsx | 2 - framework/bigcommerce/use-signup.tsx | 54 - framework/bigcommerce/wishlist/index.ts | 3 + .../bigcommerce/wishlist/use-add-item.tsx | 54 +- .../bigcommerce/wishlist/use-remove-item.tsx | 67 +- .../wishlist/use-wishlist-actions.tsx | 11 - .../bigcommerce/wishlist/use-wishlist.tsx | 106 +- framework/commerce/api/index.ts | 2 - framework/commerce/auth/use-login.tsx | 19 + framework/commerce/auth/use-logout.tsx | 19 + framework/commerce/auth/use-signup.tsx | 19 + framework/commerce/cart/use-add-item.tsx | 22 +- framework/commerce/cart/use-cart-actions.tsx | 17 - framework/commerce/cart/use-cart.tsx | 54 +- framework/commerce/cart/use-remove-item.tsx | 34 +- framework/commerce/cart/use-update-item.tsx | 37 +- framework/commerce/customer/use-customer.tsx | 20 + framework/commerce/index.tsx | 62 +- .../commerce/{ => product}/use-price.tsx | 2 +- framework/commerce/product/use-search.tsx | 20 + framework/commerce/products/use-search.tsx | 5 - framework/commerce/types.ts | 203 + framework/commerce/use-customer.tsx | 5 - framework/commerce/use-login.tsx | 5 - framework/commerce/use-logout.tsx | 5 - framework/commerce/use-signup.tsx | 5 - framework/commerce/utils/default-fetcher.ts | 12 + framework/commerce/utils/define-property.ts | 37 + framework/commerce/utils/errors.ts | 8 + framework/commerce/utils/types.ts | 131 +- framework/commerce/utils/use-action.tsx | 15 - framework/commerce/utils/use-data.tsx | 65 +- framework/commerce/utils/use-hook.ts | 50 + framework/commerce/wishlist/index.ts | 3 + framework/commerce/wishlist/use-add-item.tsx | 18 +- .../commerce/wishlist/use-remove-item.tsx | 27 +- framework/commerce/wishlist/use-wishlist.tsx | 36 +- framework/commerce/with-config.js | 41 + framework/shopify/.env.template | 2 + framework/shopify/README.md | 260 + framework/shopify/api/cart/index.ts | 1 + framework/shopify/api/catalog/index.ts | 1 + framework/shopify/api/catalog/products.ts | 1 + framework/shopify/api/checkout/index.ts | 46 + framework/shopify/api/customer.ts | 1 + framework/shopify/api/customers/index.ts | 1 + framework/shopify/api/customers/login.ts | 1 + framework/shopify/api/customers/logout.ts | 1 + framework/shopify/api/customers/signup.ts | 1 + framework/shopify/api/index.ts | 62 + .../api/operations/get-all-collections.ts | 21 + framework/shopify/api/operations/get-page.ts | 25 + .../shopify/api/utils/create-api-handler.ts | 58 + .../shopify/api/utils/fetch-all-products.ts | 41 + .../shopify/api/utils/fetch-graphql-api.ts | 34 + framework/shopify/api/utils/fetch.ts | 2 + .../shopify/api/utils/is-allowed-method.ts | 28 + framework/shopify/api/wishlist/index.tsx | 2 + framework/shopify/auth/use-login.tsx | 76 + framework/shopify/auth/use-logout.tsx | 36 + framework/shopify/auth/use-signup.tsx | 74 + framework/shopify/cart/index.ts | 3 + framework/shopify/cart/use-add-item.tsx | 58 + framework/shopify/cart/use-cart.tsx | 59 + framework/shopify/cart/use-remove-item.tsx | 72 + framework/shopify/cart/use-update-item.tsx | 107 + .../shopify/cart/utils/checkout-create.ts | 29 + .../shopify/cart/utils/checkout-to-cart.ts | 42 + framework/shopify/cart/utils/fetcher.ts | 31 + framework/shopify/cart/utils/index.ts | 2 + framework/shopify/commerce.config.json | 6 + framework/shopify/common/get-all-pages.ts | 42 + framework/shopify/common/get-page.ts | 37 + framework/shopify/common/get-site-info.ts | 31 + framework/shopify/const.ts | 13 + framework/shopify/customer/get-customer-id.ts | 24 + framework/shopify/customer/index.ts | 1 + framework/shopify/customer/use-customer.tsx | 27 + framework/shopify/fetcher.ts | 18 + framework/shopify/index.tsx | 40 + framework/shopify/next.config.js | 8 + .../shopify/product/get-all-collections.ts | 29 + .../shopify/product/get-all-product-paths.ts | 42 + framework/shopify/product/get-all-products.ts | 40 + framework/shopify/product/get-product.ts | 32 + framework/shopify/product/use-price.tsx | 2 + framework/shopify/product/use-search.tsx | 77 + framework/shopify/provider.ts | 31 + framework/shopify/schema.d.ts | 4985 +++++++++ framework/shopify/schema.graphql | 9631 +++++++++++++++++ framework/shopify/types.ts | 45 + framework/shopify/utils/customer-token.ts | 21 + framework/shopify/utils/get-categories.ts | 29 + framework/shopify/utils/get-checkout-id.ts | 8 + .../shopify/utils/get-search-variables.ts | 27 + framework/shopify/utils/get-sort-variables.ts | 32 + framework/shopify/utils/get-vendors.ts | 36 + .../shopify/utils/handle-fetch-response.ts | 27 + framework/shopify/utils/handle-login.ts | 39 + framework/shopify/utils/index.ts | 10 + .../associate-customer-with-checkout.ts | 18 + .../utils/mutations/checkout-create.ts | 16 + .../utils/mutations/checkout-line-item-add.ts | 16 + .../mutations/checkout-line-item-remove.ts | 19 + .../mutations/checkout-line-item-update.ts | 16 + .../mutations/customer-access-token-create.ts | 16 + .../mutations/customer-access-token-delete.ts | 14 + .../utils/mutations/customer-create.ts | 15 + framework/shopify/utils/mutations/index.ts | 7 + framework/shopify/utils/normalize.ts | 152 + .../queries/get-all-collections-query.ts | 14 + .../utils/queries/get-all-pages-query.ts | 14 + .../queries/get-all-product-vendors-query.ts | 17 + .../queries/get-all-products-paths-query.ts | 17 + .../utils/queries/get-all-products-query.ts | 57 + .../utils/queries/get-checkout-query.ts | 62 + .../queries/get-collection-products-query.ts | 24 + .../utils/queries/get-customer-id-query.ts | 8 + .../utils/queries/get-customer-query.ts | 16 + .../shopify/utils/queries/get-page-query.ts | 14 + .../utils/queries/get-product-query.ts | 69 + framework/shopify/utils/queries/index.ts | 10 + framework/shopify/utils/storage.ts | 13 + framework/shopify/wishlist/use-add-item.tsx | 13 + .../shopify/wishlist/use-remove-item.tsx | 17 + framework/shopify/wishlist/use-wishlist.tsx | 46 + lib/click-outside/click-outside.tsx | 50 +- lib/colors.ts | 156 +- next.config.js | 20 +- package.json | 138 +- pages/[...pages].tsx | 7 +- pages/_app.tsx | 5 +- pages/blog.tsx | 2 +- pages/cart.tsx | 60 +- pages/index.tsx | 123 +- pages/orders.tsx | 6 +- pages/product/[slug].tsx | 16 +- pages/profile.tsx | 4 +- pages/search.tsx | 56 +- pages/wishlist.tsx | 32 +- public/card.png | Bin 0 -> 6286 bytes tsconfig.json | 14 +- yarn.lock | 745 +- 232 files changed, 20545 insertions(+), 1895 deletions(-) create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 commerce.config.json create mode 100644 components/common/Navbar/NavbarRoot.tsx create mode 100644 components/icons/CreditCard.tsx create mode 100644 components/icons/MapPin.tsx create mode 100644 framework/bigcommerce/.env.template create mode 100644 framework/bigcommerce/auth/index.ts rename framework/bigcommerce/{api/operations => auth}/login.ts (87%) create mode 100644 framework/bigcommerce/auth/use-login.tsx create mode 100644 framework/bigcommerce/auth/use-logout.tsx create mode 100644 framework/bigcommerce/auth/use-signup.tsx create mode 100644 framework/bigcommerce/cart/index.ts delete mode 100644 framework/bigcommerce/cart/use-cart-actions.tsx create mode 100644 framework/bigcommerce/commerce.config.json rename framework/bigcommerce/{api/operations => common}/get-all-pages.ts (83%) rename framework/bigcommerce/{api/operations => common}/get-page.ts (75%) rename framework/bigcommerce/{api/operations => common}/get-site-info.ts (89%) rename framework/bigcommerce/{api/operations => customer}/get-customer-id.ts (84%) rename framework/bigcommerce/{api/operations => customer}/get-customer-wishlist.ts (83%) create mode 100644 framework/bigcommerce/customer/index.ts create mode 100644 framework/bigcommerce/customer/use-customer.tsx create mode 100644 framework/bigcommerce/fetcher.ts create mode 100644 framework/bigcommerce/lib/immutability.ts create mode 100644 framework/bigcommerce/lib/normalize.ts create mode 100644 framework/bigcommerce/next.config.js rename framework/bigcommerce/{api/operations => product}/get-all-product-paths.ts (89%) rename framework/bigcommerce/{api/operations => product}/get-all-products.ts (82%) rename framework/bigcommerce/{api/operations => product}/get-product.ts (87%) create mode 100644 framework/bigcommerce/product/index.ts create mode 100644 framework/bigcommerce/product/use-price.tsx create mode 100644 framework/bigcommerce/product/use-search.tsx delete mode 100644 framework/bigcommerce/products/use-search.tsx create mode 100644 framework/bigcommerce/provider.ts create mode 100644 framework/bigcommerce/types.ts delete mode 100644 framework/bigcommerce/use-customer.tsx delete mode 100644 framework/bigcommerce/use-login.tsx delete mode 100644 framework/bigcommerce/use-logout.tsx delete mode 100644 framework/bigcommerce/use-price.tsx delete mode 100644 framework/bigcommerce/use-signup.tsx create mode 100644 framework/bigcommerce/wishlist/index.ts delete mode 100644 framework/bigcommerce/wishlist/use-wishlist-actions.tsx create mode 100644 framework/commerce/auth/use-login.tsx create mode 100644 framework/commerce/auth/use-logout.tsx create mode 100644 framework/commerce/auth/use-signup.tsx delete mode 100644 framework/commerce/cart/use-cart-actions.tsx create mode 100644 framework/commerce/customer/use-customer.tsx rename framework/commerce/{ => product}/use-price.tsx (97%) create mode 100644 framework/commerce/product/use-search.tsx delete mode 100644 framework/commerce/products/use-search.tsx create mode 100644 framework/commerce/types.ts delete mode 100644 framework/commerce/use-customer.tsx delete mode 100644 framework/commerce/use-login.tsx delete mode 100644 framework/commerce/use-logout.tsx delete mode 100644 framework/commerce/use-signup.tsx create mode 100644 framework/commerce/utils/default-fetcher.ts create mode 100644 framework/commerce/utils/define-property.ts delete mode 100644 framework/commerce/utils/use-action.tsx create mode 100644 framework/commerce/utils/use-hook.ts create mode 100644 framework/commerce/wishlist/index.ts create mode 100644 framework/commerce/with-config.js create mode 100644 framework/shopify/.env.template create mode 100644 framework/shopify/README.md create mode 100644 framework/shopify/api/cart/index.ts create mode 100644 framework/shopify/api/catalog/index.ts create mode 100644 framework/shopify/api/catalog/products.ts create mode 100644 framework/shopify/api/checkout/index.ts create mode 100644 framework/shopify/api/customer.ts create mode 100644 framework/shopify/api/customers/index.ts create mode 100644 framework/shopify/api/customers/login.ts create mode 100644 framework/shopify/api/customers/logout.ts create mode 100644 framework/shopify/api/customers/signup.ts create mode 100644 framework/shopify/api/index.ts create mode 100644 framework/shopify/api/operations/get-all-collections.ts create mode 100644 framework/shopify/api/operations/get-page.ts create mode 100644 framework/shopify/api/utils/create-api-handler.ts create mode 100644 framework/shopify/api/utils/fetch-all-products.ts create mode 100644 framework/shopify/api/utils/fetch-graphql-api.ts create mode 100644 framework/shopify/api/utils/fetch.ts create mode 100644 framework/shopify/api/utils/is-allowed-method.ts create mode 100644 framework/shopify/api/wishlist/index.tsx create mode 100644 framework/shopify/auth/use-login.tsx create mode 100644 framework/shopify/auth/use-logout.tsx create mode 100644 framework/shopify/auth/use-signup.tsx create mode 100644 framework/shopify/cart/index.ts create mode 100644 framework/shopify/cart/use-add-item.tsx create mode 100644 framework/shopify/cart/use-cart.tsx create mode 100644 framework/shopify/cart/use-remove-item.tsx create mode 100644 framework/shopify/cart/use-update-item.tsx create mode 100644 framework/shopify/cart/utils/checkout-create.ts create mode 100644 framework/shopify/cart/utils/checkout-to-cart.ts create mode 100644 framework/shopify/cart/utils/fetcher.ts create mode 100644 framework/shopify/cart/utils/index.ts create mode 100644 framework/shopify/commerce.config.json create mode 100644 framework/shopify/common/get-all-pages.ts create mode 100644 framework/shopify/common/get-page.ts create mode 100644 framework/shopify/common/get-site-info.ts create mode 100644 framework/shopify/const.ts create mode 100644 framework/shopify/customer/get-customer-id.ts create mode 100644 framework/shopify/customer/index.ts create mode 100644 framework/shopify/customer/use-customer.tsx create mode 100644 framework/shopify/fetcher.ts create mode 100644 framework/shopify/index.tsx create mode 100644 framework/shopify/next.config.js create mode 100644 framework/shopify/product/get-all-collections.ts create mode 100644 framework/shopify/product/get-all-product-paths.ts create mode 100644 framework/shopify/product/get-all-products.ts create mode 100644 framework/shopify/product/get-product.ts create mode 100644 framework/shopify/product/use-price.tsx create mode 100644 framework/shopify/product/use-search.tsx create mode 100644 framework/shopify/provider.ts create mode 100644 framework/shopify/schema.d.ts create mode 100644 framework/shopify/schema.graphql create mode 100644 framework/shopify/types.ts create mode 100644 framework/shopify/utils/customer-token.ts create mode 100644 framework/shopify/utils/get-categories.ts create mode 100644 framework/shopify/utils/get-checkout-id.ts create mode 100644 framework/shopify/utils/get-search-variables.ts create mode 100644 framework/shopify/utils/get-sort-variables.ts create mode 100644 framework/shopify/utils/get-vendors.ts create mode 100644 framework/shopify/utils/handle-fetch-response.ts create mode 100644 framework/shopify/utils/handle-login.ts create mode 100644 framework/shopify/utils/index.ts create mode 100644 framework/shopify/utils/mutations/associate-customer-with-checkout.ts create mode 100644 framework/shopify/utils/mutations/checkout-create.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-add.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-remove.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-update.ts create mode 100644 framework/shopify/utils/mutations/customer-access-token-create.ts create mode 100644 framework/shopify/utils/mutations/customer-access-token-delete.ts create mode 100644 framework/shopify/utils/mutations/customer-create.ts create mode 100644 framework/shopify/utils/mutations/index.ts create mode 100644 framework/shopify/utils/normalize.ts create mode 100644 framework/shopify/utils/queries/get-all-collections-query.ts create mode 100644 framework/shopify/utils/queries/get-all-pages-query.ts create mode 100644 framework/shopify/utils/queries/get-all-product-vendors-query.ts create mode 100644 framework/shopify/utils/queries/get-all-products-paths-query.ts create mode 100644 framework/shopify/utils/queries/get-all-products-query.ts create mode 100644 framework/shopify/utils/queries/get-checkout-query.ts create mode 100644 framework/shopify/utils/queries/get-collection-products-query.ts create mode 100644 framework/shopify/utils/queries/get-customer-id-query.ts create mode 100644 framework/shopify/utils/queries/get-customer-query.ts create mode 100644 framework/shopify/utils/queries/get-page-query.ts create mode 100644 framework/shopify/utils/queries/get-product-query.ts create mode 100644 framework/shopify/utils/queries/index.ts create mode 100644 framework/shopify/utils/storage.ts create mode 100644 framework/shopify/wishlist/use-add-item.tsx create mode 100644 framework/shopify/wishlist/use-remove-item.tsx create mode 100644 framework/shopify/wishlist/use-wishlist.tsx create mode 100644 public/card.png diff --git a/.env.template b/.env.template index 73a8a6e3b..9b45afe4b 100644 --- a/.env.template +++ b/.env.template @@ -2,4 +2,8 @@ BIGCOMMERCE_STOREFRONT_API_URL= BIGCOMMERCE_STOREFRONT_API_TOKEN= BIGCOMMERCE_STORE_API_URL= BIGCOMMERCE_STORE_API_TOKEN= -BIGCOMMERCE_STORE_API_CLIENT_ID= \ No newline at end of file +BIGCOMMERCE_STORE_API_CLIENT_ID= +BIGCOMMERCE_CHANNEL_ID= + +SHOPIFY_STORE_DOMAIN= +SHOPIFY_STOREFRONT_ACCESS_TOKEN= diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..e1076edfa --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "useTabs": false +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..c83e26348 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["esbenp.prettier-vscode"] +} diff --git a/README.md b/README.md index 8eb69383c..885c95e85 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ Start right now at [nextjs.org/commerce](https://nextjs.org/commerce) Demo live at: [demo.vercel.store](https://demo.vercel.store/) -This project is currently under development. +- Shopify Demo: https://shopify.demo.vercel.store/ +- BigCommerce Demo: https://bigcommerce.demo.vercel.store/ ## Features @@ -21,26 +22,122 @@ This project is currently under development. - Integrations - Integrate seamlessly with the most common ecommerce platforms. - Dark Mode Support +## Integrations + +Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends. + +## Considerations + +- `framework/commerce` contains all types, helpers and functions to be used as base to build a new **provider**. +- **Providers** live under `framework`'s root folder and they will extend Next.js Commerce types and functionality. +- **Features API** is to ensure feature parity between the UI and the Provider. The UI should update accordingly and no extra code should be bundled. All extra configuration for features will live under `features` in `commerce.config.json` and if needed it can also be accessed programatically. +- Each **provider** should add its corresponding `next.config.js` and `commerce.config.json` adding specific data related to the provider. For example in case of BigCommerce, the images CDN and additional API routes. +- **Providers don't depend on anything that's specific to the application they're used in**. They only depend on `framework/commerce`, on their own framework folder and on some dependencies included in `package.json` +- We recommend that each **provider** ships with an `env.template` file and a `[readme.md](http://readme.md)` file. + +## Provider Structure + +Next.js Commerce provides a set of utilities and functions to create new providers. This is how a provider structure looks like. + +- `product` + - usePrice + - useSearch + - getProduct + - getAllProducts +- `wishlist` + - useWishlist + - useAddItem + - useRemoveItem +- `auth` + - useLogin + - useLogout + - useSignup +- `customer` + - useCustomer + - getCustomerId + - getCustomerWistlist +- `cart` + - useCart + - useAddItem + - useRemoveItem + - useUpdateItem +- `env.template` +- `provider.ts` +- `commerce.config.json` +- `next.config.js` +- `README.md` + +## Configuration + +### How to change providers + +First, update the provider selected in `commerce.config.json`: + +```json +{ + "provider": "bigcommerce", + "features": { + "wishlist": true + } +} +``` + +Then, change the paths defined in `tsconfig.json` and update the `@framework` paths to point to the right folder provider: + +```json +"@framework": ["framework/bigcommerce"], +"@framework/*": ["framework/bigcommerce/*"] +``` + +Make sure to add the environment variables required by the new provider. + +### Features + +Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` + +#### How to turn Features on and off + +> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box) + +- Open `commerce.config.json` +- You'll see a config file like this: + ```json + { + "provider": "bigcommerce", + "features": { + "wishlist": false + } + } + ``` +- Turn wishlist on by setting wishlist to true. +- Run the app and the wishlist functionality should be back on. + +### How to create a new provider + +We'd recommend to duplicate a provider folder and push your providers SDK. + +If you succeeded building a provider, submit a PR so we can all enjoy it. + ## Work in progress + We're using Github Projects to keep track of issues in progress and todo's. Here is our [Board](https://github.com/vercel/commerce/projects/1) -## Integrations -Next.js Commerce integrates out-of-the-box with BigCommerce. We plan to support all major ecommerce backends. - - -## Goals - -* **Next.js Commerce** should have a completely data **agnostic** UI -* **Aware of schema**: should ship with the right data schemas and types. -* All providers should return the right data types and schemas to blend correctly with Next.js Commerce. -* `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ - -There is a `framework` folder in the root folder that will contain multiple ecommerce providers. - -Additionally, we need to ensure feature parity (not all providers have e.g. wishlist) we will also have to build a feature API to disable/enable features in the UI. - People actively working on this project: @okbel & @lfades. +## Contribute + +Our commitment to Open Source can be found [here](https://vercel.com/oss). + +1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. +2. Create a new branch `git checkout -b MY_BRANCH_NAME` +3. Install yarn: `npm install -g yarn` +4. Install the dependencies: `yarn` +5. Duplicate `.env.template` and rename it to `.env.local`. +6. Add proper store values to `.env.local`. +7. Run `yarn dev` to build and watch for code changes +8. The development branch is `canary` (this is the branch pull requests should be made against). + On a release, `canary` branch is rebased into `master`. + ## Troubleshoot
@@ -57,6 +154,7 @@ BIGCOMMERCE_STOREFRONT_API_TOKEN=<> BIGCOMMERCE_STORE_API_URL=<> BIGCOMMERCE_STORE_API_TOKEN=<> BIGCOMMERCE_STORE_API_CLIENT_ID=<> +BIGCOMMERCE_CHANNEL_ID=<> ``` If your project was started with a "Deploy with Vercel" button, you can use Vercel's CLI to retrieve these credentials. @@ -77,22 +175,3 @@ After Email confirmation, Checkout should be manually enabled through BigCommerc
BigCommerce team has been notified and they plan to add more detailed about this subject.
- -## Contribute - -Our commitment to Open Source can be found [here](https://vercel.com/oss). - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. -2. Create a new branch `git checkout -b MY_BRANCH_NAME` -3. Install yarn: `npm install -g yarn` -4. Install the dependencies: `yarn` -5. Duplicate `.env.template` and rename it to `.env.local`. -6. Add proper store values to `.env.local`. -7. Run `yarn dev` to build and watch for code changes -8. The development branch is `canary` (this is the branch pull requests should be made against). - On a release, `canary` branch is rebased into `master`. - - - - - diff --git a/commerce.config.json b/commerce.config.json new file mode 100644 index 000000000..bef7db222 --- /dev/null +++ b/commerce.config.json @@ -0,0 +1,7 @@ +{ + "provider": "bigcommerce", + "features": { + "wishlist": true, + "customCheckout": false + } +} diff --git a/components/auth/LoginView.tsx b/components/auth/LoginView.tsx index 9102a53c6..89d5bf893 100644 --- a/components/auth/LoginView.tsx +++ b/components/auth/LoginView.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState, useCallback } from 'react' import { Logo, Button, Input } from '@components/ui' -import useLogin from '@framework/use-login' +import useLogin from '@framework/auth/use-login' import { useUI } from '@components/ui/context' import { validate } from 'email-validator' diff --git a/components/auth/SignUpView.tsx b/components/auth/SignUpView.tsx index c49637d47..1b619828b 100644 --- a/components/auth/SignUpView.tsx +++ b/components/auth/SignUpView.tsx @@ -3,7 +3,7 @@ import { validate } from 'email-validator' import { Info } from '@components/icons' import { useUI } from '@components/ui/context' import { Logo, Button, Input } from '@components/ui' -import useSignup from '@framework/use-signup' +import useSignup from '@framework/auth/use-signup' interface Props {} diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 2769ac715..cb7f8600e 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -2,43 +2,51 @@ import { ChangeEvent, useEffect, useState } from 'react' import cn from 'classnames' import Image from 'next/image' import Link from 'next/link' +import s from './CartItem.module.css' import { Trash, Plus, Minus } from '@components/icons' -import usePrice from '@framework/use-price' +import { useUI } from '@components/ui/context' +import type { LineItem } from '@framework/types' +import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' -import s from './CartItem.module.css' type ItemOption = { - name: string, - nameId: number, - value: string, + name: string + nameId: number + value: string valueId: number } const CartItem = ({ item, currencyCode, + ...rest }: { - item: any + item: LineItem currencyCode: string }) => { + const { closeSidebarIfPresent } = useUI() + const { price } = usePrice({ - amount: item.extended_sale_price, - baseAmount: item.extended_list_price, + amount: item.variant.price * item.quantity, + baseAmount: item.variant.listPrice * item.quantity, currencyCode, }) - const updateItem = useUpdateItem(item) + + const updateItem = useUpdateItem({ item }) const removeItem = useRemoveItem() const [quantity, setQuantity] = useState(item.quantity) const [removing, setRemoving] = useState(false) + const updateQuantity = async (val: number) => { await updateItem({ quantity: val }) } + const handleQuantity = (e: ChangeEvent) => { const val = Number(e.target.value) if (Number.isInteger(val) && val >= 0) { - setQuantity(e.target.value) + setQuantity(Number(e.target.value)) } } const handleBlur = () => { @@ -62,11 +70,13 @@ const CartItem = ({ try { // If this action succeeds then there's no need to do `setRemoving(true)` // because the component will be removed from the view - await removeItem({ id: item.id }) + await removeItem(item) } catch (error) { setRemoving(false) } } + // TODO: Add a type for this + const options = (item as any).options useEffect(() => { // Reset the quantity state if the item quantity changes @@ -80,32 +90,38 @@ const CartItem = ({ className={cn('flex flex-row space-x-8 py-8', { 'opacity-75 pointer-events-none': removing, })} + {...rest} >
Product Image
- {/** TODO: Replace this. No `path` found at Cart */} - - + + closeSidebarIfPresent()} + > {item.name} - {item.options && item.options.length > 0 ? ( + {options && options.length > 0 ? (
- {item.options.map((option:ItemOption, i: number) => - - {option.value}{ i === item.options.length -1 ? "" : ", " } + {options.map((option: ItemOption, i: number) => ( + + {option.value} + {i === options.length - 1 ? '' : ', '} - )} + ))}
) : null}
@@ -130,7 +146,10 @@ const CartItem = ({
{price} -
diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index eb76c5da5..326390327 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -1,42 +1,40 @@ import { FC } from 'react' import cn from 'classnames' -import { UserNav } from '@components/common' -import { Button } from '@components/ui' -import { Bag, Cross, Check } from '@components/icons' -import { useUI } from '@components/ui/context' -import useCart from '@framework/cart/use-cart' -import usePrice from '@framework/use-price' +import Link from 'next/link' import CartItem from '../CartItem' import s from './CartSidebarView.module.css' +import { Button } from '@components/ui' +import { UserNav } from '@components/common' +import { useUI } from '@components/ui/context' +import { Bag, Cross, Check } from '@components/icons' +import useCart from '@framework/cart/use-cart' +import usePrice from '@framework/product/use-price' const CartSidebarView: FC = () => { const { closeSidebar } = useUI() - const { data, isEmpty } = useCart() + const { data, isLoading, isEmpty } = useCart() + const { price: subTotal } = usePrice( data && { - amount: data.base_amount, + amount: Number(data.subtotalPrice), currencyCode: data.currency.code, } ) const { price: total } = usePrice( data && { - amount: data.cart_amount, + amount: Number(data.totalPrice), currencyCode: data.currency.code, } ) const handleClose = () => closeSidebar() - const items = data?.line_items.physical_items ?? [] - const error = null const success = null return (
@@ -51,12 +49,12 @@ const CartSidebarView: FC = () => {
- +
- {isEmpty ? ( + {isLoading || isEmpty ? (
@@ -90,15 +88,20 @@ const CartSidebarView: FC = () => { ) : ( <>
-

- My Cart -

+ +

+ My Cart +

+
    - {items.map((item: any) => ( + {data!.lineItems.map((item: any) => ( ))}
diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index c90b4886f..75b2806ef 100644 --- a/components/common/Footer/Footer.tsx +++ b/components/common/Footer/Footer.tsx @@ -2,7 +2,7 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' import { useRouter } from 'next/router' -import type { Page } from '@framework/api/operations/get-all-pages' +import type { Page } from '@framework/common/get-all-pages' import getSlug from '@lib/get-slug' import { Github, Vercel } from '@components/icons' import { Logo, Container } from '@components/ui' diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index f19e1586a..423048f75 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -1,5 +1,6 @@ import { FC } from 'react' import Link from 'next/link' +import type { Product } from '@commerce/types' import { Grid } from '@components/ui' import { ProductCard } from '@components/product' import s from './HomeAllProductsGrid.module.css' @@ -8,10 +9,14 @@ import { getCategoryPath, getDesignerPath } from '@lib/search' interface Props { categories?: any brands?: any - newestProducts?: any + products?: Product[] } -const Head: FC = ({ categories, brands, newestProducts }) => { +const HomeAllProductsGrid: FC = ({ + categories, + brands, + products = [], +}) => { return (
@@ -48,13 +53,15 @@ const Head: FC = ({ categories, brands, newestProducts }) => {
- {newestProducts.map(({ node }: any) => ( + {products.map((product) => ( ))} @@ -63,4 +70,4 @@ const Head: FC = ({ categories, brands, newestProducts }) => { ) } -export default Head +export default HomeAllProductsGrid diff --git a/components/common/I18nWidget/I18nWidget.tsx b/components/common/I18nWidget/I18nWidget.tsx index 9bfc7b63c..fbe67a4c1 100644 --- a/components/common/I18nWidget/I18nWidget.tsx +++ b/components/common/I18nWidget/I18nWidget.tsx @@ -43,7 +43,7 @@ const I18nWidget: FC = () => { const currentLocale = locale || defaultLocale return ( - setDisplay(false)} > + setDisplay(false)}>
-
- +
+
- -
- ) -} + +
+ +
+
+ +
+ +
+ + +) export default Navbar diff --git a/components/common/Navbar/NavbarRoot.tsx b/components/common/Navbar/NavbarRoot.tsx new file mode 100644 index 000000000..2eb8c5429 --- /dev/null +++ b/components/common/Navbar/NavbarRoot.tsx @@ -0,0 +1,33 @@ +import { FC, useState, useEffect } from 'react' +import throttle from 'lodash.throttle' +import cn from 'classnames' +import s from './Navbar.module.css' + +const NavbarRoot: FC = ({ children }) => { + const [hasScrolled, setHasScrolled] = useState(false) + + useEffect(() => { + const handleScroll = throttle(() => { + const offset = 0 + const { scrollTop } = document.documentElement + const scrolled = scrollTop > offset + + if (hasScrolled !== scrolled) { + setHasScrolled(scrolled) + } + }, 200) + + document.addEventListener('scroll', handleScroll) + return () => { + document.removeEventListener('scroll', handleScroll) + } + }, [hasScrolled]) + + return ( +
+ {children} +
+ ) +} + +export default NavbarRoot diff --git a/components/common/UserNav/DropdownMenu.tsx b/components/common/UserNav/DropdownMenu.tsx index 7b02c863a..43f842009 100644 --- a/components/common/UserNav/DropdownMenu.tsx +++ b/components/common/UserNav/DropdownMenu.tsx @@ -8,6 +8,7 @@ import { Avatar } from '@components/common' import { Moon, Sun } from '@components/icons' import { useUI } from '@components/ui/context' import ClickOutside from '@lib/click-outside' +import useLogout from '@framework/auth/use-logout' import { disableBodyScroll, @@ -15,8 +16,6 @@ import { clearAllBodyScrollLocks, } from 'body-scroll-lock' -import useLogout from '@framework/use-logout' - interface DropdownMenuProps { open?: boolean } diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 31852f658..4d00970a9 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -1,27 +1,26 @@ import { FC } from 'react' import Link from 'next/link' import cn from 'classnames' +import type { LineItem } from '@framework/types' import useCart from '@framework/cart/use-cart' -import useCustomer from '@framework/use-customer' +import useCustomer from '@framework/customer/use-customer' +import { Avatar } from '@components/common' import { Heart, Bag } from '@components/icons' import { useUI } from '@components/ui/context' import DropdownMenu from './DropdownMenu' import s from './UserNav.module.css' -import { Avatar } from '@components/common' interface Props { className?: string } -const countItem = (count: number, item: any) => count + item.quantity -const countItems = (count: number, items: any[]) => - items.reduce(countItem, count) +const countItem = (count: number, item: LineItem) => count + item.quantity -const UserNav: FC = ({ className, children, ...props }) => { +const UserNav: FC = ({ className }) => { const { data } = useCart() const { data: customer } = useCustomer() const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI() - const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0) + const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0 return (