@vendure-platform/create 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +39 -39
- package/dist/add-to-existing.js +1 -1
- package/dist/assets/demo-data/initial-data.json +663 -663
- package/dist/assets/storefront/components.json +20 -20
- package/dist/assets/storefront/eslint.config.mjs +10 -10
- package/dist/assets/storefront/graphql.config.yml +1 -1
- package/dist/assets/storefront/messages/de.json +2 -0
- package/dist/assets/storefront/messages/en.json +2 -0
- package/dist/assets/storefront/next.config.ts +5 -4
- package/dist/assets/storefront/package.json +1 -1
- package/dist/assets/storefront/postcss.config.mjs +1 -1
- package/dist/assets/storefront/src/app/[locale]/(catalog)/catalog/page.tsx +17 -21
- package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/page.tsx +64 -42
- package/dist/assets/storefront/src/app/[locale]/(catalog)/layout.tsx +1 -5
- package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/actions.ts +69 -65
- package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/page.tsx +68 -37
- package/dist/assets/storefront/src/app/[locale]/(catalog)/search/page.tsx +24 -27
- package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-results.tsx +11 -9
- package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-term.tsx +4 -4
- package/dist/assets/storefront/src/app/[locale]/(scenario)/[...path]/page.tsx +1 -1
- package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/accept-invitation-client.tsx +8 -13
- package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/actions.ts +11 -14
- package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/page.tsx +30 -33
- package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/sign-out-and-retry.tsx +6 -6
- package/dist/assets/storefront/src/app/[locale]/account/addresses/actions.ts +30 -45
- package/dist/assets/storefront/src/app/[locale]/account/addresses/address-form.tsx +166 -159
- package/dist/assets/storefront/src/app/[locale]/account/addresses/addresses-client.tsx +35 -26
- package/dist/assets/storefront/src/app/[locale]/account/addresses/loading.tsx +1 -3
- package/dist/assets/storefront/src/app/[locale]/account/addresses/page.tsx +16 -18
- package/dist/assets/storefront/src/app/[locale]/account/approvals/actions.ts +5 -8
- package/dist/assets/storefront/src/app/[locale]/account/approvals/page.tsx +77 -69
- package/dist/assets/storefront/src/app/[locale]/account/company/actions.ts +10 -11
- package/dist/assets/storefront/src/app/[locale]/account/company/addresses/actions.ts +6 -15
- package/dist/assets/storefront/src/app/[locale]/account/company/addresses/address-form.tsx +57 -49
- package/dist/assets/storefront/src/app/[locale]/account/company/addresses/addresses-client.tsx +23 -25
- package/dist/assets/storefront/src/app/[locale]/account/company/addresses/page.tsx +30 -30
- package/dist/assets/storefront/src/app/[locale]/account/company/business-units/actions.ts +20 -29
- package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-unit-form.tsx +32 -37
- package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-units-client.tsx +32 -25
- package/dist/assets/storefront/src/app/[locale]/account/company/business-units/page.tsx +24 -24
- package/dist/assets/storefront/src/app/[locale]/account/company/business-units/types.ts +7 -4
- package/dist/assets/storefront/src/app/[locale]/account/company/edit-company-form.tsx +11 -21
- package/dist/assets/storefront/src/app/[locale]/account/company/page.tsx +23 -28
- package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/page.tsx +24 -24
- package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/payment-methods-client.tsx +5 -7
- package/dist/assets/storefront/src/app/[locale]/account/company/roles/page.tsx +22 -25
- package/dist/assets/storefront/src/app/[locale]/account/company/roles/roles-client.tsx +11 -26
- package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/actions.ts +6 -10
- package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/page.tsx +18 -16
- package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/tax-ids-client.tsx +74 -67
- package/dist/assets/storefront/src/app/[locale]/account/company/users/actions.ts +16 -25
- package/dist/assets/storefront/src/app/[locale]/account/company/users/edit-user-form.tsx +27 -25
- package/dist/assets/storefront/src/app/[locale]/account/company/users/invite-user-form.tsx +27 -19
- package/dist/assets/storefront/src/app/[locale]/account/company/users/page.tsx +32 -29
- package/dist/assets/storefront/src/app/[locale]/account/company/users/users-client.tsx +35 -38
- package/dist/assets/storefront/src/app/[locale]/account/error.tsx +1 -3
- package/dist/assets/storefront/src/app/[locale]/account/layout.tsx +16 -22
- package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/page.tsx +151 -103
- package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-actions.ts +6 -7
- package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-dialog.tsx +22 -48
- package/dist/assets/storefront/src/app/[locale]/account/orders/loading.tsx +8 -8
- package/dist/assets/storefront/src/app/[locale]/account/orders/page.tsx +101 -61
- package/dist/assets/storefront/src/app/[locale]/account/profile/actions.ts +32 -23
- package/dist/assets/storefront/src/app/[locale]/account/profile/change-password-form.tsx +6 -16
- package/dist/assets/storefront/src/app/[locale]/account/profile/edit-email-form.tsx +7 -17
- package/dist/assets/storefront/src/app/[locale]/account/profile/edit-profile-form.tsx +6 -16
- package/dist/assets/storefront/src/app/[locale]/account/profile/loading.tsx +12 -18
- package/dist/assets/storefront/src/app/[locale]/account/profile/page.tsx +15 -15
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/file-upload-tab.tsx +2 -6
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/manual-entry-tab.tsx +18 -15
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/page.tsx +3 -6
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/preview-table.tsx +10 -2
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/save-to-list-dialog.tsx +24 -26
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/sku-autocomplete.tsx +19 -10
- package/dist/assets/storefront/src/app/[locale]/account/quick-order/text-input-tab.tsx +3 -8
- package/dist/assets/storefront/src/app/[locale]/account/quotes/[id]/page.tsx +86 -59
- package/dist/assets/storefront/src/app/[locale]/account/quotes/actions.ts +38 -45
- package/dist/assets/storefront/src/app/[locale]/account/quotes/new/new-quote-form.tsx +3 -5
- package/dist/assets/storefront/src/app/[locale]/account/quotes/new/page.tsx +6 -6
- package/dist/assets/storefront/src/app/[locale]/account/quotes/page.tsx +92 -59
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/activity-feed.tsx +152 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-item-search.tsx +132 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-member-form.tsx +140 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/members-panel.tsx +259 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/page.tsx +55 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/rename-dialog.tsx +117 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/shared-cart-detail-client.tsx +555 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/actions.ts +305 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/new-shared-cart-form.tsx +84 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/page.tsx +47 -0
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/page.tsx +276 -0
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/page.tsx +22 -8
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/shopping-list-detail-client.tsx +62 -49
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/actions.ts +9 -4
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/create-shopping-list-form.tsx +5 -11
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/loading.tsx +1 -1
- package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/page.tsx +32 -42
- package/dist/assets/storefront/src/app/[locale]/account/store-credits/actions.ts +8 -8
- package/dist/assets/storefront/src/app/[locale]/account/store-credits/claim-form.tsx +6 -10
- package/dist/assets/storefront/src/app/[locale]/account/store-credits/page.tsx +76 -55
- package/dist/assets/storefront/src/app/[locale]/account/store-credits/reveal-code.tsx +10 -6
- package/dist/assets/storefront/src/app/[locale]/account/verify-email/page.tsx +32 -39
- package/dist/assets/storefront/src/app/[locale]/cart/actions.ts +29 -23
- package/dist/assets/storefront/src/app/[locale]/cart/cart-items.tsx +111 -40
- package/dist/assets/storefront/src/app/[locale]/cart/cart-line-actions.tsx +9 -9
- package/dist/assets/storefront/src/app/[locale]/cart/cart-quantity-control.tsx +61 -48
- package/dist/assets/storefront/src/app/[locale]/cart/cart-remove-button.tsx +15 -9
- package/dist/assets/storefront/src/app/[locale]/cart/cart.tsx +38 -41
- package/dist/assets/storefront/src/app/[locale]/cart/code-input.tsx +8 -8
- package/dist/assets/storefront/src/app/[locale]/cart/order-summary.tsx +70 -29
- package/dist/assets/storefront/src/app/[locale]/cart/page.tsx +11 -11
- package/dist/assets/storefront/src/app/[locale]/cart/promotion-code.tsx +48 -42
- package/dist/assets/storefront/src/app/[locale]/cart/reapproval-confirm.tsx +22 -20
- package/dist/assets/storefront/src/app/[locale]/cart/request-quote-button.tsx +7 -16
- package/dist/assets/storefront/src/app/[locale]/checkout/actions.ts +39 -65
- package/dist/assets/storefront/src/app/[locale]/checkout/cancel-quote-checkout-button.tsx +5 -5
- package/dist/assets/storefront/src/app/[locale]/checkout/checkout-flow.tsx +202 -202
- package/dist/assets/storefront/src/app/[locale]/checkout/checkout-provider.tsx +142 -142
- package/dist/assets/storefront/src/app/[locale]/checkout/order-summary.tsx +158 -139
- package/dist/assets/storefront/src/app/[locale]/checkout/page.tsx +56 -47
- package/dist/assets/storefront/src/app/[locale]/checkout/steps/delivery-step.tsx +86 -88
- package/dist/assets/storefront/src/app/[locale]/checkout/steps/payment-step.tsx +90 -91
- package/dist/assets/storefront/src/app/[locale]/checkout/steps/review-step.tsx +166 -161
- package/dist/assets/storefront/src/app/[locale]/checkout/steps/shipping-address-step.tsx +573 -494
- package/dist/assets/storefront/src/app/[locale]/error.tsx +3 -5
- package/dist/assets/storefront/src/app/[locale]/forgot-password/actions.ts +10 -7
- package/dist/assets/storefront/src/app/[locale]/forgot-password/forgot-password-form.tsx +10 -25
- package/dist/assets/storefront/src/app/[locale]/forgot-password/page.tsx +5 -5
- package/dist/assets/storefront/src/app/[locale]/globals.css +48 -48
- package/dist/assets/storefront/src/app/[locale]/layout.tsx +53 -47
- package/dist/assets/storefront/src/app/[locale]/not-found.tsx +3 -5
- package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/order-confirmation.tsx +71 -44
- package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/page.tsx +7 -5
- package/dist/assets/storefront/src/app/[locale]/page.tsx +33 -35
- package/dist/assets/storefront/src/app/[locale]/register/actions.ts +7 -7
- package/dist/assets/storefront/src/app/[locale]/register/page.tsx +22 -16
- package/dist/assets/storefront/src/app/[locale]/register/registration-form.tsx +22 -34
- package/dist/assets/storefront/src/app/[locale]/register-company/actions.ts +15 -19
- package/dist/assets/storefront/src/app/[locale]/register-company/page.tsx +17 -15
- package/dist/assets/storefront/src/app/[locale]/register-company/registration-form.tsx +9 -15
- package/dist/assets/storefront/src/app/[locale]/reset-password/actions.ts +7 -8
- package/dist/assets/storefront/src/app/[locale]/reset-password/page.tsx +18 -12
- package/dist/assets/storefront/src/app/[locale]/reset-password/reset-password-form.tsx +8 -16
- package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/add-to-cart-button.tsx +10 -4
- package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/page.tsx +62 -30
- package/dist/assets/storefront/src/app/[locale]/sign-in/actions.ts +14 -16
- package/dist/assets/storefront/src/app/[locale]/sign-in/login-form.tsx +17 -30
- package/dist/assets/storefront/src/app/[locale]/sign-in/page.tsx +35 -30
- package/dist/assets/storefront/src/app/[locale]/verify/actions.ts +8 -8
- package/dist/assets/storefront/src/app/[locale]/verify/page.tsx +18 -14
- package/dist/assets/storefront/src/app/[locale]/verify/verify-content.tsx +25 -27
- package/dist/assets/storefront/src/app/[locale]/verify-pending/page.tsx +23 -23
- package/dist/assets/storefront/src/app/api/clear-company-context/route.ts +6 -3
- package/dist/assets/storefront/src/app/api/revalidate/route.ts +19 -28
- package/dist/assets/storefront/src/app/api/search-analytics/route.ts +1 -1
- package/dist/assets/storefront/src/components/commerce/account-nav-items.ts +44 -17
- package/dist/assets/storefront/src/components/commerce/account-sidebar.tsx +30 -22
- package/dist/assets/storefront/src/components/commerce/active-filters.tsx +1 -1
- package/dist/assets/storefront/src/components/commerce/add-to-shared-cart.tsx +247 -0
- package/dist/assets/storefront/src/components/commerce/approval-decision-form.tsx +9 -13
- package/dist/assets/storefront/src/components/commerce/approval-status-badge.tsx +23 -15
- package/dist/assets/storefront/src/components/commerce/business-unit-switcher.tsx +11 -11
- package/dist/assets/storefront/src/components/commerce/catalog-search-bar.tsx +2 -2
- package/dist/assets/storefront/src/components/commerce/category-product-section.tsx +28 -16
- package/dist/assets/storefront/src/components/commerce/category-sidebar.tsx +31 -18
- package/dist/assets/storefront/src/components/commerce/collection-hero-banner.tsx +2 -4
- package/dist/assets/storefront/src/components/commerce/company-state-badge.tsx +10 -16
- package/dist/assets/storefront/src/components/commerce/company-switcher.tsx +12 -12
- package/dist/assets/storefront/src/components/commerce/configurator-form.tsx +188 -79
- package/dist/assets/storefront/src/components/commerce/facet-filters.tsx +29 -49
- package/dist/assets/storefront/src/components/commerce/gift-card-pdp.tsx +4 -4
- package/dist/assets/storefront/src/components/commerce/gift-card-product-info.tsx +20 -30
- package/dist/assets/storefront/src/components/commerce/instant-search-dropdown.tsx +258 -227
- package/dist/assets/storefront/src/components/commerce/order-status-badge.tsx +27 -19
- package/dist/assets/storefront/src/components/commerce/packaging-unit-selector.tsx +27 -26
- package/dist/assets/storefront/src/components/commerce/permission-gate.tsx +4 -4
- package/dist/assets/storefront/src/components/commerce/price-range-filter.tsx +5 -5
- package/dist/assets/storefront/src/components/commerce/price-tiers.tsx +38 -21
- package/dist/assets/storefront/src/components/commerce/price.tsx +3 -3
- package/dist/assets/storefront/src/components/commerce/product-card-list.tsx +35 -14
- package/dist/assets/storefront/src/components/commerce/product-card.tsx +31 -16
- package/dist/assets/storefront/src/components/commerce/product-carousel.tsx +20 -12
- package/dist/assets/storefront/src/components/commerce/product-grid.tsx +14 -13
- package/dist/assets/storefront/src/components/commerce/product-image-carousel.tsx +10 -8
- package/dist/assets/storefront/src/components/commerce/product-info.tsx +129 -72
- package/dist/assets/storefront/src/components/commerce/product-list-expansion.tsx +102 -74
- package/dist/assets/storefront/src/components/commerce/product-list-view.tsx +1 -1
- package/dist/assets/storefront/src/components/commerce/product-sidebar.tsx +36 -11
- package/dist/assets/storefront/src/components/commerce/product-view-switcher.tsx +33 -21
- package/dist/assets/storefront/src/components/commerce/quote-action-buttons.tsx +54 -36
- package/dist/assets/storefront/src/components/commerce/quote-activity-timeline.tsx +126 -50
- package/dist/assets/storefront/src/components/commerce/quote-comment-form.tsx +9 -13
- package/dist/assets/storefront/src/components/commerce/quote-csv-export-button.tsx +6 -6
- package/dist/assets/storefront/src/components/commerce/quote-product-search.tsx +22 -18
- package/dist/assets/storefront/src/components/commerce/quote-request-form.tsx +28 -27
- package/dist/assets/storefront/src/components/commerce/quote-status-badge.tsx +26 -18
- package/dist/assets/storefront/src/components/commerce/quote-validity-indicator.tsx +7 -7
- package/dist/assets/storefront/src/components/commerce/quote-version-comparison.tsx +50 -30
- package/dist/assets/storefront/src/components/commerce/related-products.tsx +37 -28
- package/dist/assets/storefront/src/components/commerce/shared-cart-role.ts +39 -0
- package/dist/assets/storefront/src/components/commerce/shared-cart-status-badge.tsx +28 -0
- package/dist/assets/storefront/src/components/commerce/shop-by-category.tsx +8 -7
- package/dist/assets/storefront/src/components/commerce/shopping-list-toggle.tsx +14 -20
- package/dist/assets/storefront/src/components/commerce/sort-dropdown.tsx +9 -16
- package/dist/assets/storefront/src/components/commerce/store-credit-summary.tsx +30 -32
- package/dist/assets/storefront/src/components/commerce/subcollection-tiles.tsx +11 -13
- package/dist/assets/storefront/src/components/layout/auth-page-shell.tsx +2 -2
- package/dist/assets/storefront/src/components/layout/draft-mode-indicator.tsx +2 -7
- package/dist/assets/storefront/src/components/layout/draft-mode-link.tsx +4 -2
- package/dist/assets/storefront/src/components/layout/footer.tsx +70 -28
- package/dist/assets/storefront/src/components/layout/navbar/actions.ts +9 -12
- package/dist/assets/storefront/src/components/layout/navbar/cart-icon.tsx +9 -9
- package/dist/assets/storefront/src/components/layout/navbar/channel-picker-wrapper.tsx +4 -9
- package/dist/assets/storefront/src/components/layout/navbar/channel-picker.tsx +13 -8
- package/dist/assets/storefront/src/components/layout/navbar/currency-picker-wrapper.tsx +4 -4
- package/dist/assets/storefront/src/components/layout/navbar/currency-picker.tsx +11 -6
- package/dist/assets/storefront/src/components/layout/navbar/language-picker.tsx +7 -7
- package/dist/assets/storefront/src/components/layout/navbar/login-button.tsx +24 -21
- package/dist/assets/storefront/src/components/layout/navbar/mobile-nav.tsx +8 -8
- package/dist/assets/storefront/src/components/layout/navbar/nav-menu-items.tsx +4 -6
- package/dist/assets/storefront/src/components/layout/navbar/navbar-cart.tsx +1 -1
- package/dist/assets/storefront/src/components/layout/navbar/navbar-collections.tsx +41 -42
- package/dist/assets/storefront/src/components/layout/navbar/navbar-link.tsx +7 -10
- package/dist/assets/storefront/src/components/layout/navbar/navbar-user.tsx +18 -23
- package/dist/assets/storefront/src/components/layout/navbar/theme-switcher.tsx +9 -9
- package/dist/assets/storefront/src/components/layout/navbar.tsx +36 -31
- package/dist/assets/storefront/src/components/layout/search-input.tsx +35 -32
- package/dist/assets/storefront/src/components/providers/awaiting-approval-banner.tsx +12 -10
- package/dist/assets/storefront/src/components/providers/cart-count-server.tsx +14 -12
- package/dist/assets/storefront/src/components/providers/company-context-guard.tsx +4 -4
- package/dist/assets/storefront/src/components/providers/company-permissions-server.tsx +2 -6
- package/dist/assets/storefront/src/components/providers/theme-provider.tsx +3 -3
- package/dist/assets/storefront/src/components/shared/breadcrumbs.tsx +4 -1
- package/dist/assets/storefront/src/components/shared/country-select.tsx +63 -67
- package/dist/assets/storefront/src/components/shared/pagination.tsx +15 -28
- package/dist/assets/storefront/src/components/shared/prefetch-link.tsx +1 -1
- package/dist/assets/storefront/src/components/shared/skeletons/search-input-skeleton.tsx +1 -3
- package/dist/assets/storefront/src/components/ui/accordion.tsx +46 -51
- package/dist/assets/storefront/src/components/ui/alert-dialog.tsx +94 -121
- package/dist/assets/storefront/src/components/ui/alert.tsx +48 -54
- package/dist/assets/storefront/src/components/ui/aspect-ratio.tsx +5 -7
- package/dist/assets/storefront/src/components/ui/avatar.tsx +29 -44
- package/dist/assets/storefront/src/components/ui/badge.tsx +28 -37
- package/dist/assets/storefront/src/components/ui/breadcrumb.tsx +82 -89
- package/dist/assets/storefront/src/components/ui/button.tsx +43 -49
- package/dist/assets/storefront/src/components/ui/calendar.tsx +157 -198
- package/dist/assets/storefront/src/components/ui/card.tsx +53 -76
- package/dist/assets/storefront/src/components/ui/carousel.tsx +194 -212
- package/dist/assets/storefront/src/components/ui/chart.tsx +274 -317
- package/dist/assets/storefront/src/components/ui/checkbox.tsx +24 -27
- package/dist/assets/storefront/src/components/ui/collapsible.tsx +9 -21
- package/dist/assets/storefront/src/components/ui/command.tsx +114 -159
- package/dist/assets/storefront/src/components/ui/context-menu.tsx +167 -199
- package/dist/assets/storefront/src/components/ui/dialog.tsx +97 -114
- package/dist/assets/storefront/src/components/ui/drawer.tsx +93 -107
- package/dist/assets/storefront/src/components/ui/dropdown-menu.tsx +171 -206
- package/dist/assets/storefront/src/components/ui/empty-state.tsx +5 -5
- package/dist/assets/storefront/src/components/ui/field.tsx +196 -208
- package/dist/assets/storefront/src/components/ui/form.tsx +115 -139
- package/dist/assets/storefront/src/components/ui/hover-card.tsx +27 -33
- package/dist/assets/storefront/src/components/ui/input-otp.tsx +50 -59
- package/dist/assets/storefront/src/components/ui/input.tsx +17 -17
- package/dist/assets/storefront/src/components/ui/kbd-shortcut.tsx +3 -1
- package/dist/assets/storefront/src/components/ui/label.tsx +16 -19
- package/dist/assets/storefront/src/components/ui/menubar.tsx +193 -223
- package/dist/assets/storefront/src/components/ui/navigation-menu.tsx +123 -130
- package/dist/assets/storefront/src/components/ui/pagination.tsx +87 -108
- package/dist/assets/storefront/src/components/ui/popover.tsx +29 -35
- package/dist/assets/storefront/src/components/ui/progress.tsx +19 -26
- package/dist/assets/storefront/src/components/ui/radio-group.tsx +32 -38
- package/dist/assets/storefront/src/components/ui/resizable.tsx +37 -42
- package/dist/assets/storefront/src/components/ui/scroll-area.tsx +41 -47
- package/dist/assets/storefront/src/components/ui/select.tsx +130 -152
- package/dist/assets/storefront/src/components/ui/separator.tsx +21 -21
- package/dist/assets/storefront/src/components/ui/sheet.tsx +90 -111
- package/dist/assets/storefront/src/components/ui/sidebar.tsx +611 -649
- package/dist/assets/storefront/src/components/ui/skeleton.tsx +10 -10
- package/dist/assets/storefront/src/components/ui/slider.tsx +50 -55
- package/dist/assets/storefront/src/components/ui/sonner.tsx +20 -20
- package/dist/assets/storefront/src/components/ui/switch.tsx +23 -26
- package/dist/assets/storefront/src/components/ui/table.tsx +65 -97
- package/dist/assets/storefront/src/components/ui/tabs.tsx +39 -55
- package/dist/assets/storefront/src/components/ui/textarea.tsx +14 -14
- package/dist/assets/storefront/src/components/ui/toggle-group.tsx +56 -62
- package/dist/assets/storefront/src/components/ui/toggle.tsx +37 -38
- package/dist/assets/storefront/src/components/ui/tooltip.tsx +38 -46
- package/dist/assets/storefront/src/config/scenario-meta.ts +2 -2
- package/dist/assets/storefront/src/config/scenario.ts +14 -16
- package/dist/assets/storefront/src/contexts/auth-context.tsx +5 -6
- package/dist/assets/storefront/src/graphql-env.d.ts +18 -5
- package/dist/assets/storefront/src/graphql.ts +5 -5
- package/dist/assets/storefront/src/hooks/use-mobile.ts +13 -13
- package/dist/assets/storefront/src/i18n/locale-utils.ts +3 -3
- package/dist/assets/storefront/src/i18n/navigation.ts +4 -4
- package/dist/assets/storefront/src/i18n/request.ts +4 -4
- package/dist/assets/storefront/src/i18n/routing.ts +5 -5
- package/dist/assets/storefront/src/i18n/server.ts +3 -3
- package/dist/assets/storefront/src/lib/actions/switch-channel.ts +9 -9
- package/dist/assets/storefront/src/lib/actions/switch-currency.ts +7 -7
- package/dist/assets/storefront/src/lib/auth.ts +1 -1
- package/dist/assets/storefront/src/lib/backend-health.ts +3 -3
- package/dist/assets/storefront/src/lib/cart-count-context.tsx +10 -4
- package/dist/assets/storefront/src/lib/cart-guard-utils.ts +2 -1
- package/dist/assets/storefront/src/lib/cart-guard.ts +7 -6
- package/dist/assets/storefront/src/lib/channel-server.ts +4 -4
- package/dist/assets/storefront/src/lib/company-context.ts +1 -1
- package/dist/assets/storefront/src/lib/company-permissions-context.tsx +1 -5
- package/dist/assets/storefront/src/lib/currency-server.ts +4 -4
- package/dist/assets/storefront/src/lib/format.ts +16 -7
- package/dist/assets/storefront/src/lib/metadata.ts +39 -44
- package/dist/assets/storefront/src/lib/quantity.ts +2 -4
- package/dist/assets/storefront/src/lib/search-bar-context.tsx +7 -4
- package/dist/assets/storefront/src/lib/use-recent-searches.ts +8 -6
- package/dist/assets/storefront/src/lib/utils.ts +3 -3
- package/dist/assets/storefront/src/lib/vendure/actions.ts +18 -16
- package/dist/assets/storefront/src/lib/vendure/api.ts +44 -27
- package/dist/assets/storefront/src/lib/vendure/approval-utils.ts +9 -8
- package/dist/assets/storefront/src/lib/vendure/cached.ts +20 -15
- package/dist/assets/storefront/src/lib/vendure/mutations.ts +96 -0
- package/dist/assets/storefront/src/lib/vendure/queries.ts +157 -5
- package/dist/assets/storefront/src/middleware.ts +1 -1
- package/dist/assets/storefront/src/scenarios/customer/hero.tsx +2 -2
- package/dist/assets/storefront/src/scenarios/customer/meta.ts +1 -1
- package/dist/assets/storefront/src/schema.graphql +134 -0
- package/dist/bin/run.js +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/plugin-registry.js +1 -1
- package/dist/scaffold-storefront-only.js +1 -1
- package/dist/scaffolder.js +1 -1
- package/dist/template-renderer.js +1 -1
- package/package.json +2 -2
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {CartItems as DefaultCartItems} from
|
|
2
|
-
import {OrderSummary} from
|
|
3
|
-
import {PromotionCode} from
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {getTranslations} from 'next-intl/server';
|
|
14
|
-
import {
|
|
1
|
+
import { CartItems as DefaultCartItems } from '@/app/[locale]/cart/cart-items';
|
|
2
|
+
import { OrderSummary } from '@/app/[locale]/cart/order-summary';
|
|
3
|
+
import { PromotionCode } from '@/app/[locale]/cart/promotion-code';
|
|
4
|
+
import { CancelQuoteCheckoutButton } from '@/app/[locale]/checkout/cancel-quote-checkout-button';
|
|
5
|
+
import { Button } from '@/components/ui/button';
|
|
6
|
+
import { getScenarioConfig } from '@/config/scenario';
|
|
7
|
+
import { Link } from '@/i18n/navigation';
|
|
8
|
+
import type { VendureContext } from '@/lib/vendure/api';
|
|
9
|
+
import { client, getVendureContext } from '@/lib/vendure/api';
|
|
10
|
+
import { getLatestApprovalForOrder } from '@/lib/vendure/approval-utils';
|
|
11
|
+
import { GetActiveOrderQuery } from '@/lib/vendure/queries';
|
|
12
|
+
import { FileText, MessageSquare } from 'lucide-react';
|
|
13
|
+
import { getTranslations } from 'next-intl/server';
|
|
14
|
+
import { cacheTag } from 'next/cache';
|
|
15
15
|
|
|
16
16
|
// Scenario override: replace the default CartItems with the scenario-registered
|
|
17
17
|
// slot when present. The slot is a ServerComponent with the same shape as the
|
|
@@ -25,10 +25,7 @@ const CartItems = getScenarioConfig().overrides?.cart?.CartItems ?? DefaultCartI
|
|
|
25
25
|
const ScenarioCartBanner = getScenarioConfig().overrides?.cart?.Banner ?? null;
|
|
26
26
|
|
|
27
27
|
export async function Cart() {
|
|
28
|
-
const [ctx, t] = await Promise.all([
|
|
29
|
-
getVendureContext(),
|
|
30
|
-
getTranslations('Cart'),
|
|
31
|
-
]);
|
|
28
|
+
const [ctx, t] = await Promise.all([getVendureContext(), getTranslations('Cart')]);
|
|
32
29
|
return (
|
|
33
30
|
<CartCached
|
|
34
31
|
ctx={ctx}
|
|
@@ -59,14 +56,14 @@ async function CartCached({
|
|
|
59
56
|
changesRequestedLabel: string;
|
|
60
57
|
changesRequestedMessage: string;
|
|
61
58
|
}) {
|
|
62
|
-
|
|
59
|
+
'use cache: private';
|
|
63
60
|
cacheTag('cart');
|
|
64
61
|
|
|
65
62
|
const [result, error] = await client.query(GetActiveOrderQuery, {}, ctx);
|
|
66
63
|
if (error) {
|
|
67
|
-
return <CartItems activeOrder={null}/>;
|
|
64
|
+
return <CartItems activeOrder={null} />;
|
|
68
65
|
}
|
|
69
|
-
const {data} = result;
|
|
66
|
+
const { data } = result;
|
|
70
67
|
|
|
71
68
|
const activeOrder = data.activeOrder;
|
|
72
69
|
|
|
@@ -93,16 +90,19 @@ async function CartCached({
|
|
|
93
90
|
<div className="rounded-lg border border-primary/30 bg-primary/10 p-4">
|
|
94
91
|
<div className="flex items-center justify-between">
|
|
95
92
|
<div className="flex gap-3">
|
|
96
|
-
<FileText className="h-5 w-5 text-primary flex-shrink-0 mt-0.5"/>
|
|
93
|
+
<FileText className="h-5 w-5 text-primary flex-shrink-0 mt-0.5" />
|
|
97
94
|
<div>
|
|
98
95
|
<h3 className="font-medium text-foreground">{quoteCheckoutTitle}</h3>
|
|
99
|
-
<p className="text-sm text-muted-foreground mt-1">
|
|
100
|
-
{quoteCheckoutMessage}
|
|
101
|
-
</p>
|
|
96
|
+
<p className="text-sm text-muted-foreground mt-1">{quoteCheckoutMessage}</p>
|
|
102
97
|
</div>
|
|
103
98
|
</div>
|
|
104
99
|
<div className="flex items-center gap-2 shrink-0 ml-4">
|
|
105
|
-
<Button
|
|
100
|
+
<Button
|
|
101
|
+
asChild
|
|
102
|
+
variant="outline"
|
|
103
|
+
size="sm"
|
|
104
|
+
className="border-primary/40 text-primary hover:bg-primary/10"
|
|
105
|
+
>
|
|
106
106
|
<Link href={`/account/quotes/${sourceQuoteId}`}>{viewQuote}</Link>
|
|
107
107
|
</Button>
|
|
108
108
|
<CancelQuoteCheckoutButton />
|
|
@@ -112,7 +112,7 @@ async function CartCached({
|
|
|
112
112
|
<div className="grid lg:grid-cols-3 gap-8">
|
|
113
113
|
<CartItems activeOrder={activeOrder} readOnly />
|
|
114
114
|
<div className="lg:col-span-1">
|
|
115
|
-
<OrderSummary activeOrder={activeOrder}/>
|
|
115
|
+
<OrderSummary activeOrder={activeOrder} />
|
|
116
116
|
</div>
|
|
117
117
|
</div>
|
|
118
118
|
</div>
|
|
@@ -120,26 +120,23 @@ async function CartCached({
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Check if this order was returned from an approval flow with changes requested
|
|
123
|
-
const { latestApproval, changesRequested, changesComment } = await getLatestApprovalForOrder(
|
|
123
|
+
const { latestApproval, changesRequested, changesComment } = await getLatestApprovalForOrder(
|
|
124
|
+
activeOrder.id,
|
|
125
|
+
ctx,
|
|
126
|
+
);
|
|
124
127
|
const wasApproved = latestApproval?.status === 'APPROVED';
|
|
125
128
|
|
|
126
129
|
return (
|
|
127
130
|
<div className="space-y-6">
|
|
128
131
|
{ScenarioCartBanner && <ScenarioCartBanner />}
|
|
129
|
-
{wasApproved &&
|
|
130
|
-
<p className="text-sm text-muted-foreground">
|
|
131
|
-
{approvedOrderWarning}
|
|
132
|
-
</p>
|
|
133
|
-
)}
|
|
132
|
+
{wasApproved && <p className="text-sm text-muted-foreground">{approvedOrderWarning}</p>}
|
|
134
133
|
{changesRequested && (
|
|
135
134
|
<div className="rounded-lg border border-destructive/30 bg-destructive/10 p-4">
|
|
136
135
|
<div className="flex gap-3">
|
|
137
|
-
<MessageSquare className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5"/>
|
|
136
|
+
<MessageSquare className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5" />
|
|
138
137
|
<div>
|
|
139
138
|
<h3 className="font-medium text-foreground">{changesRequestedLabel}</h3>
|
|
140
|
-
<p className="text-sm text-muted-foreground mt-1">
|
|
141
|
-
{changesRequestedMessage}
|
|
142
|
-
</p>
|
|
139
|
+
<p className="text-sm text-muted-foreground mt-1">{changesRequestedMessage}</p>
|
|
143
140
|
{changesComment && (
|
|
144
141
|
<blockquote className="mt-2 border-l-2 border-destructive/40 pl-3 text-sm text-muted-foreground italic">
|
|
145
142
|
“{changesComment}”
|
|
@@ -150,13 +147,13 @@ async function CartCached({
|
|
|
150
147
|
</div>
|
|
151
148
|
)}
|
|
152
149
|
<div className="grid lg:grid-cols-3 gap-8">
|
|
153
|
-
<CartItems activeOrder={activeOrder} wasApproved={wasApproved}/>
|
|
150
|
+
<CartItems activeOrder={activeOrder} wasApproved={wasApproved} />
|
|
154
151
|
|
|
155
152
|
<div className="lg:col-span-1 sticky top-20 space-y-4">
|
|
156
|
-
<OrderSummary activeOrder={activeOrder}/>
|
|
157
|
-
<PromotionCode activeOrder={activeOrder}/>
|
|
153
|
+
<OrderSummary activeOrder={activeOrder} />
|
|
154
|
+
<PromotionCode activeOrder={activeOrder} />
|
|
158
155
|
</div>
|
|
159
156
|
</div>
|
|
160
157
|
</div>
|
|
161
|
-
)
|
|
158
|
+
);
|
|
162
159
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import { Input } from '@/components/ui/input';
|
|
5
|
+
import { useRouter } from '@/i18n/navigation';
|
|
6
|
+
import { Loader2 } from 'lucide-react';
|
|
7
|
+
import { useTranslations } from 'next-intl';
|
|
8
|
+
import { useRef, useTransition } from 'react';
|
|
9
|
+
import { toast } from 'sonner';
|
|
10
|
+
import { applyCode } from './actions';
|
|
11
11
|
|
|
12
12
|
export function CodeInput() {
|
|
13
13
|
const t = useTranslations('Cart');
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {getAuthToken} from '@/lib/auth';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { AddToSharedCart } from '@/components/commerce/add-to-shared-cart';
|
|
2
|
+
import { Price } from '@/components/commerce/price';
|
|
3
|
+
import { canCreateSharedCarts } from '@/components/commerce/shared-cart-role';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
import { Link } from '@/i18n/navigation';
|
|
6
|
+
import { getAuthToken } from '@/lib/auth';
|
|
7
|
+
import { maskCode } from '@/lib/format';
|
|
8
|
+
import { getActiveCustomer, getCompanyAccount } from '@/lib/vendure/actions';
|
|
9
|
+
import { getTranslations } from 'next-intl/server';
|
|
10
|
+
import { RequestQuoteButton } from './request-quote-button';
|
|
9
11
|
|
|
10
12
|
type ActiveOrder = {
|
|
11
13
|
id: string;
|
|
@@ -46,13 +48,13 @@ type ActiveOrder = {
|
|
|
46
48
|
}> | null;
|
|
47
49
|
};
|
|
48
50
|
|
|
49
|
-
export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder }) {
|
|
51
|
+
export async function OrderSummary({ activeOrder }: { activeOrder: ActiveOrder }) {
|
|
50
52
|
const t = await getTranslations('Cart');
|
|
51
53
|
const hasCreditsApplied = activeOrder.storeCreditsApplied.length > 0;
|
|
52
54
|
const authToken = await getAuthToken();
|
|
53
55
|
const taxTotal = activeOrder.totalWithTax - activeOrder.total;
|
|
54
56
|
const MIN_QTY_FOR_QUOTE = 50;
|
|
55
|
-
const hasHighQuantityLine = activeOrder.lines.some(line => line.quantity >= MIN_QTY_FOR_QUOTE);
|
|
57
|
+
const hasHighQuantityLine = activeOrder.lines.some((line) => line.quantity >= MIN_QTY_FOR_QUOTE);
|
|
56
58
|
|
|
57
59
|
// Check PlaceOrders permission for company users
|
|
58
60
|
const companyAccount = await getCompanyAccount();
|
|
@@ -71,6 +73,13 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
const canShareCart = canCreateSharedCarts(companyAccount?.permissions);
|
|
77
|
+
let shareDefaultName = 'Shared cart';
|
|
78
|
+
if (canShareCart) {
|
|
79
|
+
const customer = await getActiveCustomer();
|
|
80
|
+
if (customer?.firstName) shareDefaultName = `${customer.firstName}'s shared cart`;
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
return (
|
|
75
84
|
<div className="border rounded-lg p-6 bg-card">
|
|
76
85
|
<h2 className="text-xl font-bold mb-4">{t('orderSummary')}</h2>
|
|
@@ -79,7 +88,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
79
88
|
<div className="flex justify-between text-sm">
|
|
80
89
|
<span className="text-muted-foreground">{t('subtotal')}</span>
|
|
81
90
|
<span>
|
|
82
|
-
<Price value={activeOrder.subTotal} currencyCode={activeOrder.currencyCode}/>
|
|
91
|
+
<Price value={activeOrder.subTotal} currencyCode={activeOrder.currencyCode} />
|
|
83
92
|
</span>
|
|
84
93
|
</div>
|
|
85
94
|
{activeOrder.discounts && activeOrder.discounts.length > 0 && (
|
|
@@ -88,7 +97,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
88
97
|
<div key={index} className="flex justify-between text-sm text-green-600">
|
|
89
98
|
<span>{discount.description}</span>
|
|
90
99
|
<span>
|
|
91
|
-
<Price value={discount.amount} currencyCode={activeOrder.currencyCode}/>
|
|
100
|
+
<Price value={discount.amount} currencyCode={activeOrder.currencyCode} />
|
|
92
101
|
</span>
|
|
93
102
|
</div>
|
|
94
103
|
))}
|
|
@@ -97,9 +106,11 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
97
106
|
<div className="flex justify-between text-sm">
|
|
98
107
|
<span className="text-muted-foreground">{t('shipping')}</span>
|
|
99
108
|
<span>
|
|
100
|
-
{activeOrder.shipping > 0
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
{activeOrder.shipping > 0 ? (
|
|
110
|
+
<Price value={activeOrder.shipping} currencyCode={activeOrder.currencyCode} />
|
|
111
|
+
) : (
|
|
112
|
+
t('calculatedAtCheckout')
|
|
113
|
+
)}
|
|
103
114
|
</span>
|
|
104
115
|
</div>
|
|
105
116
|
{activeOrder.taxSummary && activeOrder.taxSummary.length > 0 ? (
|
|
@@ -109,7 +120,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
109
120
|
{tax.description} ({tax.taxRate}%)
|
|
110
121
|
</span>
|
|
111
122
|
<span>
|
|
112
|
-
<Price value={tax.taxTotal} currencyCode={activeOrder.currencyCode}/>
|
|
123
|
+
<Price value={tax.taxTotal} currencyCode={activeOrder.currencyCode} />
|
|
113
124
|
</span>
|
|
114
125
|
</div>
|
|
115
126
|
))
|
|
@@ -117,16 +128,23 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
117
128
|
<div className="flex justify-between text-sm">
|
|
118
129
|
<span className="text-muted-foreground">{t('tax')}</span>
|
|
119
130
|
<span>
|
|
120
|
-
<Price value={taxTotal} currencyCode={activeOrder.currencyCode}/>
|
|
131
|
+
<Price value={taxTotal} currencyCode={activeOrder.currencyCode} />
|
|
121
132
|
</span>
|
|
122
133
|
</div>
|
|
123
134
|
)}
|
|
124
|
-
{hasCreditsApplied &&
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
135
|
+
{hasCreditsApplied &&
|
|
136
|
+
activeOrder.storeCreditsApplied.map((credit) => (
|
|
137
|
+
<div key={credit.code} className="flex justify-between text-sm text-green-600">
|
|
138
|
+
<span>{t('storeCredit', { code: maskCode(credit.code) })}</span>
|
|
139
|
+
<span>
|
|
140
|
+
-
|
|
141
|
+
<Price
|
|
142
|
+
value={credit.amountDeducted}
|
|
143
|
+
currencyCode={activeOrder.currencyCode}
|
|
144
|
+
/>
|
|
145
|
+
</span>
|
|
146
|
+
</div>
|
|
147
|
+
))}
|
|
130
148
|
</div>
|
|
131
149
|
|
|
132
150
|
<div className="border-t pt-4 mb-6">
|
|
@@ -136,12 +154,23 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
136
154
|
{hasCreditsApplied ? (
|
|
137
155
|
<span className="flex items-center gap-2">
|
|
138
156
|
<span className="text-sm font-normal text-muted-foreground line-through">
|
|
139
|
-
<Price
|
|
157
|
+
<Price
|
|
158
|
+
value={activeOrder.totalWithTax}
|
|
159
|
+
currencyCode={activeOrder.currencyCode}
|
|
160
|
+
/>
|
|
140
161
|
</span>
|
|
141
|
-
<Price
|
|
162
|
+
<Price
|
|
163
|
+
value={activeOrder.totalWithTaxAfterStoreCredit}
|
|
164
|
+
currencyCode={activeOrder.currencyCode}
|
|
165
|
+
taxLabel="incl"
|
|
166
|
+
/>
|
|
142
167
|
</span>
|
|
143
168
|
) : (
|
|
144
|
-
<Price
|
|
169
|
+
<Price
|
|
170
|
+
value={activeOrder.totalWithTax}
|
|
171
|
+
currencyCode={activeOrder.currencyCode}
|
|
172
|
+
taxLabel="incl"
|
|
173
|
+
/>
|
|
145
174
|
)}
|
|
146
175
|
</span>
|
|
147
176
|
</div>
|
|
@@ -156,9 +185,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
156
185
|
<Button className="w-full" size="lg" disabled>
|
|
157
186
|
{t('checkoutNotPermitted')}
|
|
158
187
|
</Button>
|
|
159
|
-
<p className="text-xs text-muted-foreground text-center">
|
|
160
|
-
{t('noOrderingPermissions')}
|
|
161
|
-
</p>
|
|
188
|
+
<p className="text-xs text-muted-foreground text-center">{t('noOrderingPermissions')}</p>
|
|
162
189
|
</div>
|
|
163
190
|
)}
|
|
164
191
|
|
|
@@ -170,6 +197,20 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
170
197
|
/>
|
|
171
198
|
)}
|
|
172
199
|
|
|
200
|
+
{canShareCart && activeOrder.lines.length > 0 && (
|
|
201
|
+
<AddToSharedCart
|
|
202
|
+
lines={activeOrder.lines.map((line) => ({
|
|
203
|
+
productVariantId: line.productVariant.id,
|
|
204
|
+
quantity: line.quantity,
|
|
205
|
+
}))}
|
|
206
|
+
canCreate
|
|
207
|
+
defaultName={shareDefaultName}
|
|
208
|
+
label="Share this cart"
|
|
209
|
+
size="default"
|
|
210
|
+
className="w-full mt-2 gap-2"
|
|
211
|
+
/>
|
|
212
|
+
)}
|
|
213
|
+
|
|
173
214
|
<Button variant="outline" className="w-full mt-2" asChild>
|
|
174
215
|
<Link href="/">{t('continueShopping')}</Link>
|
|
175
216
|
</Button>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { Cart } from '@/app/[locale]/cart/cart';
|
|
2
|
+
import { CartSkeleton } from '@/components/shared/skeletons/cart-skeleton';
|
|
3
|
+
import { type Locale } from '@/i18n/routing';
|
|
4
|
+
import { noIndexRobots } from '@/lib/metadata';
|
|
5
|
+
import type { Metadata } from 'next';
|
|
6
|
+
import { getTranslations } from 'next-intl/server';
|
|
7
|
+
import { locale as rootLocale } from 'next/root-params';
|
|
8
|
+
import { Suspense } from 'react';
|
|
9
9
|
|
|
10
10
|
export async function generateMetadata(): Promise<Metadata> {
|
|
11
11
|
const locale = (await rootLocale()) as Locale;
|
|
12
|
-
const t = await getTranslations({locale, namespace: 'Cart'});
|
|
12
|
+
const t = await getTranslations({ locale, namespace: 'Cart' });
|
|
13
13
|
return {
|
|
14
14
|
title: t('title'),
|
|
15
15
|
description: t('description'),
|
|
@@ -19,14 +19,14 @@ export async function generateMetadata(): Promise<Metadata> {
|
|
|
19
19
|
|
|
20
20
|
export default async function CartPage() {
|
|
21
21
|
const locale = (await rootLocale()) as Locale;
|
|
22
|
-
const t = await getTranslations({locale, namespace: 'Cart'});
|
|
22
|
+
const t = await getTranslations({ locale, namespace: 'Cart' });
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<div className="container mx-auto px-4 py-8 mt-[var(--page-top-offset)]">
|
|
26
26
|
<h1 className="text-3xl font-bold mb-8">{t('title')}</h1>
|
|
27
27
|
|
|
28
28
|
<Suspense fallback={<CartSkeleton />}>
|
|
29
|
-
<Cart/>
|
|
29
|
+
<Cart />
|
|
30
30
|
</Suspense>
|
|
31
31
|
</div>
|
|
32
32
|
);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {client} from '@/lib/vendure/api';
|
|
7
|
-
import {GetMyStoreCreditsQuery} from '@/lib/vendure/queries';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
1
|
+
import { Price } from '@/components/commerce/price';
|
|
2
|
+
import { Button } from '@/components/ui/button';
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
4
|
+
import { maskCode } from '@/lib/format';
|
|
5
|
+
import { getActiveCustomer } from '@/lib/vendure/actions';
|
|
6
|
+
import { client } from '@/lib/vendure/api';
|
|
7
|
+
import { GetMyStoreCreditsQuery } from '@/lib/vendure/queries';
|
|
8
|
+
import { Tag, Wallet } from 'lucide-react';
|
|
9
|
+
import { getTranslations } from 'next-intl/server';
|
|
10
|
+
import { applyStoreCredit, removePromotionCode, removeStoreCredit } from './actions';
|
|
11
|
+
import { CodeInput } from './code-input';
|
|
12
12
|
|
|
13
13
|
const MAX_STORE_CREDITS_IN_CART = 100;
|
|
14
14
|
|
|
@@ -20,46 +20,48 @@ type ActiveOrder = {
|
|
|
20
20
|
currencyCode: string;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder }) {
|
|
23
|
+
export async function PromotionCode({ activeOrder }: { activeOrder: ActiveOrder }) {
|
|
24
24
|
const [t, activeCustomer, [creditsResult, creditsError]] = await Promise.all([
|
|
25
25
|
getTranslations('Cart'),
|
|
26
26
|
getActiveCustomer(),
|
|
27
|
-
client.query(GetMyStoreCreditsQuery, {options: {take: MAX_STORE_CREDITS_IN_CART}}),
|
|
27
|
+
client.query(GetMyStoreCreditsQuery, { options: { take: MAX_STORE_CREDITS_IN_CART } }),
|
|
28
28
|
]);
|
|
29
|
-
const availableCredits = creditsError ? [] :
|
|
30
|
-
const appliedCodes = new Set(activeOrder.storeCreditsApplied.map(c => c.code));
|
|
29
|
+
const availableCredits = creditsError ? [] : creditsResult.data.myStoreCredits?.items ?? [];
|
|
30
|
+
const appliedCodes = new Set(activeOrder.storeCreditsApplied.map((c) => c.code));
|
|
31
31
|
const activeCustomerId = activeCustomer?.id;
|
|
32
32
|
// Only show credits the current customer can actually redeem (own + unclaimed)
|
|
33
33
|
// Hide when order is already fully covered by applied credits
|
|
34
34
|
const orderFullyCovered = activeOrder.totalWithTaxAfterStoreCredit <= 0;
|
|
35
|
-
const redeemableCredits = orderFullyCovered
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const redeemableCredits = orderFullyCovered
|
|
36
|
+
? []
|
|
37
|
+
: availableCredits.filter(
|
|
38
|
+
(c) => !appliedCodes.has(c.code) && (!c.issuedTo || c.issuedTo.id === activeCustomerId),
|
|
39
|
+
);
|
|
38
40
|
|
|
39
41
|
return (
|
|
40
42
|
<Card>
|
|
41
43
|
<CardHeader>
|
|
42
44
|
<CardTitle className="text-lg flex items-center gap-2">
|
|
43
|
-
<Tag className="h-5 w-5"/>
|
|
45
|
+
<Tag className="h-5 w-5" />
|
|
44
46
|
{t('promotionCode')}
|
|
45
47
|
</CardTitle>
|
|
46
|
-
<CardDescription>
|
|
47
|
-
{t('enterDiscountCode')}
|
|
48
|
-
</CardDescription>
|
|
48
|
+
<CardDescription>{t('enterDiscountCode')}</CardDescription>
|
|
49
49
|
</CardHeader>
|
|
50
50
|
<CardContent className="space-y-4">
|
|
51
51
|
{/* Applied coupon codes */}
|
|
52
52
|
{activeOrder.couponCodes && activeOrder.couponCodes.length > 0 && (
|
|
53
53
|
<div className="space-y-2">
|
|
54
54
|
{activeOrder.couponCodes.map((code) => (
|
|
55
|
-
<div
|
|
56
|
-
|
|
55
|
+
<div
|
|
56
|
+
key={code}
|
|
57
|
+
className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20"
|
|
58
|
+
>
|
|
57
59
|
<div className="flex items-center gap-2">
|
|
58
|
-
<Tag className="h-4 w-4 text-green-600"/>
|
|
60
|
+
<Tag className="h-4 w-4 text-green-600" />
|
|
59
61
|
<span className="font-medium text-sm">{code}</span>
|
|
60
62
|
</div>
|
|
61
63
|
<form action={removePromotionCode}>
|
|
62
|
-
<input type="hidden" name="code" value={code}/>
|
|
64
|
+
<input type="hidden" name="code" value={code} />
|
|
63
65
|
<Button
|
|
64
66
|
type="submit"
|
|
65
67
|
variant="ghost"
|
|
@@ -78,19 +80,23 @@ export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
78
80
|
{activeOrder.storeCreditsApplied.length > 0 && (
|
|
79
81
|
<div className="space-y-2">
|
|
80
82
|
{activeOrder.storeCreditsApplied.map((credit) => (
|
|
81
|
-
<div
|
|
82
|
-
|
|
83
|
+
<div
|
|
84
|
+
key={credit.code}
|
|
85
|
+
className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20"
|
|
86
|
+
>
|
|
83
87
|
<div className="flex items-center gap-2">
|
|
84
|
-
<Wallet className="h-4 w-4 text-green-600"/>
|
|
85
|
-
<span className="font-medium text-sm">
|
|
86
|
-
{maskCode(credit.code)}
|
|
87
|
-
</span>
|
|
88
|
+
<Wallet className="h-4 w-4 text-green-600" />
|
|
89
|
+
<span className="font-medium text-sm">{maskCode(credit.code)}</span>
|
|
88
90
|
<span className="text-xs text-green-600">
|
|
89
|
-
|
|
91
|
+
-
|
|
92
|
+
<Price
|
|
93
|
+
value={credit.amountDeducted}
|
|
94
|
+
currencyCode={activeOrder.currencyCode}
|
|
95
|
+
/>
|
|
90
96
|
</span>
|
|
91
97
|
</div>
|
|
92
98
|
<form action={removeStoreCredit}>
|
|
93
|
-
<input type="hidden" name="code" value={credit.code}/>
|
|
99
|
+
<input type="hidden" name="code" value={credit.code} />
|
|
94
100
|
<Button
|
|
95
101
|
type="submit"
|
|
96
102
|
variant="ghost"
|
|
@@ -109,22 +115,22 @@ export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder })
|
|
|
109
115
|
{redeemableCredits.length > 0 && (
|
|
110
116
|
<div className="space-y-2">
|
|
111
117
|
<p className="text-xs text-muted-foreground font-medium flex items-center gap-1.5">
|
|
112
|
-
<Wallet className="h-3.5 w-3.5"/>
|
|
118
|
+
<Wallet className="h-3.5 w-3.5" />
|
|
113
119
|
{t('availableStoreCredits')}
|
|
114
120
|
</p>
|
|
115
121
|
{redeemableCredits.map((credit) => (
|
|
116
|
-
<div
|
|
117
|
-
|
|
122
|
+
<div
|
|
123
|
+
key={credit.id}
|
|
124
|
+
className="flex items-center justify-between p-3 border rounded-md"
|
|
125
|
+
>
|
|
118
126
|
<div className="flex items-center gap-2">
|
|
119
|
-
<span className="font-mono text-sm">
|
|
120
|
-
{maskCode(credit.code)}
|
|
121
|
-
</span>
|
|
127
|
+
<span className="font-mono text-sm">{maskCode(credit.code)}</span>
|
|
122
128
|
<span className="text-xs text-muted-foreground">
|
|
123
|
-
<Price value={credit.balance} currencyCode={credit.currencyCode}/>
|
|
129
|
+
<Price value={credit.balance} currencyCode={credit.currencyCode} />
|
|
124
130
|
</span>
|
|
125
131
|
</div>
|
|
126
132
|
<form action={applyStoreCredit}>
|
|
127
|
-
<input type="hidden" name="code" value={credit.code}/>
|
|
133
|
+
<input type="hidden" name="code" value={credit.code} />
|
|
128
134
|
<Button type="submit" variant="outline" size="sm" className="h-8">
|
|
129
135
|
{t('apply')}
|
|
130
136
|
</Button>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {useState, useCallback, useRef} from 'react';
|
|
4
3
|
import {
|
|
5
4
|
AlertDialog,
|
|
6
5
|
AlertDialogAction,
|
|
@@ -11,7 +10,8 @@ import {
|
|
|
11
10
|
AlertDialogHeader,
|
|
12
11
|
AlertDialogTitle,
|
|
13
12
|
} from '@/components/ui/alert-dialog';
|
|
14
|
-
import {useTranslations} from 'next-intl';
|
|
13
|
+
import { useTranslations } from 'next-intl';
|
|
14
|
+
import { useCallback, useRef, useState } from 'react';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Hook that provides a confirmation gate for actions that would invalidate
|
|
@@ -26,23 +26,27 @@ export function useReapprovalConfirm(requiresReapproval?: boolean | (() => Promi
|
|
|
26
26
|
const [isChecking, setIsChecking] = useState(false);
|
|
27
27
|
const pendingActionRef = useRef<(() => void) | null>(null);
|
|
28
28
|
|
|
29
|
-
const guardCartChange = useCallback(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
const guardCartChange = useCallback(
|
|
30
|
+
async (action: () => void) => {
|
|
31
|
+
setIsChecking(true);
|
|
32
|
+
try {
|
|
33
|
+
const needsConfirmation =
|
|
34
|
+
typeof requiresReapproval === 'function'
|
|
35
|
+
? await requiresReapproval()
|
|
36
|
+
: requiresReapproval;
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
if (needsConfirmation) {
|
|
39
|
+
pendingActionRef.current = action;
|
|
40
|
+
setOpen(true);
|
|
41
|
+
} else {
|
|
42
|
+
action();
|
|
43
|
+
}
|
|
44
|
+
} finally {
|
|
45
|
+
setIsChecking(false);
|
|
41
46
|
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}, [requiresReapproval]);
|
|
47
|
+
},
|
|
48
|
+
[requiresReapproval],
|
|
49
|
+
);
|
|
46
50
|
|
|
47
51
|
const handleConfirm = useCallback(() => {
|
|
48
52
|
setOpen(false);
|
|
@@ -60,9 +64,7 @@ export function useReapprovalConfirm(requiresReapproval?: boolean | (() => Promi
|
|
|
60
64
|
<AlertDialogContent>
|
|
61
65
|
<AlertDialogHeader>
|
|
62
66
|
<AlertDialogTitle>{t('reapprovalTitle')}</AlertDialogTitle>
|
|
63
|
-
<AlertDialogDescription>
|
|
64
|
-
{t('reapprovalMessage')}
|
|
65
|
-
</AlertDialogDescription>
|
|
67
|
+
<AlertDialogDescription>{t('reapprovalMessage')}</AlertDialogDescription>
|
|
66
68
|
</AlertDialogHeader>
|
|
67
69
|
<AlertDialogFooter>
|
|
68
70
|
<AlertDialogCancel onClick={handleCancel}>{t('cancel')}</AlertDialogCancel>
|