diff --git a/.changeset/green-flowers-double.md b/.changeset/green-flowers-double.md index 0ccb611a33..9db781ada7 100644 --- a/.changeset/green-flowers-double.md +++ b/.changeset/green-flowers-double.md @@ -2,4 +2,4 @@ '@graphcommerce/react-hook-form': patch --- -When a useFormGql throws an error in the onBeforeSubmit method or onComplete method it will setError('root.thrown') with the message, allowing it to be displayed somewhere. PaymentMethodButton will now render this as an ErrorSnackbar. +When a useFormGql throws an error in the onBeforeSubmit method or onComplete method it will be set as an ApolloError with the message, allowing it to be displayed somewhere. PaymentMethodButton will now render this as an ErrorSnackbar. diff --git a/.changeset/popular-rules-complain.md b/.changeset/popular-rules-complain.md new file mode 100644 index 0000000000..d2c4af0366 --- /dev/null +++ b/.changeset/popular-rules-complain.md @@ -0,0 +1,9 @@ +--- +'@graphcommerce/ecommerce-ui': minor +'@graphcommerce/magento-cart-email': minor +'@graphcommerce/magento-customer': minor +'@graphcommerce/magento-cart': minor +'@graphcommerce/magento-graphcms': minor +--- + +Add `permissions` config so the website or store can be configurated to run in different modes. diff --git a/docs/framework/config.md b/docs/framework/config.md index 223cdf4dc5..255539f40a 100644 --- a/docs/framework/config.md +++ b/docs/framework/config.md @@ -290,6 +290,10 @@ Limit the static generation of SSG when building. By default GraphCommerce will statically generate all product and category pages during build. This can take quite a long time, to skip this step set this value to true. +#### permissions: [GraphCommercePermissions](#GraphCommercePermissions) + +Allows the option to require login or completely disable certain sections of the site, can be overriden per storeview with the storefrontConfig + #### previewSecret: string To enable next.js' preview mode, configure the secret you'd like to use. @@ -366,6 +370,22 @@ Issues that this can cause are: - The same package is included multiple times in the bundle, increasing the bundle size. - The Typescript types of the package are not compatible with each other, causing Typescript errors. +### GraphCommercePermissions + +#### cart: CUSTOMER_ONLY | DISABLED | ENABLED + +Changes the availability of the add to cart buttons and the cart page to either customer only or completely disables it. + +#### checkout: CUSTOMER_ONLY | DISABLED | ENABLED + +Changes the availability of the checkout to either customer only or completely disables it. + +#### customerAccount: DISABLED | DISABLE_REGISTRATION | ENABLED + +Enables / disabled the account section of the website. DISABLE_REGISTRATION will only disable the registration page. + +#### website: ENABLED + ### GraphCommerceStorefrontConfig All storefront configuration for the project @@ -438,6 +458,10 @@ Add a gcms-locales header to make sure queries return in a certain language, can Custom locale used to load the .po files. Must be a valid locale, also used for Intl functions. +#### permissions: [GraphCommercePermissions](#GraphCommercePermissions) + +Allows the option to require login or completely disable certain sections of the site on a per store basis + #### robotsAllow: boolean Allow the site to be indexed by search engines. diff --git a/examples/magento-graphcms/components/Layout/Footer.tsx b/examples/magento-graphcms/components/Layout/Footer.tsx index b157d67790..232a416dd4 100644 --- a/examples/magento-graphcms/components/Layout/Footer.tsx +++ b/examples/magento-graphcms/components/Layout/Footer.tsx @@ -1,4 +1,5 @@ import { Image } from '@graphcommerce/image' +import { useCheckoutGuestEnabled } from '@graphcommerce/magento-cart' import { StoreSwitcherButton } from '@graphcommerce/magento-store' import { Footer as FooterBase } from '@graphcommerce/next-ui' import { Trans } from '@lingui/macro' @@ -9,6 +10,7 @@ export type FooterProps = FooterQueryFragment export function Footer(props: FooterProps) { const { footer } = props + const cartEnabled = useCheckoutGuestEnabled() return ( ))} - {import.meta.graphCommerce.magentoVersion >= 247 && ( + {import.meta.graphCommerce.magentoVersion >= 247 && cartEnabled && ( Order status diff --git a/examples/magento-graphcms/components/Layout/LayoutNavigation.tsx b/examples/magento-graphcms/components/Layout/LayoutNavigation.tsx index ffb3e64e58..b5466e3c33 100644 --- a/examples/magento-graphcms/components/Layout/LayoutNavigation.tsx +++ b/examples/magento-graphcms/components/Layout/LayoutNavigation.tsx @@ -1,4 +1,4 @@ -import { CartFab } from '@graphcommerce/magento-cart' +import { CartFab, useCartEnabled } from '@graphcommerce/magento-cart' import { magentoMenuToNavigation } from '@graphcommerce/magento-category' import { CustomerFab, CustomerMenuFabItem } from '@graphcommerce/magento-customer' import { ProductFiltersProSearchField, SearchLink } from '@graphcommerce/magento-search' @@ -39,6 +39,8 @@ export function LayoutNavigation(props: LayoutNavigationProps) { const selection = useNavigationSelection() const router = useRouter() + const cartEnabled = useCartEnabled() + return ( <> } /> {/* The placeholder exists because the CartFab is sticky but we want to reserve the space for the */} - + {cartEnabled && } } diff --git a/examples/magento-graphcms/components/ProductView/AddProductsToCartView.tsx b/examples/magento-graphcms/components/ProductView/AddProductsToCartView.tsx index 2474534cf5..6cf7dbc41d 100644 --- a/examples/magento-graphcms/components/ProductView/AddProductsToCartView.tsx +++ b/examples/magento-graphcms/components/ProductView/AddProductsToCartView.tsx @@ -1,3 +1,4 @@ +import { useCartEnabled } from '@graphcommerce/magento-cart' import { AddProductsToCartError, AddProductsToCartQuantity, @@ -21,6 +22,7 @@ export type AddProductsToCartViewProps = { export function AddProductsToCartView(props: AddProductsToCartViewProps) { const { product } = props + const cartEnabled = useCartEnabled() return ( <> @@ -39,9 +41,8 @@ export function AddProductsToCartView(props: AddProductsToCartViewProps) { <> - - + {cartEnabled && } @@ -49,10 +50,8 @@ export function AddProductsToCartView(props: AddProductsToCartViewProps) { - - - + {cartEnabled && } )} diff --git a/examples/magento-graphcms/locales/de.po b/examples/magento-graphcms/locales/de.po index 2014d07020..250a564d5b 100644 --- a/examples/magento-graphcms/locales/de.po +++ b/examples/magento-graphcms/locales/de.po @@ -161,6 +161,10 @@ msgstr "Kategorien" msgid "Order #{orderNumber}" msgstr "Bestellung #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "Sie müssen sich zuerst anmelden, bevor Sie fortfahren können" + msgid "Change" msgstr "Ändern" @@ -611,6 +615,10 @@ msgstr "Produkt nicht verfügbar in {allLabels}" msgid "Products" msgstr "Produkte" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "Bei der Bearbeitung Ihrer Zahlung ist ein Fehler aufgetreten. Bitte kontaktieren Sie den Ladenbesitzer" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Ergebnisse für ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Ergebnisse für ‘{search}’" msgid "Telephone" msgstr "Telefon" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Bitte loggen Sie sich ein, um Produkte zu Ihrem Warenkorb hinzuzufügen" + msgid "Recently viewed products" msgstr "Kürzlich angesehene Produkte" @@ -715,11 +727,14 @@ msgstr "Abmelden" msgid "Sign up for our newsletter and stay updated" msgstr "Abonnieren Sie unseren Newsletter und bleiben Sie auf dem Laufenden" +msgid "Sign up is disabled, please contact us for more information." +msgstr "Die Anmeldung ist deaktiviert, bitte kontaktieren Sie uns für weitere Informationen." + msgid "Skip to main content" msgstr "Zum Hauptinhalt springen" msgid "Some items in your cart contain errors, please update or remove them, then try again." -msgstr "Einige Artikel im Warenkorb enthalten Fehler, bitte aktualisieren oder entfernen Sie diese, und versuchen Sie es erneut." +msgstr "Einige Artikel in Ihrem Warenkorb enthalten Fehler, bitte aktualisieren oder entfernen Sie sie, und versuchen Sie es erneut." msgid "Something went wrong" msgstr "Etwas ist schief gelaufen" @@ -799,9 +814,6 @@ msgstr "Die Zahlung wurde abgelehnt, bitte versuchen Sie es erneut oder wählen msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "Es gibt maximal '{maxLength}' Zeichen" -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "Dieser Warenkorb ist {email} zugewiesen. Bitte melden Sie sich an, um mit dem Einkauf fortzufahren." - msgid "This field is invalid" msgstr "Dieses Feld ist ungültig" @@ -922,6 +934,9 @@ msgstr "Sie müssen zustimmen, um fortfahren zu können" msgid "You haven't placed any reviews yet" msgstr "Sie haben noch keine Bewertungen abgegeben" +msgid "You must be signed in to continue" +msgstr "Sie müssen sich anmelden, um fortzufahren" + msgid "You must sign in to continue" msgstr "Sie müssen sich anmelden, um fortzufahren" @@ -1025,6 +1040,10 @@ msgstr "Auftrag erhalten" msgid "one product" msgstr "ein Produkt" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Zur Kasse gehen" + #. js-lingui-generated-id msgid "Order not found" msgstr "Bestellung nicht gefunden" @@ -1049,6 +1068,10 @@ msgstr "Die angegebene E-Mail-Adresse stimmt nicht mit der Kontoe-Mail-Adresse msgid "Message" msgstr "Nachricht" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Einige Artikel im Warenkorb enthalten Fehler, bitte aktualisieren oder entfernen Sie diese, und versuchen Sie es erneut." + #. js-lingui-generated-id msgid "Order details" msgstr "Details zur Bestellung" diff --git a/examples/magento-graphcms/locales/en.po b/examples/magento-graphcms/locales/en.po index 2e044a286b..34ddd9ce93 100644 --- a/examples/magento-graphcms/locales/en.po +++ b/examples/magento-graphcms/locales/en.po @@ -161,6 +161,10 @@ msgstr "Categories" msgid "Order #{orderNumber}" msgstr "Order #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "You must first login before you can continue" + msgid "Change" msgstr "Change" @@ -611,6 +615,10 @@ msgstr "Product not available in {allLabels}" msgid "Products" msgstr "Products" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "An error occurred while processing your payment. Please contact the store owner" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Results for ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Results for ‘{search}’" msgid "Telephone" msgstr "Telephone" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Please login to add products to your cart" + msgid "Recently viewed products" msgstr "Recently viewed products" @@ -715,6 +727,9 @@ msgstr "Sign out" msgid "Sign up for our newsletter and stay updated" msgstr "Sign up for our newsletter and stay updated" +msgid "Sign up is disabled, please contact us for more information." +msgstr "Sign up is disabled, please contact us for more information." + msgid "Skip to main content" msgstr "Skip to main content" @@ -799,9 +814,6 @@ msgstr "The payment is refused, please try again or select a different payment m msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "There is a maximum of ‘{maxLength}’ characters" -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "This cart is assigned to {email}. Please sign in to continue shopping." - msgid "This field is invalid" msgstr "This field is invalid" @@ -922,6 +934,9 @@ msgstr "You have to agree in order to proceed" msgid "You haven't placed any reviews yet" msgstr "You haven't placed any reviews yet" +msgid "You must be signed in to continue" +msgstr "You must be signed in to continue" + msgid "You must sign in to continue" msgstr "You must sign in to continue" @@ -1025,6 +1040,10 @@ msgstr "Get order" msgid "one product" msgstr "one product" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Start Checkout" + #. js-lingui-generated-id msgid "Order not found" msgstr "Order not found" @@ -1049,6 +1068,10 @@ msgstr "The given email does not match the account email" msgid "Message" msgstr "Message" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Some items in your cart contain errors, please update or remove them, then try again." + #. js-lingui-generated-id msgid "Order details" msgstr "Order details" diff --git a/examples/magento-graphcms/locales/es.po b/examples/magento-graphcms/locales/es.po index 40863702c2..0e41c58c0e 100644 --- a/examples/magento-graphcms/locales/es.po +++ b/examples/magento-graphcms/locales/es.po @@ -161,6 +161,10 @@ msgstr "Categorías" msgid "Order #{orderNumber}" msgstr "Pedido #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "Debe iniciar sesión antes de continuar" + msgid "Change" msgstr "Cambiar" @@ -611,6 +615,10 @@ msgstr "Producto no disponible en {allLabels}" msgid "Products" msgstr "Productos" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "Se ha producido un error al procesar su pago. Póngase en contacto con el propietario de la tienda" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Resultados para ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Resultados para ‘{search}’" msgid "Telephone" msgstr "Teléfono" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Inicie sesión para añadir productos a su cesta" + msgid "Recently viewed products" msgstr "Productos vistos recientemente" @@ -715,11 +727,14 @@ msgstr "Cerrar sesión" msgid "Sign up for our newsletter and stay updated" msgstr "Regístrese para nuestro boletín y manténgase actualizado" +msgid "Sign up is disabled, please contact us for more information." +msgstr "La inscripción está deshabilitada, póngase en contacto con nosotros para obtener más información." + msgid "Skip to main content" msgstr "Saltar al contenido principal" msgid "Some items in your cart contain errors, please update or remove them, then try again." -msgstr "Algunos artículos de su carrito contienen errores, actualícelos o elimínelos y vuelva a intentarlo." +msgstr "Algunos artículos en su carrito contienen errores, por favor actualice o elimine ellos, y luego intente de nuevo." msgid "Something went wrong" msgstr "Algo salió mal" @@ -799,9 +814,6 @@ msgstr "El pago se ha rechazado, inténtelo de nuevo o seleccione un método de msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "Hay un máximo de caracteres '{maxLength}'" -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "Este carrito está asignado a {email}. Inicie sesión para continuar comprando." - msgid "This field is invalid" msgstr "Este campo es inválido" @@ -922,6 +934,9 @@ msgstr "Debe aceptar para proceder" msgid "You haven't placed any reviews yet" msgstr "Aún no ha escrito ningún comentario" +msgid "You must be signed in to continue" +msgstr "Debe iniciar sesión para continuar" + msgid "You must sign in to continue" msgstr "Debe iniciar sesión para continuar" @@ -1025,6 +1040,10 @@ msgstr "Obtener pedido" msgid "one product" msgstr "un producto" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Iniciar compra" + #. js-lingui-generated-id msgid "Order not found" msgstr "Pedido no encontrado" @@ -1049,6 +1068,10 @@ msgstr "El correo electrónico proporcionado no coincide con el correo electrón msgid "Message" msgstr "Mensaje" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Algunos artículos de su carrito contienen errores, actualícelos o elimínelos y vuelva a intentarlo." + #. js-lingui-generated-id msgid "Order details" msgstr "Detalles del pedido" diff --git a/examples/magento-graphcms/locales/fr.po b/examples/magento-graphcms/locales/fr.po index 711a859db3..3e89a55472 100644 --- a/examples/magento-graphcms/locales/fr.po +++ b/examples/magento-graphcms/locales/fr.po @@ -161,6 +161,10 @@ msgstr "Catégories" msgid "Order #{orderNumber}" msgstr "Commande #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "Vous devez d'abord vous connecter avant de pouvoir continuer" + msgid "Change" msgstr "Changer" @@ -611,6 +615,10 @@ msgstr "Produit non disponible dans {allLabels}" msgid "Products" msgstr "Produits" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "Se ha producido un error al procesar su pago. Póngase en contacto con el propietario de la tienda" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Résultats pour ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Résultats pour ‘{search}’" msgid "Telephone" msgstr "Téléphone" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Veuillez vous connecter pour ajouter des produits à votre panier" + msgid "Recently viewed products" msgstr "Derniers produits consultés" @@ -715,6 +727,9 @@ msgstr "Déconnexion" msgid "Sign up for our newsletter and stay updated" msgstr "Inscrivez-vous à notre newsletter et restez à jour" +msgid "Sign up is disabled, please contact us for more information." +msgstr "L'inscription est désactivée, veuillez nous contacter pour plus d'informations." + msgid "Skip to main content" msgstr "Passer au contenu principal" @@ -799,9 +814,6 @@ msgstr "Le paiement est refusé, veuillez réessayer ou sélectionner une autre msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "Il y a un maximum de caractères '{maxLength}'" -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "Ce panier est assigné à {email}. Veuillez vous connecter pour continuer vos achats." - msgid "This field is invalid" msgstr "Ce champ est invalide" @@ -922,6 +934,9 @@ msgstr "Vous devez accepter pour continuer" msgid "You haven't placed any reviews yet" msgstr "Vous n'avez pas encore écrit d'évaluation" +msgid "You must be signed in to continue" +msgstr "Vous devez vous connecter pour continuer" + msgid "You must sign in to continue" msgstr "Vous devez vous connecter pour continuer" @@ -1025,6 +1040,10 @@ msgstr "Obtenir une commande" msgid "one product" msgstr "un produit" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Commencer la commande" + #. js-lingui-generated-id msgid "Order not found" msgstr "Ordre non trouvé" @@ -1049,6 +1068,10 @@ msgstr "L'email donné ne correspond pas à l'email du compte" msgid "Message" msgstr "Message" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Certains articles de votre panier contiennent des erreurs, veuillez les mettre à jour ou les supprimer, puis réessayer." + #. js-lingui-generated-id msgid "Order details" msgstr "Détails de la commande" diff --git a/examples/magento-graphcms/locales/it.po b/examples/magento-graphcms/locales/it.po index cf6bc7924c..702047e54d 100644 --- a/examples/magento-graphcms/locales/it.po +++ b/examples/magento-graphcms/locales/it.po @@ -161,6 +161,10 @@ msgstr "Categorie" msgid "Order #{orderNumber}" msgstr "Ordine #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "Per poter continuare è necessario effettuare il login" + msgid "Change" msgstr "Cambia" @@ -611,6 +615,10 @@ msgstr "Prodotto non disponibile in {allLabels}" msgid "Products" msgstr "Prodotti" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "Si è verificato un errore durante il processo di pagamento. Si prega di contattare il proprietario del negozio" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Risultati per ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Risultati per ‘{search}’" msgid "Telephone" msgstr "Telefono" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Effettuare il login per aggiungere prodotti al carrello" + msgid "Recently viewed products" msgstr "Prodotti visionati recentemente" @@ -715,11 +727,14 @@ msgstr "Esci" msgid "Sign up for our newsletter and stay updated" msgstr "Iscriviti alla nostra newsletter e rimani aggiornato" +msgid "Sign up is disabled, please contact us for more information." +msgstr "L'iscrizione è disabilitata, contattateci per maggiori informazioni." + msgid "Skip to main content" msgstr "Passa al contenuto principale" msgid "Some items in your cart contain errors, please update or remove them, then try again." -msgstr "Alcuni articoli nel tuo carrello contengono errori, aggiorna o rimuovi e riprova." +msgstr "Alcuni articoli nel tuo carrello contengono errori, per favore aggiorna o rimuovi, poi riprova." msgid "Something went wrong" msgstr "Qualcosa è andato storto" @@ -734,7 +749,7 @@ msgid "Sort By" msgstr "Ordina per" msgid "Start Checkout" -msgstr "Inizia checkout" +msgstr "Inizia la checkout" msgid "Store home" msgstr "Home del negozio" @@ -799,9 +814,6 @@ msgstr "Il pagamento è stato rifiutato, riprova o seleziona un metodo di pagame msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "È consentito un massimo di caratteri \"{maxLength}\"." -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "Questo carrello è assegnato a {email}. Accedi per continuare gli acquisti." - msgid "This field is invalid" msgstr "Questo campo non è valido" @@ -922,9 +934,12 @@ msgstr "Devi accettare per procedere" msgid "You haven't placed any reviews yet" msgstr "Non hai ancora scritto nessuna recensione" -msgid "You must sign in to continue" +msgid "You must be signed in to continue" msgstr "Devi accedere per continuare" +msgid "You must sign in to continue" +msgstr "È necessario effettuare l'accesso per continuare" + msgid "Your address has been added" msgstr "Il tuo indirizzo è stato aggiunto" @@ -1025,6 +1040,10 @@ msgstr "Ottenere l'ordine" msgid "one product" msgstr "un prodotto" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Inizia checkout" + #. js-lingui-generated-id msgid "Order not found" msgstr "Ordine non trovato" @@ -1049,6 +1068,10 @@ msgstr "L'email fornita non corrisponde all'email dell'account" msgid "Message" msgstr "Messaggio" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Alcuni articoli nel tuo carrello contengono errori, aggiorna o rimuovi e riprova." + #. js-lingui-generated-id msgid "Order details" msgstr "Dettagli dell'ordine" diff --git a/examples/magento-graphcms/locales/nl.po b/examples/magento-graphcms/locales/nl.po index 182029e713..93c9c01c3e 100644 --- a/examples/magento-graphcms/locales/nl.po +++ b/examples/magento-graphcms/locales/nl.po @@ -161,6 +161,10 @@ msgstr "Categorieën" msgid "Order #{orderNumber}" msgstr "Bestelling #{orderNumber}" +#. js-lingui-generated-id +msgid "You must first login before you can continue" +msgstr "U moet eerst inloggen voordat u verder kunt gaan" + msgid "Change" msgstr "Wijzig" @@ -611,6 +615,10 @@ msgstr "Product niet beschikbaar in {allLabels}" msgid "Products" msgstr "Producten" +#. js-lingui-generated-id +msgid "An error occurred while processing your payment. Please contact the store owner" +msgstr "Er is een fout opgetreden bij het verwerken van uw betaling. Neem contact op met de eigenaar van de winkel" + #. js-lingui-generated-id msgid "Results for ‘{search}’" msgstr "Resultaten voor ‘{search}’" @@ -619,6 +627,10 @@ msgstr "Resultaten voor ‘{search}’" msgid "Telephone" msgstr "Telefoon" +#. js-lingui-generated-id +msgid "Please login to add products to your cart" +msgstr "Log in om producten aan uw winkelwagen toe te voegen" + msgid "Recently viewed products" msgstr "Recent bekeken producten" @@ -715,11 +727,14 @@ msgstr "Uitloggen" msgid "Sign up for our newsletter and stay updated" msgstr "Abonneer u op onze nieuwsbrief en blijf op de hoogte" +msgid "Sign up is disabled, please contact us for more information." +msgstr "Inschrijven is niet mogelijk, neem contact met ons op voor meer informatie." + msgid "Skip to main content" msgstr "Ga naar hoofdinhoud" msgid "Some items in your cart contain errors, please update or remove them, then try again." -msgstr "Sommige items in uw winkelwagen bevatten fouten, pas deze aan of verwijder ze en probeer het opnieuw." +msgstr "Sommige artikelen in uw winkelwagen bevatten fouten, update of verwijder ze, en probeer het opnieuw." msgid "Something went wrong" msgstr "Er is iets misgegaan" @@ -734,7 +749,7 @@ msgid "Sort By" msgstr "Sorteer op" msgid "Start Checkout" -msgstr "Afrekenen" +msgstr "Start afrekenen" msgid "Store home" msgstr "Winkel home" @@ -799,9 +814,6 @@ msgstr "De betaling is geweigerd, probeer het opnieuw of selecteer een andere be msgid "There is a maximum of ‘{maxLength}’ characters" msgstr "Er is een maximum van ‘{maxLength}’ karakters" -msgid "This cart is assigned to {email}. Please sign in to continue shopping." -msgstr "Deze winkelwagen is toegewezen aan {email}. Log in om verder te winkelen." - msgid "This field is invalid" msgstr "Dit veld is ongeldig" @@ -922,8 +934,11 @@ msgstr "U moet akkoord gaan met de voorwaarden om verder te gaan" msgid "You haven't placed any reviews yet" msgstr "Je hebt nog geen reviews geplaatst" +msgid "You must be signed in to continue" +msgstr "U moet ingelogd zijn om verder te gaan" + msgid "You must sign in to continue" -msgstr "U moet inloggen om verder te gaan" +msgstr "U moet zich aanmelden om verder te gaan" msgid "Your address has been added" msgstr "Uw adres is toegevoegd" @@ -1025,6 +1040,10 @@ msgstr "Bestelling belijken" msgid "one product" msgstr "één product" +#. js-lingui-generated-id +msgid "Start Checkout" +msgstr "Afrekenen" + #. js-lingui-generated-id msgid "Order not found" msgstr "Bestelling niet gevonden" @@ -1049,6 +1068,10 @@ msgstr "Het opgegeven e-mailadres komt niet overeen met het account e-mailadres" msgid "Message" msgstr "Bericht" +#. js-lingui-generated-id +msgid "Some items in your cart contain errors, please update or remove them, then try again." +msgstr "Sommige items in uw winkelwagen bevatten fouten, pas deze aan of verwijder ze en probeer het opnieuw." + #. js-lingui-generated-id msgid "Order details" msgstr "Bestelgegevens" diff --git a/examples/magento-graphcms/pages/404.tsx b/examples/magento-graphcms/pages/404.tsx index dcd182d117..a369c4b8d1 100644 --- a/examples/magento-graphcms/pages/404.tsx +++ b/examples/magento-graphcms/pages/404.tsx @@ -1,4 +1,6 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' +import { cacheFirst } from '@graphcommerce/graphql' +import { useCustomerAccountCanSignIn } from '@graphcommerce/magento-customer' import { SearchLink } from '@graphcommerce/magento-search' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, Separator, icon404, IconSvg } from '@graphcommerce/next-ui' @@ -8,21 +10,27 @@ import { Box, Container, Typography, Link } from '@mui/material' import React from 'react' import { LayoutDocument, LayoutNavigation, LayoutNavigationProps } from '../components' import { graphqlSsrClient, graphqlSharedClient } from '../lib/graphql/graphqlSsrClient' -import { cacheFirst } from '@graphcommerce/graphql' type Props = Record type GetPageStaticProps = GetStaticProps function RouteNotFoundPage() { + const canSignIn = useCustomerAccountCanSignIn() + const links = [ , - - - , ] + if (canSignIn) { + links.push( + + + , + ) + } + return ( <> diff --git a/examples/magento-graphcms/pages/account/addresses/add.tsx b/examples/magento-graphcms/pages/account/addresses/add.tsx index e0ee145134..5a328fa900 100644 --- a/examples/magento-graphcms/pages/account/addresses/add.tsx +++ b/examples/magento-graphcms/pages/account/addresses/add.tsx @@ -5,6 +5,7 @@ import { useCustomerQuery, WaitForCustomer, AccountDashboardAddressesQuery, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -60,6 +61,8 @@ AddNewAddressPage.pageOptions = pageOptions export default AddNewAddressPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/addresses/edit.tsx b/examples/magento-graphcms/pages/account/addresses/edit.tsx index 7761a008bb..1f98b34bfb 100644 --- a/examples/magento-graphcms/pages/account/addresses/edit.tsx +++ b/examples/magento-graphcms/pages/account/addresses/edit.tsx @@ -4,6 +4,7 @@ import { useCustomerQuery, WaitForCustomer, AccountDashboardAddressesDocument, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -75,6 +76,8 @@ EditAddressPage.pageOptions = pageOptions export default EditAddressPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/addresses/index.tsx b/examples/magento-graphcms/pages/account/addresses/index.tsx index e42e3fecd0..4dc08c9172 100644 --- a/examples/magento-graphcms/pages/account/addresses/index.tsx +++ b/examples/magento-graphcms/pages/account/addresses/index.tsx @@ -4,6 +4,7 @@ import { useCustomerQuery, WaitForCustomer, AccountDashboardAddressesDocument, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { CountryRegionsDocument, PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -60,6 +61,8 @@ AccountAddressesPage.pageOptions = pageOptions export default AccountAddressesPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const staticClient = graphqlSsrClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/authentication/index.tsx b/examples/magento-graphcms/pages/account/authentication/index.tsx index 5a1692d51a..d07e3affda 100644 --- a/examples/magento-graphcms/pages/account/authentication/index.tsx +++ b/examples/magento-graphcms/pages/account/authentication/index.tsx @@ -1,5 +1,9 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { ChangePasswordForm, WaitForCustomer } from '@graphcommerce/magento-customer' +import { + ChangePasswordForm, + WaitForCustomer, + getCustomerAccountIsDisabled, +} from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, @@ -48,6 +52,8 @@ AccountAuthenticationPage.pageOptions = pageOptions export default AccountAuthenticationPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/contact/index.tsx b/examples/magento-graphcms/pages/account/contact/index.tsx index 1bfe1f7180..765848a542 100644 --- a/examples/magento-graphcms/pages/account/contact/index.tsx +++ b/examples/magento-graphcms/pages/account/contact/index.tsx @@ -1,6 +1,7 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' import { CustomerDocument, + getCustomerAccountIsDisabled, UpdateCustomerEmailForm, useCustomerQuery, WaitForCustomer, @@ -60,6 +61,8 @@ AccountContactPage.pageOptions = pageOptions export default AccountContactPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/delete/index.tsx b/examples/magento-graphcms/pages/account/delete/index.tsx index 41a21d6c35..7a4a7913ad 100644 --- a/examples/magento-graphcms/pages/account/delete/index.tsx +++ b/examples/magento-graphcms/pages/account/delete/index.tsx @@ -1,5 +1,5 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { AccountDeleteForm } from '@graphcommerce/magento-customer' +import { AccountDeleteForm, getCustomerAccountIsDisabled } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, LayoutOverlayHeader, LayoutTitle, iconBin } from '@graphcommerce/next-ui' import { Trans, t } from '@lingui/macro' @@ -39,14 +39,16 @@ AccountDeletePage.pageOptions = pageOptions export default AccountDeletePage export const getStaticProps: GetPageStaticProps = async (context) => { - const client = graphqlSharedClient(context) - const conf = client.query({ query: StoreConfigDocument }) if ( import.meta.graphCommerce.magentoVersion < 246 || - !import.meta.graphCommerce.customerDeleteEnabled + !import.meta.graphCommerce.customerDeleteEnabled || + getCustomerAccountIsDisabled(context.locale) ) return { notFound: true } + const client = graphqlSharedClient(context) + const conf = client.query({ query: StoreConfigDocument }) + return { props: { apolloState: await conf.then(() => client.cache.extract()), diff --git a/examples/magento-graphcms/pages/account/forgot-password.tsx b/examples/magento-graphcms/pages/account/forgot-password.tsx index f111ca33bc..8cadf06fbb 100644 --- a/examples/magento-graphcms/pages/account/forgot-password.tsx +++ b/examples/magento-graphcms/pages/account/forgot-password.tsx @@ -1,5 +1,5 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { ForgotPasswordForm } from '@graphcommerce/magento-customer' +import { ForgotPasswordForm, getCustomerAccountIsDisabled } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' import { i18n } from '@lingui/core' @@ -42,6 +42,8 @@ AccountForgotPasswordPage.pageOptions = pageOptions export default AccountForgotPasswordPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/index.tsx b/examples/magento-graphcms/pages/account/index.tsx index 7b4b32f1e5..d6d2193def 100644 --- a/examples/magento-graphcms/pages/account/index.tsx +++ b/examples/magento-graphcms/pages/account/index.tsx @@ -5,6 +5,7 @@ import { AccountMenu, AccountMenuItem, AddressSingleLine, + getCustomerAccountIsDisabled, OrderStateLabelInline, SignOutForm, useCustomerQuery, @@ -168,6 +169,8 @@ AccountIndexPage.pageOptions = pageOptions export default AccountIndexPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const staticClient = graphqlSsrClient(context) const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/name/index.tsx b/examples/magento-graphcms/pages/account/name/index.tsx index 4a52ad082b..8a250a5e90 100644 --- a/examples/magento-graphcms/pages/account/name/index.tsx +++ b/examples/magento-graphcms/pages/account/name/index.tsx @@ -2,6 +2,7 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' import { ChangeNameForm, CustomerDocument, + getCustomerAccountIsDisabled, useCustomerQuery, WaitForCustomer, } from '@graphcommerce/magento-customer' @@ -67,6 +68,8 @@ AccountNamePage.pageOptions = pageOptions export default AccountNamePage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/orders/index.tsx b/examples/magento-graphcms/pages/account/orders/index.tsx index ab880a859a..4cfc31f4fd 100644 --- a/examples/magento-graphcms/pages/account/orders/index.tsx +++ b/examples/magento-graphcms/pages/account/orders/index.tsx @@ -4,6 +4,7 @@ import { WaitForCustomer, AccountDashboardOrdersDocument, AccountOrders, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -77,6 +78,8 @@ AccountOrdersPage.pageOptions = pageOptions export default AccountOrdersPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/orders/view.tsx b/examples/magento-graphcms/pages/account/orders/view.tsx index ca54b5879f..b2b1ffe058 100644 --- a/examples/magento-graphcms/pages/account/orders/view.tsx +++ b/examples/magento-graphcms/pages/account/orders/view.tsx @@ -10,6 +10,7 @@ import { OrderStateLabel, ReorderItems, CancelOrderForm, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { CountryRegionsDocument, PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -94,6 +95,8 @@ OrderDetailPage.pageOptions = pageOptions export default OrderDetailPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const staticClient = graphqlSsrClient(context) const config = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/reviews/add.tsx b/examples/magento-graphcms/pages/account/reviews/add.tsx index a9b271d854..1680bc0079 100644 --- a/examples/magento-graphcms/pages/account/reviews/add.tsx +++ b/examples/magento-graphcms/pages/account/reviews/add.tsx @@ -1,6 +1,10 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' import { useQuery } from '@graphcommerce/graphql' -import { ApolloCustomerErrorFullPage, CustomerDocument } from '@graphcommerce/magento-customer' +import { + ApolloCustomerErrorFullPage, + CustomerDocument, + getCustomerAccountIsDisabled, +} from '@graphcommerce/magento-customer' import { ProductReviewProductNameDocument, CreateProductReviewForm, @@ -104,6 +108,8 @@ AccountReviewsAddPage.pageOptions = pageOptions export default AccountReviewsAddPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/reviews/index.tsx b/examples/magento-graphcms/pages/account/reviews/index.tsx index 9f9dac5263..35c12849f7 100644 --- a/examples/magento-graphcms/pages/account/reviews/index.tsx +++ b/examples/magento-graphcms/pages/account/reviews/index.tsx @@ -1,5 +1,9 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { useCustomerQuery, WaitForCustomer } from '@graphcommerce/magento-customer' +import { + getCustomerAccountIsDisabled, + useCustomerQuery, + WaitForCustomer, +} from '@graphcommerce/magento-customer' import { AccountDashboardReviewsDocument, AccountReviews } from '@graphcommerce/magento-review' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -71,6 +75,8 @@ AccountReviewsPage.pageOptions = pageOptions export default AccountReviewsPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/account/signin.tsx b/examples/magento-graphcms/pages/account/signin.tsx index 859d7582c2..0cb61e6a27 100644 --- a/examples/magento-graphcms/pages/account/signin.tsx +++ b/examples/magento-graphcms/pages/account/signin.tsx @@ -1,6 +1,5 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { useMergeCustomerCart } from '@graphcommerce/magento-cart' -import { AccountSignInUpForm } from '@graphcommerce/magento-customer' +import { AccountSignInUpForm, getCustomerAccountIsDisabled } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { useMergeGuestWishlistWithCustomer } from '@graphcommerce/magento-wishlist' import { GetStaticProps, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' @@ -13,7 +12,6 @@ import { graphqlSharedClient } from '../../lib/graphql/graphqlSsrClient' type GetPageStaticProps = GetStaticProps function AccountSignInPage() { - useMergeCustomerCart() useMergeGuestWishlistWithCustomer() return ( @@ -41,6 +39,8 @@ AccountSignInPage.pageOptions = pageOptions export default AccountSignInPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/cart.tsx b/examples/magento-graphcms/pages/cart.tsx index 955b15a9d3..e7eb790417 100644 --- a/examples/magento-graphcms/pages/cart.tsx +++ b/examples/magento-graphcms/pages/cart.tsx @@ -6,6 +6,7 @@ import { CartStartCheckoutLinkOrButton, CartTotals, EmptyCart, + getCartDisabled, useCartQuery, } from '@graphcommerce/magento-cart' import { CartPageDocument } from '@graphcommerce/magento-cart-checkout' @@ -88,7 +89,7 @@ function CartPage() { sx={(theme) => ({ mt: theme.spacings.md })} /> - + ) : ( @@ -116,6 +117,8 @@ CartPage.pageOptions = pageOptions export default CartPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCartDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/checkout/added.tsx b/examples/magento-graphcms/pages/checkout/added.tsx index 1e1373fe7c..6c1f07748c 100644 --- a/examples/magento-graphcms/pages/checkout/added.tsx +++ b/examples/magento-graphcms/pages/checkout/added.tsx @@ -1,6 +1,6 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' import { Image } from '@graphcommerce/image' -import { useCrosssellItems } from '@graphcommerce/magento-cart' +import { getCartDisabled, useCrosssellItems } from '@graphcommerce/magento-cart' import { AddProductsToCartForm, ProductScroller } from '@graphcommerce/magento-product' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -162,6 +162,8 @@ CheckoutAdded.pageOptions = pageOptions export default CheckoutAdded export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCartDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/checkout/customer/addresses/edit.tsx b/examples/magento-graphcms/pages/checkout/customer/addresses/edit.tsx index a9f2ceed37..f283eb238e 100644 --- a/examples/magento-graphcms/pages/checkout/customer/addresses/edit.tsx +++ b/examples/magento-graphcms/pages/checkout/customer/addresses/edit.tsx @@ -1,9 +1,11 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' +import { getCartDisabled } from '@graphcommerce/magento-cart' import { ApolloCustomerErrorFullPage, EditAddressForm, useCustomerQuery, AccountDashboardAddressesDocument, + getCustomerAccountIsDisabled, } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -90,6 +92,8 @@ CheckoutCustomerAddressesEdit.pageOptions = pageOptions export default CheckoutCustomerAddressesEdit export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCartDisabled(context.locale) || getCustomerAccountIsDisabled(context.locale)) + return { notFound: true } const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/checkout/edit/billing-address.tsx b/examples/magento-graphcms/pages/checkout/edit/billing-address.tsx index 0a55ef7262..c93d8fb8fa 100644 --- a/examples/magento-graphcms/pages/checkout/edit/billing-address.tsx +++ b/examples/magento-graphcms/pages/checkout/edit/billing-address.tsx @@ -1,4 +1,6 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' +import { cacheFirst } from '@graphcommerce/graphql' +import { getCheckoutIsDisabled } from '@graphcommerce/magento-cart' import { EditBillingAddressForm } from '@graphcommerce/magento-cart-billing-address' import { StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, PageMeta, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' @@ -7,7 +9,6 @@ import { Trans } from '@lingui/react' import { Container } from '@mui/material' import { LayoutDocument, LayoutOverlay, LayoutOverlayProps } from '../../../components' import { graphqlSsrClient, graphqlSharedClient } from '../../../lib/graphql/graphqlSsrClient' -import { cacheFirst } from '@graphcommerce/graphql' type Props = Record type GetPageStaticProps = GetStaticProps @@ -47,6 +48,8 @@ EditBillingAddress.pageOptions = pageOptions export default EditBillingAddress export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCheckoutIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) const staticClient = graphqlSsrClient(context) diff --git a/examples/magento-graphcms/pages/checkout/index.tsx b/examples/magento-graphcms/pages/checkout/index.tsx index 04a7400864..dd3d29a2af 100644 --- a/examples/magento-graphcms/pages/checkout/index.tsx +++ b/examples/magento-graphcms/pages/checkout/index.tsx @@ -11,6 +11,7 @@ import { ApolloCartErrorFullPage, ApolloCartErrorSnackbar, EmptyCart, + getCheckoutIsDisabled, useCartQuery, } from '@graphcommerce/magento-cart' import { ShippingPageDocument } from '@graphcommerce/magento-cart-checkout' @@ -150,6 +151,8 @@ ShippingPage.pageOptions = pageOptions export default ShippingPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCheckoutIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) const staticClient = graphqlSsrClient(context) diff --git a/examples/magento-graphcms/pages/checkout/item/[url].tsx b/examples/magento-graphcms/pages/checkout/item/[url].tsx index bcd65436e8..7f71566c3d 100644 --- a/examples/magento-graphcms/pages/checkout/item/[url].tsx +++ b/examples/magento-graphcms/pages/checkout/item/[url].tsx @@ -1,7 +1,12 @@ import { WaitForQueries } from '@graphcommerce/ecommerce-ui' import { PageOptions } from '@graphcommerce/framer-next-pages' import { flushMeasurePerf } from '@graphcommerce/graphql' -import { ApolloCartErrorAlert, EmptyCart, useCartQuery } from '@graphcommerce/magento-cart' +import { + ApolloCartErrorAlert, + EmptyCart, + getCartDisabled, + useCartQuery, +} from '@graphcommerce/magento-cart' import { CartPageDocument } from '@graphcommerce/magento-cart-checkout' import { EditCartItemButton, @@ -121,6 +126,7 @@ CartItemEdit.pageOptions = { export default CartItemEdit export const getServerSideProps: GetSSP = async (context) => { + if (getCartDisabled(context.locale)) return { notFound: true } const result = await getStaticProps(context) delete result.revalidate diff --git a/examples/magento-graphcms/pages/checkout/payment.tsx b/examples/magento-graphcms/pages/checkout/payment.tsx index c1cb508f94..21cb442660 100644 --- a/examples/magento-graphcms/pages/checkout/payment.tsx +++ b/examples/magento-graphcms/pages/checkout/payment.tsx @@ -7,6 +7,7 @@ import { CartSummary, CartTotals, EmptyCart, + getCheckoutIsDisabled, useCartQuery, } from '@graphcommerce/magento-cart' import { BillingPageDocument } from '@graphcommerce/magento-cart-checkout' @@ -155,6 +156,8 @@ PaymentPage.pageOptions = pageOptions export default PaymentPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCheckoutIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const staticClient = graphqlSsrClient(context) diff --git a/examples/magento-graphcms/pages/checkout/success.tsx b/examples/magento-graphcms/pages/checkout/success.tsx index 53e645c967..f13d8e4f27 100644 --- a/examples/magento-graphcms/pages/checkout/success.tsx +++ b/examples/magento-graphcms/pages/checkout/success.tsx @@ -1,5 +1,11 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { CartItemSummary, CartSummary, InlineAccount } from '@graphcommerce/magento-cart' +import { cacheFirst } from '@graphcommerce/graphql' +import { + CartItemSummary, + CartSummary, + InlineAccount, + getCheckoutIsDisabled, +} from '@graphcommerce/magento-cart' import { SignupNewsletter } from '@graphcommerce/magento-newsletter' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { @@ -22,7 +28,6 @@ import { LayoutMinimalProps, } from '../../components' import { graphqlSsrClient, graphqlSharedClient } from '../../lib/graphql/graphqlSsrClient' -import { cacheFirst } from '@graphcommerce/graphql' type Props = Record type GetPageStaticProps = GetStaticProps @@ -91,6 +96,8 @@ OrderSuccessPage.pageOptions = pageOptions export default OrderSuccessPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCheckoutIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const staticClient = graphqlSsrClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/checkout/terms/[url].tsx b/examples/magento-graphcms/pages/checkout/terms/[url].tsx index 50c176d008..8a7665cb49 100644 --- a/examples/magento-graphcms/pages/checkout/terms/[url].tsx +++ b/examples/magento-graphcms/pages/checkout/terms/[url].tsx @@ -1,5 +1,9 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { CartAgreementsDocument, CartAgreementsQuery } from '@graphcommerce/magento-cart' +import { + CartAgreementsDocument, + CartAgreementsQuery, + getCheckoutIsDisabled, +} from '@graphcommerce/magento-cart' import { StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, PageMeta, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' import { Container, Typography } from '@mui/material' @@ -68,6 +72,8 @@ export const getStaticPaths: GetPageStaticPaths = async ({ locales = [] }) => { } export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCheckoutIsDisabled(context.locale)) return { notFound: true } + const { params } = context const client = graphqlSharedClient(context) const staticClient = graphqlSsrClient(context) diff --git a/examples/magento-graphcms/pages/customer/account/confirm.tsx b/examples/magento-graphcms/pages/customer/account/confirm.tsx index 12c10a2d01..0145052831 100644 --- a/examples/magento-graphcms/pages/customer/account/confirm.tsx +++ b/examples/magento-graphcms/pages/customer/account/confirm.tsx @@ -1,5 +1,5 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { ConfirmCustomerForm } from '@graphcommerce/magento-customer' +import { ConfirmCustomerForm, getCustomerAccountIsDisabled } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' import { i18n } from '@lingui/core' @@ -40,6 +40,8 @@ AccountConfirmPage.pageOptions = pageOptions export default AccountConfirmPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/examples/magento-graphcms/pages/customer/account/createPassword/index.tsx b/examples/magento-graphcms/pages/customer/account/createPassword/index.tsx index 306d2fb80e..a36ac4f7fe 100644 --- a/examples/magento-graphcms/pages/customer/account/createPassword/index.tsx +++ b/examples/magento-graphcms/pages/customer/account/createPassword/index.tsx @@ -1,5 +1,5 @@ import { PageOptions } from '@graphcommerce/framer-next-pages' -import { ResetPasswordForm } from '@graphcommerce/magento-customer' +import { ResetPasswordForm, getCustomerAccountIsDisabled } from '@graphcommerce/magento-customer' import { PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store' import { GetStaticProps, LayoutOverlayHeader, LayoutTitle } from '@graphcommerce/next-ui' import { i18n } from '@lingui/core' @@ -81,6 +81,8 @@ CustomerAccountCreatePasswordPage.pageOptions = pageOptions export default CustomerAccountCreatePasswordPage export const getStaticProps: GetPageStaticProps = async (context) => { + if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true } + const client = graphqlSharedClient(context) const conf = client.query({ query: StoreConfigDocument }) diff --git a/packages/ecommerce-ui/Config.graphqls b/packages/ecommerce-ui/Config.graphqls new file mode 100644 index 0000000000..40fe817075 --- /dev/null +++ b/packages/ecommerce-ui/Config.graphqls @@ -0,0 +1,23 @@ +enum WebsitePermissions { + ENABLED + # CUSTOMER_ONLY will be implemented later + # DISABLED will be implemented later +} + +input GraphCommercePermissions { + website: WebsitePermissions +} + +extend input GraphCommerceConfig { + """ + Allows the option to require login or completely disable certain sections of the site, can be overriden per storeview with the storefrontConfig + """ + permissions: GraphCommercePermissions +} + +extend input GraphCommerceStorefrontConfig { + """ + Allows the option to require login or completely disable certain sections of the site on a per store basis + """ + permissions: GraphCommercePermissions +} diff --git a/packages/magento-cart-checkout/index.ts b/packages/magento-cart-checkout/index.ts index 207655e40c..11a7ab68e3 100644 --- a/packages/magento-cart-checkout/index.ts +++ b/packages/magento-cart-checkout/index.ts @@ -1,3 +1,3 @@ +export * from './queries/BillingPage.gql' export * from './queries/CartPage.gql' export * from './queries/ShippingPage.gql' -export * from './queries/BillingPage.gql' diff --git a/packages/magento-cart-email/EmailForm/EmailForm.tsx b/packages/magento-cart-email/EmailForm/EmailForm.tsx index 993b804125..f9b52c6548 100644 --- a/packages/magento-cart-email/EmailForm/EmailForm.tsx +++ b/packages/magento-cart-email/EmailForm/EmailForm.tsx @@ -1,11 +1,15 @@ -import { EmailElement, WaitForQueries } from '@graphcommerce/ecommerce-ui' +import { EmailElement } from '@graphcommerce/ecommerce-ui' import { useQuery } from '@graphcommerce/graphql' import { ApolloCartErrorAlert, useCartQuery, useFormGqlMutationCart, } from '@graphcommerce/magento-cart' -import { IsEmailAvailableDocument, useCustomerSession } from '@graphcommerce/magento-customer' +import { + IsEmailAvailableDocument, + useCustomerAccountCanSignIn, + useCustomerSession, +} from '@graphcommerce/magento-customer' import { extendableComponent, FormRow } from '@graphcommerce/next-ui' import { FormAutoSubmit, @@ -24,13 +28,15 @@ export type EmailFormProps = Pick & { sx?: SxProps } -const name = 'EmailForm' as const +const name = 'EmailForm' const parts = ['root', 'formRow'] as const const { classes } = extendableComponent(name, parts) const EmailFormBase = React.memo((props) => { const { step, sx } = props + const canLogin = useCustomerAccountCanSignIn() + const cartEmail = useCartQuery(CartEmailDocument) const form = useFormGqlMutationCart(SetGuestEmailOnCartDocument, { @@ -44,11 +50,16 @@ const EmailFormBase = React.memo((props) => { skip: !import.meta.graphCommerce.enableGuestCheckoutLogin || !email, }) - const { formState, required, error, handleSubmit } = form + const { required, error, handleSubmit } = form const submit = handleSubmit(() => {}) useFormCompose({ form, step, submit, key: 'EmailForm' }) + const showLogin = + import.meta.graphCommerce.enableGuestCheckoutLogin && + canLogin && + isEmailAvailable.data?.isEmailAvailable + return ( @@ -61,19 +72,14 @@ const EmailFormBase = React.memo((props) => { disabled={cartEmail.loading} InputProps={{ autoComplete: 'email', - endAdornment: ( - - {(isEmailAvailable.data?.isEmailAvailable || - !import.meta.graphCommerce.enableGuestCheckoutLogin) && ( - - )} - + endAdornment: showLogin && ( + ), }} /> diff --git a/packages/magento-cart-payment-method/PaymentMethodButton/PaymentMethodButton.tsx b/packages/magento-cart-payment-method/PaymentMethodButton/PaymentMethodButton.tsx index 891071fe12..e516e83851 100644 --- a/packages/magento-cart-payment-method/PaymentMethodButton/PaymentMethodButton.tsx +++ b/packages/magento-cart-payment-method/PaymentMethodButton/PaymentMethodButton.tsx @@ -1,5 +1,5 @@ import { ApolloCartErrorSnackbar } from '@graphcommerce/magento-cart' -import { ErrorSnackbar, LinkOrButton, LinkOrButtonProps } from '@graphcommerce/next-ui' +import { LinkOrButton, LinkOrButtonProps } from '@graphcommerce/next-ui' import { ComposedSubmit, ComposedSubmitProps, @@ -50,9 +50,9 @@ export function PaymentMethodButton(props: PaymentMethodButtonProps) { return ( { + render={({ submit, buttonState, error }) => { const errorVal = buttonState.isSubmitting ? undefined : error - const rootMessage = buttonState.isSubmitting ? undefined : rootThrown?.message + const button = ( {button} - - <>{rootMessage} - ) }} diff --git a/packages/magento-cart/Config.graphqls b/packages/magento-cart/Config.graphqls index 957498c255..605198c18d 100644 --- a/packages/magento-cart/Config.graphqls +++ b/packages/magento-cart/Config.graphqls @@ -1,3 +1,20 @@ +enum CartPermissions { + ENABLED + CUSTOMER_ONLY + DISABLED +} + +extend input GraphCommercePermissions { + """ + Changes the availability of the add to cart buttons and the cart page to either customer only or completely disables it. + """ + cart: CartPermissions + """ + Changes the availability of the checkout to either customer only or completely disables it. + """ + checkout: CartPermissions +} + extend input GraphCommerceStorefrontConfig { """ Due to a limitation of the GraphQL API it is not possible to determine if a cart should be displayed including or excluding tax. diff --git a/packages/magento-cart/components/ApolloCartError/ApolloCartErrorAlert.tsx b/packages/magento-cart/components/ApolloCartError/ApolloCartErrorAlert.tsx index c1d12ce0df..a836c5fb6c 100644 --- a/packages/magento-cart/components/ApolloCartError/ApolloCartErrorAlert.tsx +++ b/packages/magento-cart/components/ApolloCartError/ApolloCartErrorAlert.tsx @@ -1,55 +1,10 @@ -import { useQuery } from '@graphcommerce/graphql' import { ApolloCustomerErrorAlert, ApolloCustomerErrorAlertProps, - CustomerDocument, } from '@graphcommerce/magento-customer' -import { graphqlErrorByCategory } from '@graphcommerce/magento-graphql' -import { i18n } from '@lingui/core' -import { Trans } from '@lingui/react' -import { Button } from '@mui/material' -import { useClearCurrentCartId } from '../../hooks' export type ApolloCartErrorAlertProps = ApolloCustomerErrorAlertProps export function ApolloCartErrorAlert(props: ApolloCartErrorAlertProps) { - const { error, graphqlErrorAlertProps } = props - - const email = useQuery(CustomerDocument, { fetchPolicy: 'cache-only' }).data?.customer?.email - - const [newError, unauthorized] = graphqlErrorByCategory({ - category: 'graphql-authorization', - error, - mask: email - ? i18n._( - /* i18n */ 'This cart is assigned to {email}. Please sign in to continue shopping.', - { email }, - ) - : undefined, - extract: false, - }) - - const clear = useClearCurrentCartId() - - return ( - - {graphqlErrorAlertProps?.action} - - - - ) : ( - graphqlErrorAlertProps?.action - ), - }} - /> - ) + return } diff --git a/packages/magento-cart/components/CartFab/CartFab.tsx b/packages/magento-cart/components/CartFab/CartFab.tsx index 8cb5ded72f..3f8b862ae8 100644 --- a/packages/magento-cart/components/CartFab/CartFab.tsx +++ b/packages/magento-cart/components/CartFab/CartFab.tsx @@ -11,6 +11,7 @@ import { i18n } from '@lingui/core' import { alpha, Fab, FabProps, styled, useTheme, Box, SxProps, Theme } from '@mui/material' import { m, useTransform } from 'framer-motion' import React from 'react' +import { useCartEnabled, useCartShouldLoginToContinue } from '../../hooks' import { useCartQuery } from '../../hooks/useCartQuery' import { CartFabDocument } from './CartFab.gql' import { CartTotalQuantityFragment } from './CartTotalQuantity.gql' @@ -100,7 +101,12 @@ function CartFabContent(props: CartFabContentProps) { } export function CartFab(props: CartFabProps) { - const cartQuery = useCartQuery(CartFabDocument) + const cartEnabled = useCartEnabled() + const shouldLoginToContinue = useCartShouldLoginToContinue() + const cartQuery = useCartQuery(CartFabDocument, { + skip: shouldLoginToContinue, + }) + if (!cartEnabled) return null return ( }> diff --git a/packages/magento-cart/components/CartStartCheckout/CartStartCheckout.tsx b/packages/magento-cart/components/CartStartCheckout/CartStartCheckout.tsx index 651e0b9b54..684eda7202 100644 --- a/packages/magento-cart/components/CartStartCheckout/CartStartCheckout.tsx +++ b/packages/magento-cart/components/CartStartCheckout/CartStartCheckout.tsx @@ -1,8 +1,9 @@ import { Money } from '@graphcommerce/magento-store' import { iconChevronRight, IconSvg, extendableComponent } from '@graphcommerce/next-ui' -import { Trans } from '@lingui/react' -import { Box, Button, ButtonProps, SxProps, Theme } from '@mui/material' +import { Trans } from '@lingui/macro' +import { Box, Button, ButtonProps, Link, SxProps, Theme } from '@mui/material' import React from 'react' +import { useCheckoutShouldLoginToContinue } from '../../hooks' import { CartStartCheckoutFragment } from './CartStartCheckout.gql' export type CartStartCheckoutProps = { @@ -17,12 +18,13 @@ export type CartStartCheckoutProps = { ) => void } -const name = 'CartStartCheckout' as const +const name = 'CartStartCheckout' const parts = [ 'checkoutButtonContainer', 'checkoutButton', 'checkoutButtonTotal', 'checkoutMoney', + 'loginContainer', ] as const const { classes } = extendableComponent(name, parts) @@ -36,6 +38,7 @@ export function CartStartCheckout(props: CartStartCheckoutProps) { cart, } = props + const shouldLoginToContinue = useCheckoutShouldLoginToContinue() const hasTotals = (cart?.prices?.grand_total?.value ?? 0) > 0 const hasErrors = cart?.items?.some((item) => (item?.errors?.length ?? 0) > 0) @@ -43,10 +46,21 @@ export function CartStartCheckout(props: CartStartCheckoutProps) { ({ textAlign: 'center', my: theme.spacings.md }), + (theme) => ({ + textAlign: 'center', + my: theme.spacings.md, + }), ...(Array.isArray(sx) ? sx : [sx]), ]} > + {shouldLoginToContinue && ( + + + You must first login before you can continue + + + )} + ) : ( diff --git a/packages/magento-customer/components/ApolloCustomerError/ApolloCustomerErrorFullPage.tsx b/packages/magento-customer/components/ApolloCustomerError/ApolloCustomerErrorFullPage.tsx index daba7c5efd..2490762262 100644 --- a/packages/magento-customer/components/ApolloCustomerError/ApolloCustomerErrorFullPage.tsx +++ b/packages/magento-customer/components/ApolloCustomerError/ApolloCustomerErrorFullPage.tsx @@ -3,7 +3,7 @@ import { iconPerson, IconSvg } from '@graphcommerce/next-ui' import { Trans } from '@lingui/react' import { Button } from '@mui/material' import type { SetOptional } from 'type-fest' -import { useCustomerSession } from '../../hooks/useCustomerSession' +import { useCustomerAccountCanSignUp } from '../../hooks' import { useAuthorizationErrorMasked } from './useAuthorizationErrorMasked' export type ApolloCustomerErrorFullPageProps = { @@ -16,7 +16,7 @@ export type ApolloCustomerErrorFullPageProps = { export function ApolloCustomerErrorFullPage(props: ApolloCustomerErrorFullPageProps) { const { error, icon, altButton, button, ...alertProps } = props const [newError, unauthorized] = useAuthorizationErrorMasked(error) - const { token } = useCustomerSession() + const canSignUp = useCustomerAccountCanSignUp() return ( - {token ? : } + {canSignUp ? : } ) : ( button diff --git a/packages/magento-customer/components/ApolloCustomerError/useAuthorizationErrorMasked.ts b/packages/magento-customer/components/ApolloCustomerError/useAuthorizationErrorMasked.ts index 8ca7c8570b..2108b10dee 100644 --- a/packages/magento-customer/components/ApolloCustomerError/useAuthorizationErrorMasked.ts +++ b/packages/magento-customer/components/ApolloCustomerError/useAuthorizationErrorMasked.ts @@ -11,7 +11,7 @@ export function useAuthorizationErrorMasked(error?: ApolloError) { error, mask: token ? i18n._(/* i18n */ 'Please reauthenticate and try again') - : i18n._(/* i18n */ 'You must sign in to continue'), + : i18n._(/* i18n */ 'You must be signed in to continue'), extract: false, }) } diff --git a/packages/magento-customer/components/CustomerFab/CustomerFab.tsx b/packages/magento-customer/components/CustomerFab/CustomerFab.tsx index e63b4e3ad8..dac69072db 100644 --- a/packages/magento-customer/components/CustomerFab/CustomerFab.tsx +++ b/packages/magento-customer/components/CustomerFab/CustomerFab.tsx @@ -7,7 +7,11 @@ import { import { i18n } from '@lingui/core' import { Fab, FabProps as FabPropsType, NoSsr, SxProps, Theme } from '@mui/material' import React from 'react' -import { useCustomerSession, UseCustomerSessionReturn } from '../../hooks' +import { + useCustomerAccountCanSignIn, + useCustomerSession, + UseCustomerSessionReturn, +} from '../../hooks' type CustomerFabContentProps = { icon?: React.ReactNode @@ -52,6 +56,9 @@ export type CustomerFabProps = Omit export function CustomerFab(props: CustomerFabProps) { const session = useCustomerSession() + const canSignIn = useCustomerAccountCanSignIn() + + if (!canSignIn) return null return ( }> diff --git a/packages/magento-customer/components/CustomerMenuFabItem/CustomerMenuFabItem.tsx b/packages/magento-customer/components/CustomerMenuFabItem/CustomerMenuFabItem.tsx index 6d2db8b2b7..05de53b4d1 100644 --- a/packages/magento-customer/components/CustomerMenuFabItem/CustomerMenuFabItem.tsx +++ b/packages/magento-customer/components/CustomerMenuFabItem/CustomerMenuFabItem.tsx @@ -1,6 +1,7 @@ import { MenuFabSecondaryItem, iconPerson, IconSvg } from '@graphcommerce/next-ui' import { Badge, NoSsr, SxProps, Theme } from '@mui/material' import React, { MouseEventHandler } from 'react' +import { useCustomerAccountCanSignIn } from '../../hooks' import { useCustomerSession, UseCustomerSessionReturn } from '../../hooks/useCustomerSession' type CustomerMenuFabItemProps = { @@ -40,6 +41,9 @@ function CustomerMenuFabItemContent(props: CustomerMenuFabItemProps) { export function CustomerMenuFabItem(props: CustomerMenuFabItemProps) { const session = useCustomerSession() + const canSignIn = useCustomerAccountCanSignIn() + if (!canSignIn) return null + return ( }> diff --git a/packages/magento-customer/components/WaitForCustomer/WaitForCustomer.tsx b/packages/magento-customer/components/WaitForCustomer/WaitForCustomer.tsx index ef406ea74f..a50efd0bf7 100644 --- a/packages/magento-customer/components/WaitForCustomer/WaitForCustomer.tsx +++ b/packages/magento-customer/components/WaitForCustomer/WaitForCustomer.tsx @@ -1,5 +1,5 @@ import { mergeErrors, WaitForQueries, WaitForQueriesProps } from '@graphcommerce/ecommerce-ui' -import { FullPageMessage, FullPageMessageProps, IconSvg, iconPerson } from '@graphcommerce/next-ui' +import { FullPageMessage, FullPageMessageProps, iconPerson, IconSvg } from '@graphcommerce/next-ui' import { Trans } from '@lingui/react' import { Button, CircularProgress } from '@mui/material' import React from 'react' diff --git a/packages/magento-customer/graphql/Config.graphqls b/packages/magento-customer/graphql/Config.graphqls new file mode 100644 index 0000000000..b415c83219 --- /dev/null +++ b/packages/magento-customer/graphql/Config.graphqls @@ -0,0 +1,12 @@ +enum CustomerAccountPermissions { + ENABLED + DISABLE_REGISTRATION + DISABLED +} + +extend input GraphCommercePermissions { + """ + Enables / disabled the account section of the website. DISABLE_REGISTRATION will only disable the registration page. + """ + customerAccount: CustomerAccountPermissions +} diff --git a/packages/magento-customer/hooks/index.ts b/packages/magento-customer/hooks/index.ts index e62f1ae5cf..cdf9c53463 100644 --- a/packages/magento-customer/hooks/index.ts +++ b/packages/magento-customer/hooks/index.ts @@ -6,6 +6,7 @@ export * from './OrderCardItemImage.gql' export * from './OrderCardItemImages.gql' export * from './UseOrderCardItemImages.gql' export * from './useAccountSignInUpForm' +export * from './useCustomerPermissions' export * from './useCustomerQuery' export * from './useCustomerSession' export * from './useGuestQuery' diff --git a/packages/magento-customer/hooks/useAccountSignInUpForm.tsx b/packages/magento-customer/hooks/useAccountSignInUpForm.tsx index c94ba08b8b..013809527b 100644 --- a/packages/magento-customer/hooks/useAccountSignInUpForm.tsx +++ b/packages/magento-customer/hooks/useAccountSignInUpForm.tsx @@ -9,6 +9,7 @@ import { IsEmailAvailableQuery, IsEmailAvailableQueryVariables, } from './IsEmailAvailable.gql' +import { useCustomerAccountCanSignUp } from './useCustomerPermissions' import { useCustomerSession } from './useCustomerSession' export type UseFormIsEmailAvailableProps = { @@ -17,11 +18,13 @@ export type UseFormIsEmailAvailableProps = { export type AccountSignInUpState = 'email' | 'signin' | 'signup' | 'signedin' | 'session-expired' -export const isToggleMethod = !import.meta.graphCommerce.enableGuestCheckoutLogin - export function useAccountSignInUpForm(props: UseFormIsEmailAvailableProps = {}) { const { onSubmitted } = props const { token, valid } = useCustomerSession() + + const canSignUp = useCustomerAccountCanSignUp() + const isToggleMethod = !import.meta.graphCommerce.enableGuestCheckoutLogin || !canSignUp + const [queryState, setRouterQuery] = useUrlQuery<{ email?: string | null }>() const customerQuery = useQuery(CustomerDocument, { fetchPolicy: 'cache-only' }) diff --git a/packages/magento-customer/hooks/useCustomerPermissions.ts b/packages/magento-customer/hooks/useCustomerPermissions.ts new file mode 100644 index 0000000000..aa458230f5 --- /dev/null +++ b/packages/magento-customer/hooks/useCustomerPermissions.ts @@ -0,0 +1,17 @@ +import { useStorefrontConfig } from '@graphcommerce/next-ui' + +function useCustomerAccountPermission() { + return ( + useStorefrontConfig().permissions?.customerAccount ?? + import.meta.graphCommerce.permissions?.customerAccount ?? + 'ENABLED' + ) +} + +export function useCustomerAccountCanSignIn() { + return useCustomerAccountPermission() !== 'DISABLED' +} + +export function useCustomerAccountCanSignUp() { + return useCustomerAccountPermission() === 'ENABLED' +} diff --git a/packages/magento-customer/link/customerLink.ts b/packages/magento-customer/link/customerLink.ts index 9bc91d1072..36fb9978ac 100644 --- a/packages/magento-customer/link/customerLink.ts +++ b/packages/magento-customer/link/customerLink.ts @@ -7,12 +7,12 @@ import { setContext, } from '@graphcommerce/graphql/apollo' import { ErrorCategory } from '@graphcommerce/magento-graphql' -import type { GraphQLError } from 'graphql' +import { GraphQLError } from 'graphql' import { NextRouter } from 'next/router' import { signOut } from '../components/SignOutForm/signOut' import { CustomerTokenDocument } from '../hooks' -export type PushRouter = Pick +export type PushRouter = Pick declare module '@apollo/client' { interface DefaultContext { @@ -21,7 +21,7 @@ declare module '@apollo/client' { } } -async function pushWithPromise(router: Pick, url: string) { +export async function pushWithPromise(router: Pick, url: string) { try { await router.push(url) } catch { diff --git a/packages/magento-customer/plugins/MagentoCustomerGraphqlProvider.tsx b/packages/magento-customer/plugins/MagentoCustomerGraphqlProvider.tsx index 6d6c1353a9..9d112d8fdf 100644 --- a/packages/magento-customer/plugins/MagentoCustomerGraphqlProvider.tsx +++ b/packages/magento-customer/plugins/MagentoCustomerGraphqlProvider.tsx @@ -15,6 +15,7 @@ export function GraphQLProvider(props: PluginProps) { const { Prev, links = [], policies = [], migrations = [], router, ...rest } = props const push = useEventCallback((...args) => router.push(...args)) + const customerLinkMemo = useMemo( () => customerLink({ push, events: router.events }), [push, router.events], diff --git a/packages/magento-customer/utils/customerPermissions.ts b/packages/magento-customer/utils/customerPermissions.ts new file mode 100644 index 0000000000..79fb6f58e7 --- /dev/null +++ b/packages/magento-customer/utils/customerPermissions.ts @@ -0,0 +1,17 @@ +import { storefrontConfig } from '@graphcommerce/next-ui' + +function getCustomerAccountPermission(locale: string | undefined) { + return ( + storefrontConfig(locale)?.permissions?.customerAccount ?? + import.meta.graphCommerce.permissions?.customerAccount ?? + 'ENABLED' + ) +} + +export function getCustomerAccountIsDisabled(locale: string | undefined) { + return getCustomerAccountPermission(locale) === 'DISABLED' +} + +export function getCustomerAccountCanSignIn(locale: string | undefined) { + return getCustomerAccountPermission(locale) !== 'DISABLED' +} diff --git a/packages/magento-customer/utils/index.ts b/packages/magento-customer/utils/index.ts index 3008e19a50..74f9599cd0 100644 --- a/packages/magento-customer/utils/index.ts +++ b/packages/magento-customer/utils/index.ts @@ -1 +1,2 @@ +export * from './customerPermissions' export * from './orderState' diff --git a/packages/magento-graphql/graphqlErrorByCategory.ts b/packages/magento-graphql/graphqlErrorByCategory.ts index 482370200d..3e595986ec 100644 --- a/packages/magento-graphql/graphqlErrorByCategory.ts +++ b/packages/magento-graphql/graphqlErrorByCategory.ts @@ -36,6 +36,7 @@ export function graphqlErrorByCategory( props: GraphQLErrorByCategoryProps | GraphQLErrorByCategoryPropsNoExtract, ): [ApolloError | undefined, GraphQLError | undefined] { const { category, error, extract = true, mask } = props + if (!error) return [error, undefined] const newError = new ApolloError({ @@ -47,7 +48,6 @@ export function graphqlErrorByCategory( const graphqlError = error.graphQLErrors.find((err) => err?.extensions?.category === category) if (mask && graphqlError) { - if (graphqlError.extensions?.category) graphqlError.extensions.category = 'masked' graphqlError.message = mask } diff --git a/packages/magento-product/components/AddProductsToCart/AddProductsToCartButton.tsx b/packages/magento-product/components/AddProductsToCart/AddProductsToCartButton.tsx index cf218a0872..2701fef8ea 100644 --- a/packages/magento-product/components/AddProductsToCart/AddProductsToCartButton.tsx +++ b/packages/magento-product/components/AddProductsToCart/AddProductsToCartButton.tsx @@ -1,3 +1,4 @@ +import { useCartEnabled } from '@graphcommerce/magento-cart' import { Button, ButtonProps } from '@graphcommerce/next-ui' import { Trans } from '@lingui/macro' import { @@ -21,11 +22,22 @@ export type AddProductsToCartButtonProps = UseAddProductsToCartActionProps & > export function AddProductsToCartButton(props: AddProductsToCartButtonProps) { - const { children, product, ...rest } = props + const { children, product, disabled, ...rest } = props const { showSuccess, ...action } = useAddProductsToCartAction(props) + const cartEnabled = useCartEnabled() + + if (!cartEnabled) return null return ( - ) diff --git a/packages/magento-product/components/AddProductsToCart/AddProductsToCartFab.tsx b/packages/magento-product/components/AddProductsToCart/AddProductsToCartFab.tsx index 50a12d47a3..26d44e00d5 100644 --- a/packages/magento-product/components/AddProductsToCart/AddProductsToCartFab.tsx +++ b/packages/magento-product/components/AddProductsToCart/AddProductsToCartFab.tsx @@ -1,3 +1,4 @@ +import { useCartEnabled } from '@graphcommerce/magento-cart' import { Fab, FabProps, iconShoppingBag, iconCheckmark } from '@graphcommerce/next-ui' import { t } from '@lingui/macro' import { SxProps, Theme } from '@mui/material' @@ -16,6 +17,10 @@ export function AddProductsToCartFab(props: AddProductsToCartFabProps) { const { icon = iconShoppingBag, product, sku, ...rest } = props const { showSuccess, ...action } = useAddProductsToCartAction(props) + const cartEnabled = useCartEnabled() + + if (!cartEnabled) return null + return ( item.itemInCart?.product.name).filter(nonNullable)} diff --git a/packages/next-ui/LayoutDefault/components/LayoutDefault.tsx b/packages/next-ui/LayoutDefault/components/LayoutDefault.tsx index c6f7256a85..fa197bf9c1 100644 --- a/packages/next-ui/LayoutDefault/components/LayoutDefault.tsx +++ b/packages/next-ui/LayoutDefault/components/LayoutDefault.tsx @@ -129,19 +129,21 @@ export function LayoutDefault(props: LayoutDefaultProps) { })} > {menuFab} - ({ - display: 'flex', - flexDirection: 'row-reverse', - gap: theme.spacings.sm, - [theme.breakpoints.up('md')]: { - flexDirection: 'column', - alignItems: 'flex-end', - }, - })} - > - {cartFab} - + {cartFab && ( + ({ + display: 'flex', + flexDirection: 'row-reverse', + gap: theme.spacings.sm, + [theme.breakpoints.up('md')]: { + flexDirection: 'column', + alignItems: 'flex-end', + }, + })} + > + {cartFab} + + )} ) : (
diff --git a/packages/react-hook-form/src/ComposedForm/ComposedSubmit.tsx b/packages/react-hook-form/src/ComposedForm/ComposedSubmit.tsx index a32fbc739d..fba45435e0 100644 --- a/packages/react-hook-form/src/ComposedForm/ComposedSubmit.tsx +++ b/packages/react-hook-form/src/ComposedForm/ComposedSubmit.tsx @@ -120,19 +120,10 @@ export function ComposedSubmit(props: ComposedSubmitProps) { } const errors: ApolloError[] = [] - let rootThrown: GlobalError | undefined formEntries.forEach(([, { form }]) => { if (form && isFormGqlOperation(form) && form.error) errors.push(form.error) - if (form && form.formState.errors.root?.thrown) rootThrown = form.formState.errors.root.thrown }) - return ( - - ) + return } diff --git a/packages/react-hook-form/src/ComposedForm/types.ts b/packages/react-hook-form/src/ComposedForm/types.ts index 275ecdc4ae..104c07a0c8 100644 --- a/packages/react-hook-form/src/ComposedForm/types.ts +++ b/packages/react-hook-form/src/ComposedForm/types.ts @@ -36,7 +36,6 @@ export type ComposedSubmitRenderComponentProps = { submit: () => Promise buttonState: ButtonState error?: ApolloError - rootThrown?: GlobalError } export type ComposedFormState = { diff --git a/packages/react-hook-form/src/useFormGql.tsx b/packages/react-hook-form/src/useFormGql.tsx index 52fd2f3fd3..1c6d6c15d9 100644 --- a/packages/react-hook-form/src/useFormGql.tsx +++ b/packages/react-hook-form/src/useFormGql.tsx @@ -4,6 +4,7 @@ import { LazyQueryResultTuple, MutationTuple, TypedDocumentNode, + isApolloError, } from '@apollo/client' import { getOperationName } from '@apollo/client/utilities' import useEventCallback from '@mui/utils/useEventCallback' @@ -21,13 +22,13 @@ type UseFormGraphQLCallbacks = { * Mutation. * * When returning false, it will silently stop the submission. - * When an error is thrown, it will be set as a generic error with `setError('root.thrown', { message: error.message })` + * When an error is thrown, it will be set as an ApolloError */ onBeforeSubmit?: (variables: V) => V | false | Promise /** * Called after the mutation has been executed. Allows you to handle the result of the mutation. * - * When an error is thrown, it will be set as a generic error with `setError('root.thrown', { message: error.message })` + * When an error is thrown, it will be set as an ApolloError */ onComplete?: OnCompleteFn @@ -115,6 +116,7 @@ export function useFormGql( const [execute, { data, error, loading }] = tuple const submittedVariables = useRef() + const returnedError = useRef() // automatically updates the default values const initital = useRef(true) @@ -153,14 +155,24 @@ export function useFormGql( return } - // Combine defaults with the formValues and encode + returnedError.current = undefined submittedVariables.current = undefined + + // Combine defaults with the formValues and encode let variables = !deprecated_useV1 ? formValues : encode({ ...defaultValues, ...formValues }) // Wait for the onBeforeSubmit to complete const [onBeforeSubmitResult, onBeforeSubmitError] = await beforeSubmit(variables) if (onBeforeSubmitError) { - form.setError('root', { message: onBeforeSubmitError.message }) + if (isApolloError(onBeforeSubmitError)) { + returnedError.current = onBeforeSubmitError + } else { + console.log( + 'A non ApolloError was thrown during the onBeforeSubmit handler.', + onBeforeSubmitError, + ) + } + return } if (onBeforeSubmitResult === false) return @@ -176,7 +188,19 @@ export function useFormGql( const [, onCompleteError] = await complete(result, variables) if (onCompleteError) { - form.setError('root', { message: onCompleteError.message }) + returnedError.current = onCompleteError as ApolloError + return + } + if (onCompleteError) { + if (isApolloError(onCompleteError)) { + returnedError.current = onCompleteError + } else { + console.log( + 'A non ApolloError was thrown during the onComplete handler.', + onCompleteError, + ) + } + return } @@ -191,7 +215,7 @@ export function useFormGql( ...gqlDocumentHandler, handleSubmit, data, - error, + error: error ?? returnedError.current, submittedVariables: submittedVariables.current, } } diff --git a/packagesDev/next-config/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap b/packagesDev/next-config/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap index daa2373815..998eb39a89 100644 --- a/packagesDev/next-config/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap +++ b/packagesDev/next-config/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap @@ -60,6 +60,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_LIMIT_SSG", "GC_MAGENTO_ENDPOINT", "GC_MAGENTO_VERSION", + "GC_PERMISSIONS", + "GC_PERMISSIONS_CART", + "GC_PERMISSIONS_CHECKOUT", + "GC_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_PERMISSIONS_WEBSITE", "GC_PREVIEW_SECRET", "GC_PRODUCT_FILTERS_LAYOUT", "GC_PRODUCT_FILTERS_PRO", @@ -106,6 +111,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_0_LINGUI_LOCALE", "GC_STOREFRONT_0_LOCALE", "GC_STOREFRONT_0_MAGENTO_STORE_CODE", + "GC_STOREFRONT_0_PERMISSIONS", + "GC_STOREFRONT_0_PERMISSIONS_CART", + "GC_STOREFRONT_0_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_0_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_0_PERMISSIONS_WEBSITE", "GC_STOREFRONT_0_ROBOTS_ALLOW", "GC_STOREFRONT_1", "GC_STOREFRONT_1_CANONICAL_BASE_URL", @@ -141,6 +151,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_1_LINGUI_LOCALE", "GC_STOREFRONT_1_LOCALE", "GC_STOREFRONT_1_MAGENTO_STORE_CODE", + "GC_STOREFRONT_1_PERMISSIONS", + "GC_STOREFRONT_1_PERMISSIONS_CART", + "GC_STOREFRONT_1_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_1_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_1_PERMISSIONS_WEBSITE", "GC_STOREFRONT_1_ROBOTS_ALLOW", "GC_STOREFRONT_2", "GC_STOREFRONT_2_CANONICAL_BASE_URL", @@ -176,6 +191,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_2_LINGUI_LOCALE", "GC_STOREFRONT_2_LOCALE", "GC_STOREFRONT_2_MAGENTO_STORE_CODE", + "GC_STOREFRONT_2_PERMISSIONS", + "GC_STOREFRONT_2_PERMISSIONS_CART", + "GC_STOREFRONT_2_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_2_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_2_PERMISSIONS_WEBSITE", "GC_STOREFRONT_2_ROBOTS_ALLOW", "GC_STOREFRONT_3", "GC_STOREFRONT_3_CANONICAL_BASE_URL", @@ -211,6 +231,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_3_LINGUI_LOCALE", "GC_STOREFRONT_3_LOCALE", "GC_STOREFRONT_3_MAGENTO_STORE_CODE", + "GC_STOREFRONT_3_PERMISSIONS", + "GC_STOREFRONT_3_PERMISSIONS_CART", + "GC_STOREFRONT_3_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_3_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_3_PERMISSIONS_WEBSITE", "GC_STOREFRONT_3_ROBOTS_ALLOW", "GC_STOREFRONT_4", "GC_STOREFRONT_4_CANONICAL_BASE_URL", @@ -246,6 +271,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_4_LINGUI_LOCALE", "GC_STOREFRONT_4_LOCALE", "GC_STOREFRONT_4_MAGENTO_STORE_CODE", + "GC_STOREFRONT_4_PERMISSIONS", + "GC_STOREFRONT_4_PERMISSIONS_CART", + "GC_STOREFRONT_4_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_4_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_4_PERMISSIONS_WEBSITE", "GC_STOREFRONT_4_ROBOTS_ALLOW", "GC_STOREFRONT_5", "GC_STOREFRONT_5_CANONICAL_BASE_URL", @@ -281,6 +311,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_5_LINGUI_LOCALE", "GC_STOREFRONT_5_LOCALE", "GC_STOREFRONT_5_MAGENTO_STORE_CODE", + "GC_STOREFRONT_5_PERMISSIONS", + "GC_STOREFRONT_5_PERMISSIONS_CART", + "GC_STOREFRONT_5_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_5_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_5_PERMISSIONS_WEBSITE", "GC_STOREFRONT_5_ROBOTS_ALLOW", "GC_STOREFRONT_6", "GC_STOREFRONT_6_CANONICAL_BASE_URL", @@ -316,6 +351,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_6_LINGUI_LOCALE", "GC_STOREFRONT_6_LOCALE", "GC_STOREFRONT_6_MAGENTO_STORE_CODE", + "GC_STOREFRONT_6_PERMISSIONS", + "GC_STOREFRONT_6_PERMISSIONS_CART", + "GC_STOREFRONT_6_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_6_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_6_PERMISSIONS_WEBSITE", "GC_STOREFRONT_6_ROBOTS_ALLOW", "GC_STOREFRONT_7", "GC_STOREFRONT_7_CANONICAL_BASE_URL", @@ -351,6 +391,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_7_LINGUI_LOCALE", "GC_STOREFRONT_7_LOCALE", "GC_STOREFRONT_7_MAGENTO_STORE_CODE", + "GC_STOREFRONT_7_PERMISSIONS", + "GC_STOREFRONT_7_PERMISSIONS_CART", + "GC_STOREFRONT_7_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_7_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_7_PERMISSIONS_WEBSITE", "GC_STOREFRONT_7_ROBOTS_ALLOW", "GC_STOREFRONT_8", "GC_STOREFRONT_8_CANONICAL_BASE_URL", @@ -386,6 +431,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_8_LINGUI_LOCALE", "GC_STOREFRONT_8_LOCALE", "GC_STOREFRONT_8_MAGENTO_STORE_CODE", + "GC_STOREFRONT_8_PERMISSIONS", + "GC_STOREFRONT_8_PERMISSIONS_CART", + "GC_STOREFRONT_8_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_8_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_8_PERMISSIONS_WEBSITE", "GC_STOREFRONT_8_ROBOTS_ALLOW", "GC_STOREFRONT_9", "GC_STOREFRONT_9_CANONICAL_BASE_URL", @@ -421,6 +471,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_9_LINGUI_LOCALE", "GC_STOREFRONT_9_LOCALE", "GC_STOREFRONT_9_MAGENTO_STORE_CODE", + "GC_STOREFRONT_9_PERMISSIONS", + "GC_STOREFRONT_9_PERMISSIONS_CART", + "GC_STOREFRONT_9_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_9_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_9_PERMISSIONS_WEBSITE", "GC_STOREFRONT_9_ROBOTS_ALLOW", "GC_STOREFRONT_10", "GC_STOREFRONT_10_CANONICAL_BASE_URL", @@ -456,6 +511,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_10_LINGUI_LOCALE", "GC_STOREFRONT_10_LOCALE", "GC_STOREFRONT_10_MAGENTO_STORE_CODE", + "GC_STOREFRONT_10_PERMISSIONS", + "GC_STOREFRONT_10_PERMISSIONS_CART", + "GC_STOREFRONT_10_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_10_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_10_PERMISSIONS_WEBSITE", "GC_STOREFRONT_10_ROBOTS_ALLOW", "GC_STOREFRONT_11", "GC_STOREFRONT_11_CANONICAL_BASE_URL", @@ -491,6 +551,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_11_LINGUI_LOCALE", "GC_STOREFRONT_11_LOCALE", "GC_STOREFRONT_11_MAGENTO_STORE_CODE", + "GC_STOREFRONT_11_PERMISSIONS", + "GC_STOREFRONT_11_PERMISSIONS_CART", + "GC_STOREFRONT_11_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_11_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_11_PERMISSIONS_WEBSITE", "GC_STOREFRONT_11_ROBOTS_ALLOW", "GC_STOREFRONT_12", "GC_STOREFRONT_12_CANONICAL_BASE_URL", @@ -526,6 +591,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_12_LINGUI_LOCALE", "GC_STOREFRONT_12_LOCALE", "GC_STOREFRONT_12_MAGENTO_STORE_CODE", + "GC_STOREFRONT_12_PERMISSIONS", + "GC_STOREFRONT_12_PERMISSIONS_CART", + "GC_STOREFRONT_12_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_12_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_12_PERMISSIONS_WEBSITE", "GC_STOREFRONT_12_ROBOTS_ALLOW", "GC_STOREFRONT_13", "GC_STOREFRONT_13_CANONICAL_BASE_URL", @@ -561,6 +631,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_13_LINGUI_LOCALE", "GC_STOREFRONT_13_LOCALE", "GC_STOREFRONT_13_MAGENTO_STORE_CODE", + "GC_STOREFRONT_13_PERMISSIONS", + "GC_STOREFRONT_13_PERMISSIONS_CART", + "GC_STOREFRONT_13_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_13_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_13_PERMISSIONS_WEBSITE", "GC_STOREFRONT_13_ROBOTS_ALLOW", "GC_STOREFRONT_14", "GC_STOREFRONT_14_CANONICAL_BASE_URL", @@ -596,6 +671,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_14_LINGUI_LOCALE", "GC_STOREFRONT_14_LOCALE", "GC_STOREFRONT_14_MAGENTO_STORE_CODE", + "GC_STOREFRONT_14_PERMISSIONS", + "GC_STOREFRONT_14_PERMISSIONS_CART", + "GC_STOREFRONT_14_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_14_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_14_PERMISSIONS_WEBSITE", "GC_STOREFRONT_14_ROBOTS_ALLOW", "GC_STOREFRONT_15", "GC_STOREFRONT_15_CANONICAL_BASE_URL", @@ -631,6 +711,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_15_LINGUI_LOCALE", "GC_STOREFRONT_15_LOCALE", "GC_STOREFRONT_15_MAGENTO_STORE_CODE", + "GC_STOREFRONT_15_PERMISSIONS", + "GC_STOREFRONT_15_PERMISSIONS_CART", + "GC_STOREFRONT_15_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_15_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_15_PERMISSIONS_WEBSITE", "GC_STOREFRONT_15_ROBOTS_ALLOW", "GC_STOREFRONT_16", "GC_STOREFRONT_16_CANONICAL_BASE_URL", @@ -666,6 +751,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_16_LINGUI_LOCALE", "GC_STOREFRONT_16_LOCALE", "GC_STOREFRONT_16_MAGENTO_STORE_CODE", + "GC_STOREFRONT_16_PERMISSIONS", + "GC_STOREFRONT_16_PERMISSIONS_CART", + "GC_STOREFRONT_16_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_16_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_16_PERMISSIONS_WEBSITE", "GC_STOREFRONT_16_ROBOTS_ALLOW", "GC_STOREFRONT_17", "GC_STOREFRONT_17_CANONICAL_BASE_URL", @@ -701,6 +791,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_17_LINGUI_LOCALE", "GC_STOREFRONT_17_LOCALE", "GC_STOREFRONT_17_MAGENTO_STORE_CODE", + "GC_STOREFRONT_17_PERMISSIONS", + "GC_STOREFRONT_17_PERMISSIONS_CART", + "GC_STOREFRONT_17_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_17_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_17_PERMISSIONS_WEBSITE", "GC_STOREFRONT_17_ROBOTS_ALLOW", "GC_STOREFRONT_18", "GC_STOREFRONT_18_CANONICAL_BASE_URL", @@ -736,6 +831,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_18_LINGUI_LOCALE", "GC_STOREFRONT_18_LOCALE", "GC_STOREFRONT_18_MAGENTO_STORE_CODE", + "GC_STOREFRONT_18_PERMISSIONS", + "GC_STOREFRONT_18_PERMISSIONS_CART", + "GC_STOREFRONT_18_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_18_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_18_PERMISSIONS_WEBSITE", "GC_STOREFRONT_18_ROBOTS_ALLOW", "GC_STOREFRONT_19", "GC_STOREFRONT_19_CANONICAL_BASE_URL", @@ -771,6 +871,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_19_LINGUI_LOCALE", "GC_STOREFRONT_19_LOCALE", "GC_STOREFRONT_19_MAGENTO_STORE_CODE", + "GC_STOREFRONT_19_PERMISSIONS", + "GC_STOREFRONT_19_PERMISSIONS_CART", + "GC_STOREFRONT_19_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_19_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_19_PERMISSIONS_WEBSITE", "GC_STOREFRONT_19_ROBOTS_ALLOW", "GC_STOREFRONT_20", "GC_STOREFRONT_20_CANONICAL_BASE_URL", @@ -806,6 +911,11 @@ exports[`traverses a schema and returns a list of env variables that match 1`] = "GC_STOREFRONT_20_LINGUI_LOCALE", "GC_STOREFRONT_20_LOCALE", "GC_STOREFRONT_20_MAGENTO_STORE_CODE", + "GC_STOREFRONT_20_PERMISSIONS", + "GC_STOREFRONT_20_PERMISSIONS_CART", + "GC_STOREFRONT_20_PERMISSIONS_CHECKOUT", + "GC_STOREFRONT_20_PERMISSIONS_CUSTOMER_ACCOUNT", + "GC_STOREFRONT_20_PERMISSIONS_WEBSITE", "GC_STOREFRONT_20_ROBOTS_ALLOW", "GC_WISHLIST_HIDE_FOR_GUESTS", "GC_WISHLIST_SHOW_FEEDBACK_MESSAGE", diff --git a/packagesDev/next-config/dist/generated/config.js b/packagesDev/next-config/dist/generated/config.js index dc3a907c41..19e8173e17 100644 --- a/packagesDev/next-config/dist/generated/config.js +++ b/packagesDev/next-config/dist/generated/config.js @@ -9,9 +9,15 @@ function _export(target, all) { }); } _export(exports, { + CartPermissionsSchema: function() { + return CartPermissionsSchema; + }, CompareVariantSchema: function() { return CompareVariantSchema; }, + CustomerAccountPermissionsSchema: function() { + return CustomerAccountPermissionsSchema; + }, DatalayerConfigSchema: function() { return DatalayerConfigSchema; }, @@ -21,6 +27,9 @@ _export(exports, { GraphCommerceDebugConfigSchema: function() { return GraphCommerceDebugConfigSchema; }, + GraphCommercePermissionsSchema: function() { + return GraphCommercePermissionsSchema; + }, GraphCommerceStorefrontConfigSchema: function() { return GraphCommerceStorefrontConfigSchema; }, @@ -42,6 +51,9 @@ _export(exports, { SidebarGalleryPaginationVariantSchema: function() { return SidebarGalleryPaginationVariantSchema; }, + WebsitePermissionsSchema: function() { + return WebsitePermissionsSchema; + }, definedNonNullAnySchema: function() { return definedNonNullAnySchema; }, @@ -52,10 +64,20 @@ _export(exports, { const _zod = require("zod"); const isDefinedNonNullAny = (v)=>v !== undefined && v !== null; const definedNonNullAnySchema = _zod.z.any().refine((v)=>isDefinedNonNullAny(v)); +const CartPermissionsSchema = _zod.z.enum([ + 'CUSTOMER_ONLY', + 'DISABLED', + 'ENABLED' +]); const CompareVariantSchema = _zod.z.enum([ 'CHECKBOX', 'ICON' ]); +const CustomerAccountPermissionsSchema = _zod.z.enum([ + 'DISABLED', + 'DISABLE_REGISTRATION', + 'ENABLED' +]); const PaginationVariantSchema = _zod.z.enum([ 'COMPACT', 'EXTENDED' @@ -68,6 +90,9 @@ const SidebarGalleryPaginationVariantSchema = _zod.z.enum([ 'DOTS', 'THUMBNAILS_BOTTOM' ]); +const WebsitePermissionsSchema = _zod.z.enum([ + 'ENABLED' +]); function DatalayerConfigSchema() { return _zod.z.object({ coreWebVitals: _zod.z.boolean().nullish() @@ -102,6 +127,7 @@ function GraphCommerceConfigSchema() { limitSsg: _zod.z.boolean().nullish(), magentoEndpoint: _zod.z.string().min(1), magentoVersion: _zod.z.number(), + permissions: GraphCommercePermissionsSchema().nullish(), previewSecret: _zod.z.string().nullish(), productFiltersLayout: ProductFiltersLayoutSchema.default("DEFAULT").nullish(), productFiltersPro: _zod.z.boolean().nullish(), @@ -123,6 +149,14 @@ function GraphCommerceDebugConfigSchema() { webpackDuplicatesPlugin: _zod.z.boolean().nullish() }); } +function GraphCommercePermissionsSchema() { + return _zod.z.object({ + cart: CartPermissionsSchema.nullish(), + checkout: CartPermissionsSchema.nullish(), + customerAccount: CustomerAccountPermissionsSchema.nullish(), + website: WebsitePermissionsSchema.nullish() + }); +} function GraphCommerceStorefrontConfigSchema() { return _zod.z.object({ canonicalBaseUrl: _zod.z.string().nullish(), @@ -137,6 +171,7 @@ function GraphCommerceStorefrontConfigSchema() { linguiLocale: _zod.z.string().nullish(), locale: _zod.z.string().min(1), magentoStoreCode: _zod.z.string().min(1), + permissions: GraphCommercePermissionsSchema().nullish(), robotsAllow: _zod.z.boolean().nullish() }); } diff --git a/packagesDev/next-config/src/generated/config.ts b/packagesDev/next-config/src/generated/config.ts index b2b61aaccd..8d9381ea53 100644 --- a/packagesDev/next-config/src/generated/config.ts +++ b/packagesDev/next-config/src/generated/config.ts @@ -16,10 +16,20 @@ export type Scalars = { Float: { input: number; output: number; } }; +export type CartPermissions = + | 'CUSTOMER_ONLY' + | 'DISABLED' + | 'ENABLED'; + export type CompareVariant = | 'CHECKBOX' | 'ICON'; +export type CustomerAccountPermissions = + | 'DISABLED' + | 'DISABLE_REGISTRATION' + | 'ENABLED'; + /** GoogleDatalayerConfig to allow enabling certain aspects of the datalayer */ export type DatalayerConfig = { /** Enable core web vitals tracking for GraphCommerce */ @@ -293,6 +303,8 @@ export type GraphCommerceConfig = { * Values: 245, 246, 247 for Magento 2.4.5, 2.4.6, 2.4.7 respectively. */ magentoVersion: Scalars['Int']['input']; + /** Allows the option to require login or completely disable certain sections of the site, can be overriden per storeview with the storefrontConfig */ + permissions?: InputMaybe; /** To enable next.js' preview mode, configure the secret you'd like to use. */ previewSecret?: InputMaybe; /** @@ -357,6 +369,16 @@ export type GraphCommerceDebugConfig = { webpackDuplicatesPlugin?: InputMaybe; }; +export type GraphCommercePermissions = { + /** Changes the availability of the add to cart buttons and the cart page to either customer only or completely disables it. */ + cart?: InputMaybe; + /** Changes the availability of the checkout to either customer only or completely disables it. */ + checkout?: InputMaybe; + /** Enables / disabled the account section of the website. DISABLE_REGISTRATION will only disable the registration page. */ + customerAccount?: InputMaybe; + website?: InputMaybe; +}; + /** All storefront configuration for the project */ export type GraphCommerceStorefrontConfig = { /** @@ -415,6 +437,8 @@ export type GraphCommerceStorefrontConfig = { * - b2b-us */ magentoStoreCode: Scalars['String']['input']; + /** Allows the option to require login or completely disable certain sections of the site on a per store basis */ + permissions?: InputMaybe; /** * Allow the site to be indexed by search engines. * If false, the robots.txt file will be set to disallow all. @@ -466,6 +490,9 @@ export type SidebarGalleryPaginationVariant = | 'DOTS' | 'THUMBNAILS_BOTTOM'; +export type WebsitePermissions = + | 'ENABLED'; + type Properties = Required<{ [K in keyof T]: z.ZodType; @@ -477,14 +504,20 @@ export const isDefinedNonNullAny = (v: any): v is definedNonNullAny => v !== und export const definedNonNullAnySchema = z.any().refine((v) => isDefinedNonNullAny(v)); +export const CartPermissionsSchema = z.enum(['CUSTOMER_ONLY', 'DISABLED', 'ENABLED']); + export const CompareVariantSchema = z.enum(['CHECKBOX', 'ICON']); +export const CustomerAccountPermissionsSchema = z.enum(['DISABLED', 'DISABLE_REGISTRATION', 'ENABLED']); + export const PaginationVariantSchema = z.enum(['COMPACT', 'EXTENDED']); export const ProductFiltersLayoutSchema = z.enum(['DEFAULT', 'SIDEBAR']); export const SidebarGalleryPaginationVariantSchema = z.enum(['DOTS', 'THUMBNAILS_BOTTOM']); +export const WebsitePermissionsSchema = z.enum(['ENABLED']); + export function DatalayerConfigSchema(): z.ZodObject> { return z.object({ coreWebVitals: z.boolean().nullish() @@ -520,6 +553,7 @@ export function GraphCommerceConfigSchema(): z.ZodObject> { + return z.object({ + cart: CartPermissionsSchema.nullish(), + checkout: CartPermissionsSchema.nullish(), + customerAccount: CustomerAccountPermissionsSchema.nullish(), + website: WebsitePermissionsSchema.nullish() + }) +} + export function GraphCommerceStorefrontConfigSchema(): z.ZodObject> { return z.object({ canonicalBaseUrl: z.string().nullish(), @@ -557,6 +600,7 @@ export function GraphCommerceStorefrontConfigSchema(): z.ZodObject