@vendure-platform/create 0.5.0 → 0.5.2
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/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 +64 -38
- 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]/add-item-search.tsx +11 -9
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-member-form.tsx +31 -15
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/members-panel.tsx +52 -33
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/page.tsx +22 -14
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/rename-dialog.tsx +34 -13
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/actions.ts +117 -72
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/new-shared-cart-form.tsx +21 -14
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/page.tsx +10 -10
- package/dist/assets/storefront/src/app/[locale]/account/shared-carts/page.tsx +54 -41
- 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 +50 -32
- 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 +43 -18
- 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 +49 -27
- 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 +118 -74
- 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-status-badge.tsx +12 -8
- 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.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 +36 -23
- 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/queries.ts +15 -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/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/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,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { createContext,
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
interface CartCountContextType {
|
|
6
6
|
count: number;
|
|
@@ -13,11 +13,17 @@ interface CartCountContextType {
|
|
|
13
13
|
|
|
14
14
|
const CartCountContext = createContext<CartCountContextType | null>(null);
|
|
15
15
|
|
|
16
|
-
export function CartCountProvider({
|
|
16
|
+
export function CartCountProvider({
|
|
17
|
+
initialCount,
|
|
18
|
+
children,
|
|
19
|
+
}: {
|
|
20
|
+
initialCount: number;
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
}) {
|
|
17
23
|
const [count, setCount] = useState(initialCount);
|
|
18
24
|
const [awaitingApprovalOrderCode, setAwaitingApprovalOrderCode] = useState<string | null>(null);
|
|
19
|
-
const increment = useCallback(() => setCount(c => c + 1), []);
|
|
20
|
-
const decrement = useCallback(() => setCount(c => Math.max(0, c - 1)), []);
|
|
25
|
+
const increment = useCallback(() => setCount((c) => c + 1), []);
|
|
26
|
+
const decrement = useCallback(() => setCount((c) => Math.max(0, c - 1)), []);
|
|
21
27
|
|
|
22
28
|
return (
|
|
23
29
|
<CartCountContext.Provider
|
|
@@ -6,5 +6,6 @@ import type { CartGuardResult } from './cart-guard';
|
|
|
6
6
|
*/
|
|
7
7
|
export function getGuardError(guard: CartGuardResult): string | undefined {
|
|
8
8
|
if (guard.blocked) return 'Order is awaiting approval and cannot be modified';
|
|
9
|
-
if (guard.quoteLocked)
|
|
9
|
+
if (guard.quoteLocked)
|
|
10
|
+
return 'You have a quote checkout in progress. Complete checkout or cancel the quote checkout to modify your cart.';
|
|
10
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
|
|
3
3
|
import { client } from '@/lib/vendure/api';
|
|
4
|
-
import { GetActiveOrderQuery, GetApprovalHistoryForEntityQuery } from '@/lib/vendure/queries';
|
|
5
4
|
import { TransitionOrderToStateMutation } from '@/lib/vendure/mutations';
|
|
5
|
+
import { GetActiveOrderQuery, GetApprovalHistoryForEntityQuery } from '@/lib/vendure/queries';
|
|
6
6
|
|
|
7
7
|
export interface CartGuardResult {
|
|
8
8
|
/** Whether the order was in a non-AddingItems state and had to be transitioned */
|
|
@@ -23,12 +23,13 @@ export interface CartGuardResult {
|
|
|
23
23
|
* and the full cart guard.
|
|
24
24
|
*/
|
|
25
25
|
async function checkOrderApprovalStatus(orderId: string): Promise<boolean> {
|
|
26
|
-
const [approvalResult] = await client.query(
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const [approvalResult] = await client.query(GetApprovalHistoryForEntityQuery, {
|
|
27
|
+
entityType: 'Order',
|
|
28
|
+
entityId: orderId,
|
|
29
|
+
});
|
|
30
|
+
const history = [...(approvalResult?.data?.approvalHistoryForEntity ?? [])].sort(
|
|
31
|
+
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
|
29
32
|
);
|
|
30
|
-
const history = [...(approvalResult?.data?.approvalHistoryForEntity ?? [])]
|
|
31
|
-
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
32
33
|
const latestApproval = history[0] ?? null;
|
|
33
34
|
return latestApproval?.status === 'APPROVED';
|
|
34
35
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getChannelsConfig } from '@/config/scenario';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
3
|
+
import { CHANNEL_COOKIE } from './channel';
|
|
4
4
|
|
|
5
5
|
const FALLBACK_TOKEN = process.env.VENDURE_CHANNEL_TOKEN || process.env.NEXT_PUBLIC_VENDURE_CHANNEL_TOKEN;
|
|
6
6
|
|
|
@@ -20,7 +20,7 @@ export async function getActiveChannelToken(): Promise<string | undefined> {
|
|
|
20
20
|
const cookie = jar.get(CHANNEL_COOKIE)?.value;
|
|
21
21
|
|
|
22
22
|
// Validate: cookie token must be one of the declared available tokens
|
|
23
|
-
if (cookie && channelsConfig.available.some(c => c.token === cookie)) {
|
|
23
|
+
if (cookie && channelsConfig.available.some((c) => c.token === cookie)) {
|
|
24
24
|
return cookie;
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -28,11 +28,7 @@ export function CompanyPermissionsProvider({
|
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
return
|
|
32
|
-
<CompanyPermissionsContext.Provider value={value}>
|
|
33
|
-
{children}
|
|
34
|
-
</CompanyPermissionsContext.Provider>
|
|
35
|
-
);
|
|
31
|
+
return <CompanyPermissionsContext.Provider value={value}>{children}</CompanyPermissionsContext.Provider>;
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
export function useCompanyPermissions() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {cookies} from 'next/headers';
|
|
2
|
-
import {CURRENCY_COOKIE} from './currency';
|
|
3
|
-
import {getActiveChannelCached} from './vendure/cached';
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { CURRENCY_COOKIE } from './currency';
|
|
3
|
+
import { getActiveChannelCached } from './vendure/cached';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Resolve the active currency code from the cookie, falling back to the
|
|
@@ -13,7 +13,7 @@ export async function getActiveCurrencyCode(): Promise<string> {
|
|
|
13
13
|
// Dynamic import to avoid circular dependency: currencyMiddleware (api.ts)
|
|
14
14
|
// → getActiveCurrencyCode → channel-server → scenario.ts. Do NOT import
|
|
15
15
|
// anything from api.ts in channel-server.ts or this chain becomes circular.
|
|
16
|
-
const {getActiveChannelToken} = await import('./channel-server');
|
|
16
|
+
const { getActiveChannelToken } = await import('./channel-server');
|
|
17
17
|
const channelToken = await getActiveChannelToken();
|
|
18
18
|
const channel = await getActiveChannelCached(channelToken);
|
|
19
19
|
return channel.defaultCurrencyCode;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {toIntlLocale} from '@/i18n/locale-utils';
|
|
1
|
+
import { toIntlLocale } from '@/i18n/locale-utils';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Format a price value
|
|
@@ -6,7 +6,12 @@ import {toIntlLocale} from '@/i18n/locale-utils';
|
|
|
6
6
|
* @param locale Routing locale (e.g. 'en', 'de')
|
|
7
7
|
* @param currencyCode ISO 4217 currency code (e.g. 'EUR', 'USD')
|
|
8
8
|
*/
|
|
9
|
-
export function formatPrice(
|
|
9
|
+
export function formatPrice(
|
|
10
|
+
price: number,
|
|
11
|
+
locale: string,
|
|
12
|
+
currencyCode = 'EUR',
|
|
13
|
+
options?: Intl.NumberFormatOptions,
|
|
14
|
+
): string {
|
|
10
15
|
return new Intl.NumberFormat(toIntlLocale(locale), {
|
|
11
16
|
style: 'currency',
|
|
12
17
|
currency: currencyCode,
|
|
@@ -23,9 +28,10 @@ type DateFormat = 'short' | 'long';
|
|
|
23
28
|
* @param format 'short' (Jan 15, 2024) or 'long' (January 15, 2024)
|
|
24
29
|
*/
|
|
25
30
|
export function formatDate(dateString: string, locale: string, format: DateFormat = 'short'): string {
|
|
26
|
-
const options: Intl.DateTimeFormatOptions =
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const options: Intl.DateTimeFormatOptions =
|
|
32
|
+
format === 'long'
|
|
33
|
+
? { year: 'numeric', month: 'long', day: 'numeric' }
|
|
34
|
+
: { year: 'numeric', month: 'short', day: 'numeric' };
|
|
29
35
|
|
|
30
36
|
return new Date(dateString).toLocaleDateString(toIntlLocale(locale), options);
|
|
31
37
|
}
|
|
@@ -37,8 +43,11 @@ export function formatDate(dateString: string, locale: string, format: DateForma
|
|
|
37
43
|
*/
|
|
38
44
|
export function formatDateTime(dateString: string, locale: string): string {
|
|
39
45
|
return new Date(dateString).toLocaleString(toIntlLocale(locale), {
|
|
40
|
-
month: 'short',
|
|
41
|
-
|
|
46
|
+
month: 'short',
|
|
47
|
+
day: 'numeric',
|
|
48
|
+
year: 'numeric',
|
|
49
|
+
hour: 'numeric',
|
|
50
|
+
minute: '2-digit',
|
|
42
51
|
});
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Metadata } from 'next';
|
|
2
1
|
import { getBranding } from '@/config/branding';
|
|
3
2
|
import { routing } from '@/i18n/routing';
|
|
3
|
+
import type { Metadata } from 'next';
|
|
4
4
|
|
|
5
5
|
export const SITE_NAME = process.env.NEXT_PUBLIC_SITE_NAME || getBranding().siteName;
|
|
6
6
|
export const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com';
|
|
@@ -9,77 +9,72 @@ export const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com
|
|
|
9
9
|
* Truncate text to a maximum length, preserving word boundaries.
|
|
10
10
|
* Strips HTML tags and is ideal for meta descriptions (recommended 150-160 chars).
|
|
11
11
|
*/
|
|
12
|
-
export function truncateDescription(
|
|
13
|
-
|
|
14
|
-
maxLength = 155
|
|
15
|
-
): string {
|
|
16
|
-
if (!text) return '';
|
|
12
|
+
export function truncateDescription(text: string | null | undefined, maxLength = 155): string {
|
|
13
|
+
if (!text) return '';
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// Strip HTML tags if present
|
|
16
|
+
const cleanText = text.replace(/<[^>]*>/g, '').trim();
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
if (cleanText.length <= maxLength) return cleanText;
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
// Find the last space before maxLength to avoid cutting words
|
|
21
|
+
const truncated = cleanText.substring(0, maxLength);
|
|
22
|
+
const lastSpaceIndex = truncated.lastIndexOf(' ');
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
? truncated.substring(0, lastSpaceIndex) + '...'
|
|
29
|
-
: truncated + '...';
|
|
24
|
+
return lastSpaceIndex > 0 ? truncated.substring(0, lastSpaceIndex) + '...' : truncated + '...';
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
/**
|
|
33
28
|
* Build a canonical URL for a given path, optionally prefixed with locale.
|
|
34
29
|
*/
|
|
35
30
|
export function buildCanonicalUrl(path: string, locale?: string): string {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
const baseUrl = SITE_URL.replace(/\/$/, '');
|
|
32
|
+
const cleanPath = path.startsWith('/') ? path : `/${path}`;
|
|
33
|
+
const prefix = locale ? `/${locale}` : '';
|
|
34
|
+
return `${baseUrl}${prefix}${cleanPath}`;
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
/**
|
|
43
38
|
* Build hreflang alternates for all configured locales.
|
|
44
39
|
*/
|
|
45
40
|
export function buildAlternates(path: string, currentLocale?: string): Metadata['alternates'] {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
const languages: Record<string, string> = {};
|
|
42
|
+
for (const loc of routing.locales) {
|
|
43
|
+
languages[loc] = buildCanonicalUrl(path, loc);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
canonical: buildCanonicalUrl(path, currentLocale),
|
|
47
|
+
languages,
|
|
48
|
+
};
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
/**
|
|
57
52
|
* Build Open Graph image array from an image URL.
|
|
58
53
|
*/
|
|
59
54
|
export function buildOgImages(
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
imageUrl: string | null | undefined,
|
|
56
|
+
alt?: string,
|
|
62
57
|
): NonNullable<Metadata['openGraph']>['images'] {
|
|
63
|
-
|
|
58
|
+
if (!imageUrl) return undefined;
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
url: imageUrl,
|
|
63
|
+
alt: alt || 'Product image',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
/**
|
|
74
69
|
* Create noindex/nofollow robots config for protected pages.
|
|
75
70
|
*/
|
|
76
71
|
export function noIndexRobots(): Metadata['robots'] {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
72
|
+
return {
|
|
73
|
+
index: false,
|
|
74
|
+
follow: false,
|
|
75
|
+
googleBot: {
|
|
76
|
+
index: false,
|
|
77
|
+
follow: false,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
85
80
|
}
|
|
@@ -8,13 +8,11 @@ export function normalizeQuantity(
|
|
|
8
8
|
value: number | string | null | undefined,
|
|
9
9
|
minimum: number = MIN_ORDER_QUANTITY,
|
|
10
10
|
) {
|
|
11
|
-
const parsed = typeof value === 'number'
|
|
12
|
-
? value
|
|
13
|
-
: Number.parseInt(value ?? '', 10);
|
|
11
|
+
const parsed = typeof value === 'number' ? value : Number.parseInt(value ?? '', 10);
|
|
14
12
|
|
|
15
13
|
if (!Number.isFinite(parsed)) {
|
|
16
14
|
return minimum;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
return Math.max(minimum, Math.floor(parsed));
|
|
20
|
-
}
|
|
18
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { createContext,
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
interface SearchBarContextType {
|
|
6
6
|
hasInlineSearch: boolean;
|
|
@@ -22,8 +22,9 @@ export function SearchBarProvider({ children }: { children: React.ReactNode }) {
|
|
|
22
22
|
function handleKeyDown(e: KeyboardEvent) {
|
|
23
23
|
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
24
24
|
e.preventDefault();
|
|
25
|
-
const input =
|
|
26
|
-
??
|
|
25
|
+
const input =
|
|
26
|
+
searchInputRef.current ??
|
|
27
|
+
document.querySelector<HTMLInputElement>('input[type="search"]');
|
|
27
28
|
input?.focus();
|
|
28
29
|
}
|
|
29
30
|
}
|
|
@@ -32,7 +33,9 @@ export function SearchBarProvider({ children }: { children: React.ReactNode }) {
|
|
|
32
33
|
}, []);
|
|
33
34
|
|
|
34
35
|
return (
|
|
35
|
-
<SearchBarContext.Provider
|
|
36
|
+
<SearchBarContext.Provider
|
|
37
|
+
value={{ hasInlineSearch, registerInlineSearch, unregisterInlineSearch, searchInputRef }}
|
|
38
|
+
>
|
|
36
39
|
{children}
|
|
37
40
|
</SearchBarContext.Provider>
|
|
38
41
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useCallback, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
const STORAGE_KEY = 'vendure-recent-searches';
|
|
6
6
|
const MAX_RECENT = 5;
|
|
@@ -11,7 +11,9 @@ function readFromStorage(): string[] {
|
|
|
11
11
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
12
12
|
if (!raw) return [];
|
|
13
13
|
const parsed = JSON.parse(raw);
|
|
14
|
-
return Array.isArray(parsed)
|
|
14
|
+
return Array.isArray(parsed)
|
|
15
|
+
? parsed.filter((s): s is string => typeof s === 'string').slice(0, MAX_RECENT)
|
|
16
|
+
: [];
|
|
15
17
|
} catch {
|
|
16
18
|
return [];
|
|
17
19
|
}
|
|
@@ -31,16 +33,16 @@ export function useRecentSearches() {
|
|
|
31
33
|
const addSearch = useCallback((term: string) => {
|
|
32
34
|
const trimmed = term.trim();
|
|
33
35
|
if (!trimmed) return;
|
|
34
|
-
setSearches(prev => {
|
|
35
|
-
const next = [trimmed, ...prev.filter(s => s !== trimmed)].slice(0, MAX_RECENT);
|
|
36
|
+
setSearches((prev) => {
|
|
37
|
+
const next = [trimmed, ...prev.filter((s) => s !== trimmed)].slice(0, MAX_RECENT);
|
|
36
38
|
writeToStorage(next);
|
|
37
39
|
return next;
|
|
38
40
|
});
|
|
39
41
|
}, []);
|
|
40
42
|
|
|
41
43
|
const removeSearch = useCallback((term: string) => {
|
|
42
|
-
setSearches(prev => {
|
|
43
|
-
const next = prev.filter(s => s !== term);
|
|
44
|
+
setSearches((prev) => {
|
|
45
|
+
const next = prev.filter((s) => s !== term);
|
|
44
46
|
writeToStorage(next);
|
|
45
47
|
return next;
|
|
46
48
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { clsx, type ClassValue } from
|
|
2
|
-
import { twMerge } from
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
3
|
|
|
4
4
|
export function cn(...inputs: ClassValue[]) {
|
|
5
|
-
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
6
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {GetActiveCustomerQuery, GetCompanyAccountQuery, GetMyCompaniesQuery, type CompanyUserCompany} from './queries';
|
|
3
|
-
import {getActiveChannelCached} from './cached';
|
|
4
|
-
import {cache} from "react";
|
|
5
|
-
import {readFragment, ResultOf} from "@/graphql";
|
|
1
|
+
import { readFragment, ResultOf } from '@/graphql';
|
|
6
2
|
import {
|
|
7
3
|
ActiveCustomerFragment,
|
|
8
4
|
CompanyBusinessUnitFragment,
|
|
@@ -10,7 +6,16 @@ import {
|
|
|
10
6
|
CompanyPermissionFragment,
|
|
11
7
|
CompanyRoleFragment,
|
|
12
8
|
CompanyUserFragment,
|
|
13
|
-
} from
|
|
9
|
+
} from '@/lib/vendure/fragments';
|
|
10
|
+
import { cache } from 'react';
|
|
11
|
+
import { client } from './api';
|
|
12
|
+
import { getActiveChannelCached } from './cached';
|
|
13
|
+
import {
|
|
14
|
+
GetActiveCustomerQuery,
|
|
15
|
+
GetCompanyAccountQuery,
|
|
16
|
+
GetMyCompaniesQuery,
|
|
17
|
+
type CompanyUserCompany,
|
|
18
|
+
} from './queries';
|
|
14
19
|
|
|
15
20
|
type CompanyRoleData = Omit<ResultOf<typeof CompanyRoleFragment>, 'permissions'> & {
|
|
16
21
|
permissions: ResultOf<typeof CompanyPermissionFragment>[];
|
|
@@ -34,7 +39,7 @@ export const getActiveCustomer = cache(async () => {
|
|
|
34
39
|
return null;
|
|
35
40
|
}
|
|
36
41
|
return readFragment(ActiveCustomerFragment, result.data.activeCustomer);
|
|
37
|
-
})
|
|
42
|
+
});
|
|
38
43
|
|
|
39
44
|
export const getCompanyAccount = cache(async (): Promise<CompanyAccount | null> => {
|
|
40
45
|
const [result, error] = await client.query(GetCompanyAccountQuery);
|
|
@@ -52,14 +57,14 @@ export const getCompanyAccount = cache(async (): Promise<CompanyAccount | null>
|
|
|
52
57
|
|
|
53
58
|
const companyUser: CompanyUserData = {
|
|
54
59
|
...rawUser,
|
|
55
|
-
companyRoles: rawUser.companyRoles.map(r => {
|
|
60
|
+
companyRoles: rawUser.companyRoles.map((r) => {
|
|
56
61
|
const role = readFragment(CompanyRoleFragment, r);
|
|
57
62
|
return {
|
|
58
63
|
...role,
|
|
59
|
-
permissions: role.permissions.map(p => readFragment(CompanyPermissionFragment, p)),
|
|
64
|
+
permissions: role.permissions.map((p) => readFragment(CompanyPermissionFragment, p)),
|
|
60
65
|
};
|
|
61
66
|
}),
|
|
62
|
-
businessUnits: rawUser.businessUnits.map(bu => readFragment(CompanyBusinessUnitFragment, bu)),
|
|
67
|
+
businessUnits: rawUser.businessUnits.map((bu) => readFragment(CompanyBusinessUnitFragment, bu)),
|
|
63
68
|
};
|
|
64
69
|
|
|
65
70
|
return {
|
|
@@ -76,8 +81,8 @@ export const getMyCompanies = cache(async (): Promise<CompanyUserCompany[]> => {
|
|
|
76
81
|
const customer = result.data.activeCustomer;
|
|
77
82
|
if (!customer) return [];
|
|
78
83
|
return customer.companyUsers
|
|
79
|
-
.filter(cu => cu.state === 'Active')
|
|
80
|
-
.map(cu => ({ id: cu.company.id, name: cu.company.name, state: cu.company.state }));
|
|
84
|
+
.filter((cu) => cu.state === 'Active')
|
|
85
|
+
.map((cu) => ({ id: cu.company.id, name: cu.company.name, state: cu.company.state }));
|
|
81
86
|
});
|
|
82
87
|
|
|
83
88
|
/**
|
|
@@ -86,10 +91,7 @@ export const getMyCompanies = cache(async (): Promise<CompanyUserCompany[]> => {
|
|
|
86
91
|
* to getMyCompanies (which includes pending companies via CompanyUser state).
|
|
87
92
|
*/
|
|
88
93
|
export const getHasCompany = cache(async (): Promise<boolean> => {
|
|
89
|
-
const [companyAccount, companies] = await Promise.all([
|
|
90
|
-
getCompanyAccount(),
|
|
91
|
-
getMyCompanies(),
|
|
92
|
-
]);
|
|
94
|
+
const [companyAccount, companies] = await Promise.all([getCompanyAccount(), getMyCompanies()]);
|
|
93
95
|
return !!companyAccount || companies.length > 0;
|
|
94
96
|
});
|
|
95
97
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { RequestMiddleware } from '@vendure-platform/storefront-client';
|
|
2
|
+
import { createClient } from '@vendure-platform/storefront-client';
|
|
3
3
|
|
|
4
4
|
const DRAFT_MODE_SECRET = process.env.DRAFT_MODE_SECRET;
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ const DRAFT_MODE_SECRET = process.env.DRAFT_MODE_SECRET;
|
|
|
11
11
|
const draftModeMiddleware: RequestMiddleware = async (req, next) => {
|
|
12
12
|
if (DRAFT_MODE_SECRET) {
|
|
13
13
|
try {
|
|
14
|
-
const {draftMode} = await import('next/headers');
|
|
14
|
+
const { draftMode } = await import('next/headers');
|
|
15
15
|
const draft = await draftMode();
|
|
16
16
|
if (draft.isEnabled) {
|
|
17
17
|
const url = new URL(req.url);
|
|
@@ -26,35 +26,44 @@ const draftModeMiddleware: RequestMiddleware = async (req, next) => {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
const VENDURE_API_URL = process.env.VENDURE_SHOP_API_URL || process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL;
|
|
29
|
-
const VENDURE_CHANNEL_TOKEN =
|
|
29
|
+
const VENDURE_CHANNEL_TOKEN =
|
|
30
|
+
process.env.VENDURE_CHANNEL_TOKEN || process.env.NEXT_PUBLIC_VENDURE_CHANNEL_TOKEN;
|
|
30
31
|
const VENDURE_AUTH_TOKEN_HEADER = process.env.VENDURE_AUTH_TOKEN_HEADER || 'vendure-auth-token';
|
|
31
32
|
const VENDURE_CHANNEL_TOKEN_HEADER = process.env.VENDURE_CHANNEL_TOKEN_HEADER || 'vendure-token';
|
|
32
33
|
|
|
33
34
|
if (!VENDURE_API_URL) {
|
|
34
|
-
throw new Error(
|
|
35
|
+
throw new Error(
|
|
36
|
+
'VENDURE_SHOP_API_URL or NEXT_PUBLIC_VENDURE_SHOP_API_URL environment variable is not set',
|
|
37
|
+
);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
// Dynamic imports to avoid Next.js static analysis marking this module as dynamic.
|
|
38
41
|
// cookies() is only available in request context — providers gracefully return undefined otherwise.
|
|
39
42
|
async function safeGetAuthToken(): Promise<string | undefined> {
|
|
40
43
|
try {
|
|
41
|
-
const {getAuthToken} = await import('@/lib/auth');
|
|
44
|
+
const { getAuthToken } = await import('@/lib/auth');
|
|
42
45
|
return await getAuthToken();
|
|
43
|
-
} catch {
|
|
46
|
+
} catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
async function safeGetCompanyId(): Promise<string | undefined> {
|
|
47
52
|
try {
|
|
48
|
-
const {getCompanyId} = await import('@/lib/company-context');
|
|
53
|
+
const { getCompanyId } = await import('@/lib/company-context');
|
|
49
54
|
return await getCompanyId();
|
|
50
|
-
} catch {
|
|
55
|
+
} catch {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
async function safeGetBusinessUnitId(): Promise<string | undefined> {
|
|
54
61
|
try {
|
|
55
|
-
const {getBusinessUnitId} = await import('@/lib/company-context');
|
|
62
|
+
const { getBusinessUnitId } = await import('@/lib/company-context');
|
|
56
63
|
return await getBusinessUnitId();
|
|
57
|
-
} catch {
|
|
64
|
+
} catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
/**
|
|
@@ -65,16 +74,20 @@ async function safeGetBusinessUnitId(): Promise<string | undefined> {
|
|
|
65
74
|
*/
|
|
66
75
|
async function safeGetChannelToken(): Promise<string | undefined> {
|
|
67
76
|
try {
|
|
68
|
-
const {getActiveChannelToken} = await import('@/lib/channel-server');
|
|
77
|
+
const { getActiveChannelToken } = await import('@/lib/channel-server');
|
|
69
78
|
return await getActiveChannelToken();
|
|
70
|
-
} catch {
|
|
79
|
+
} catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
async function safeGetLanguageCode(): Promise<string | undefined> {
|
|
74
85
|
try {
|
|
75
|
-
const {getLocale} = await import('next-intl/server');
|
|
86
|
+
const { getLocale } = await import('next-intl/server');
|
|
76
87
|
return await getLocale();
|
|
77
|
-
} catch {
|
|
88
|
+
} catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
78
91
|
}
|
|
79
92
|
|
|
80
93
|
const sharedConfig = {
|
|
@@ -95,7 +108,7 @@ const sharedConfig = {
|
|
|
95
108
|
*/
|
|
96
109
|
const currencyMiddleware: RequestMiddleware = async (req, next) => {
|
|
97
110
|
try {
|
|
98
|
-
const {getActiveCurrencyCode} = await import('@/lib/currency-server');
|
|
111
|
+
const { getActiveCurrencyCode } = await import('@/lib/currency-server');
|
|
99
112
|
const currency = await getActiveCurrencyCode();
|
|
100
113
|
const url = new URL(req.url);
|
|
101
114
|
url.searchParams.set('currencyCode', currency);
|
|
@@ -130,7 +143,7 @@ export const client = createClient({
|
|
|
130
143
|
* access cookies, headers, or draftMode. Pass languageCode and currencyCode explicitly
|
|
131
144
|
* as query options from the calling function.
|
|
132
145
|
*/
|
|
133
|
-
export const publicClient = createClient({...sharedConfig});
|
|
146
|
+
export const publicClient = createClient({ ...sharedConfig });
|
|
134
147
|
|
|
135
148
|
/**
|
|
136
149
|
* Pre-resolved context for use at cache boundaries where cookies() is not available.
|
|
@@ -149,20 +162,20 @@ export interface VendureContext {
|
|
|
149
162
|
* Use this at cache boundaries ('use cache') where providers can't access cookies().
|
|
150
163
|
*/
|
|
151
164
|
export async function getVendureContext(): Promise<VendureContext> {
|
|
152
|
-
const {getAuthToken} = await import('@/lib/auth');
|
|
165
|
+
const { getAuthToken } = await import('@/lib/auth');
|
|
153
166
|
const authToken = await getAuthToken();
|
|
154
167
|
let companyId: string | undefined;
|
|
155
168
|
let businessUnitId: string | undefined;
|
|
156
169
|
try {
|
|
157
|
-
const {getCompanyId, getBusinessUnitId} = await import('@/lib/company-context');
|
|
170
|
+
const { getCompanyId, getBusinessUnitId } = await import('@/lib/company-context');
|
|
158
171
|
companyId = await getCompanyId();
|
|
159
172
|
businessUnitId = await getBusinessUnitId();
|
|
160
173
|
} catch {}
|
|
161
|
-
const {getActiveChannelToken} = await import('@/lib/channel-server');
|
|
174
|
+
const { getActiveChannelToken } = await import('@/lib/channel-server');
|
|
162
175
|
const channelToken = await getActiveChannelToken();
|
|
163
|
-
const {getRouteLocale} = await import('@/i18n/server');
|
|
176
|
+
const { getRouteLocale } = await import('@/i18n/server');
|
|
164
177
|
const locale = await getRouteLocale();
|
|
165
|
-
const {getActiveCurrencyCode} = await import('@/lib/currency-server');
|
|
178
|
+
const { getActiveCurrencyCode } = await import('@/lib/currency-server');
|
|
166
179
|
const currencyCode = await getActiveCurrencyCode();
|
|
167
|
-
return {authToken, channelToken, companyId, businessUnitId, locale, currencyCode};
|
|
180
|
+
return { authToken, channelToken, companyId, businessUnitId, locale, currencyCode };
|
|
168
181
|
}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {GetApprovalHistoryForEntityQuery} from '@/lib/vendure/queries';
|
|
1
|
+
import type { VendureContext } from '@/lib/vendure/api';
|
|
2
|
+
import { client } from '@/lib/vendure/api';
|
|
3
|
+
import { GetApprovalHistoryForEntityQuery } from '@/lib/vendure/queries';
|
|
4
4
|
|
|
5
5
|
export async function getLatestApprovalForOrder(orderId: string, ctx?: VendureContext) {
|
|
6
6
|
const queryArgs = { entityType: 'Order', entityId: orderId } as const;
|
|
7
7
|
const [result] = ctx
|
|
8
8
|
? await client.query(GetApprovalHistoryForEntityQuery, queryArgs, ctx)
|
|
9
9
|
: await client.query(GetApprovalHistoryForEntityQuery, queryArgs);
|
|
10
|
-
const history = [...(result?.data?.approvalHistoryForEntity ?? [])]
|
|
11
|
-
|
|
10
|
+
const history = [...(result?.data?.approvalHistoryForEntity ?? [])].sort(
|
|
11
|
+
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
|
12
|
+
);
|
|
12
13
|
const latestApproval = history[0] ?? null;
|
|
13
14
|
const changesRequested = latestApproval?.status === 'CHANGES_REQUESTED';
|
|
14
15
|
const changesComment = changesRequested
|
|
15
16
|
? latestApproval.decisions
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
?.filter((d: any) => d.decision === 'CHANGES_REQUESTED' && d.comment)
|
|
18
|
+
.map((d: any) => d.comment)
|
|
19
|
+
.at(-1) ?? null
|
|
19
20
|
: null;
|
|
20
21
|
return { latestApproval, changesRequested, changesComment };
|
|
21
22
|
}
|