orionplace-nuxt 0.1.2 → 0.2.0
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/README.md +711 -24
- package/bin/orionplace-nuxt.mjs +39 -11
- package/package.json +26 -6
- package/runtime/api.mjs +4 -1
- package/runtime/domain.mjs +4 -2
- package/runtime/marketplace.mjs +287 -211
- package/src/asset-loading-plugin.mjs +10 -0
- package/src/module.mjs +44 -14
- package/src/project-readme.mjs +507 -35
- package/src/setup.mjs +100 -51
- package/src/update.mjs +36 -0
- package/src/validation.mjs +6 -0
- package/templates/.vscode/settings.json +5 -0
- package/templates/app/app.vue +48 -0
- package/templates/app/assets/css/orionplace-tokens.css +21 -0
- package/templates/app/assets/css/orionplace.css +28 -0
- package/templates/app/components/orionplace/account/AccountActivity.README.md +31 -0
- package/templates/app/components/orionplace/account/AccountActivity.vue +61 -0
- package/templates/app/components/orionplace/account/AccountPromocodes.README.md +50 -0
- package/templates/app/components/orionplace/account/AccountPromocodes.vue +267 -0
- package/templates/app/components/orionplace/account/AccountSection.README.md +31 -0
- package/templates/app/components/orionplace/account/AccountSection.vue +132 -0
- package/templates/app/components/orionplace/account/ProfileAvatar.vue +139 -0
- package/templates/app/components/orionplace/account/ProfileDeleteAccount.vue +161 -0
- package/templates/app/components/orionplace/account/ProfileDetailsForm.vue +172 -0
- package/templates/app/components/orionplace/account/ProfileEmailSettings.vue +269 -0
- package/templates/app/components/orionplace/account/ProfilePasswordForm.vue +201 -0
- package/templates/app/components/orionplace/account/ProfileSignIn.vue +446 -0
- package/templates/app/components/orionplace/account/SignInHistory.README.md +27 -0
- package/templates/app/components/orionplace/account/SignInHistory.vue +218 -0
- package/templates/app/components/orionplace/account/StorefrontLogout.README.md +15 -0
- package/templates/app/components/orionplace/account/StorefrontLogout.vue +109 -0
- package/templates/app/components/orionplace/account/StorefrontProfile.README.md +145 -0
- package/templates/app/components/orionplace/account/StorefrontProfile.vue +168 -0
- package/templates/app/components/orionplace/account/account.css +1047 -0
- package/templates/app/components/orionplace/account/profile.css +696 -0
- package/templates/app/components/orionplace/address/AddressForm.README.md +67 -0
- package/templates/app/components/orionplace/address/AddressForm.vue +537 -0
- package/templates/app/components/orionplace/address/StorefrontAddresses.README.md +44 -0
- package/templates/app/components/orionplace/address/StorefrontAddresses.vue +438 -0
- package/templates/app/components/orionplace/banners/MainBanner.vue +171 -0
- package/templates/app/components/orionplace/banners/examples/BannerExample.vue +6 -0
- package/templates/app/components/orionplace/blog/BlogArticle.README.md +44 -0
- package/templates/app/components/orionplace/blog/BlogArticle.vue +829 -0
- package/templates/app/components/orionplace/blog/BlogCommentForm.README.md +28 -0
- package/templates/app/components/orionplace/blog/BlogCommentForm.vue +129 -0
- package/templates/app/components/orionplace/blog/BlogComments.README.md +36 -0
- package/templates/app/components/orionplace/blog/BlogComments.vue +373 -0
- package/templates/app/components/orionplace/blog/BlogPostCard.vue +307 -0
- package/templates/app/components/orionplace/blog/BlogPostGroup.vue +108 -0
- package/templates/app/components/orionplace/blog/StorefrontJournal.README.md +42 -0
- package/templates/app/components/orionplace/blog/StorefrontJournal.vue +669 -0
- package/templates/app/components/orionplace/branding/BrandLogos.vue +25 -0
- package/templates/app/components/orionplace/branding/examples/BrandLogosExample.vue +6 -0
- package/templates/app/components/orionplace/cart/CartCheckoutDetails.README.md +81 -0
- package/templates/app/components/orionplace/cart/CartCheckoutDetails.vue +367 -0
- package/templates/app/components/orionplace/cart/CartDeliverySelector.README.md +95 -0
- package/templates/app/components/orionplace/cart/CartDeliverySelector.vue +724 -0
- package/templates/app/components/orionplace/cart/CartItemOptions.README.md +98 -0
- package/templates/app/components/orionplace/cart/CartItemOptions.vue +693 -0
- package/templates/app/components/orionplace/cart/CartLineItem.README.md +70 -0
- package/templates/app/components/orionplace/cart/CartLineItem.vue +271 -0
- package/templates/app/components/orionplace/cart/CartPreview.README.md +43 -0
- package/templates/app/components/orionplace/cart/CartPreview.vue +263 -0
- package/templates/app/components/orionplace/cart/DeliveryMap.README.md +48 -0
- package/templates/app/components/orionplace/cart/DeliveryMap.vue +155 -0
- package/templates/app/components/orionplace/cart/StorefrontCart.README.md +89 -0
- package/templates/app/components/orionplace/cart/StorefrontCart.vue +689 -0
- package/templates/app/components/orionplace/catalog/CatalogHeader.vue +681 -0
- package/templates/app/components/orionplace/catalog/CatalogRepresentative.vue +59 -0
- package/templates/app/components/orionplace/catalog/StorefrontCatalog.README.md +35 -0
- package/templates/app/components/orionplace/catalog/StorefrontCatalog.vue +179 -0
- package/templates/app/components/orionplace/catalog/examples/CatalogHeaderExample.vue +6 -0
- package/templates/app/components/orionplace/categories/CategoryGroup.vue +125 -0
- package/templates/app/components/orionplace/categories/StorefrontCategory.README.md +60 -0
- package/templates/app/components/orionplace/categories/StorefrontCategory.vue +277 -0
- package/templates/app/components/orionplace/categories/examples/CategoryGroupExample.vue +7 -0
- package/templates/app/components/orionplace/contact/AboutPage.README.md +23 -0
- package/templates/app/components/orionplace/contact/AboutPage.vue +409 -0
- package/templates/app/components/orionplace/contact/ContactForm.README.md +29 -0
- package/templates/app/components/orionplace/contact/ContactForm.vue +289 -0
- package/templates/app/components/orionplace/contact/EmailUnsubscribe.README.md +27 -0
- package/templates/app/components/orionplace/contact/EmailUnsubscribe.vue +95 -0
- package/templates/app/components/orionplace/contact/StorefrontContact.README.md +18 -0
- package/templates/app/components/orionplace/contact/StorefrontContact.vue +89 -0
- package/templates/app/components/orionplace/contact/examples/ContactExample.vue +6 -0
- package/templates/app/components/orionplace/currencies/MainCurrencySwitcher.vue +80 -0
- package/templates/app/components/orionplace/currencies/examples/CurrencyExample.vue +6 -0
- package/templates/app/components/orionplace/events/EventEnrollmentDialog.README.md +58 -0
- package/templates/app/components/orionplace/events/EventEnrollmentDialog.vue +294 -0
- package/templates/app/components/orionplace/events/EventsBlock.vue +138 -0
- package/templates/app/components/orionplace/events/examples/EventsExample.vue +6 -0
- package/templates/app/components/orionplace/locale/MainLanguageSwitcher.vue +506 -0
- package/templates/app/components/orionplace/locale/examples/LocaleExample.vue +6 -0
- package/templates/app/components/orionplace/manufacturers/ManufacturerIndex.README.md +36 -0
- package/templates/app/components/orionplace/manufacturers/ManufacturerIndex.vue +495 -0
- package/templates/app/components/orionplace/manufacturers/StorefrontManufacturers.README.md +30 -0
- package/templates/app/components/orionplace/manufacturers/StorefrontManufacturers.vue +263 -0
- package/templates/app/components/orionplace/orders/OrderDetails.README.md +39 -0
- package/templates/app/components/orionplace/orders/OrderDetails.vue +1074 -0
- package/templates/app/components/orionplace/orders/OrderPaymentForm.README.md +59 -0
- package/templates/app/components/orionplace/orders/OrderPaymentForm.vue +73 -0
- package/templates/app/components/orionplace/orders/StorefrontOrders.README.md +39 -0
- package/templates/app/components/orionplace/orders/StorefrontOrders.vue +869 -0
- package/templates/app/components/orionplace/orders/orders.css +612 -0
- package/templates/app/components/orionplace/payments/PaymentPanel.README.md +76 -0
- package/templates/app/components/orionplace/payments/PaymentPanel.vue +108 -0
- package/templates/app/components/orionplace/products/HoverImageViewer.vue +190 -0
- package/templates/app/components/orionplace/products/ProductCard.README.md +63 -0
- package/templates/app/components/orionplace/products/ProductCard.vue +897 -0
- package/templates/app/components/orionplace/products/ProductCardActions.README.md +33 -0
- package/templates/app/components/orionplace/products/ProductCardActions.vue +412 -0
- package/templates/app/components/orionplace/products/ProductCardBadges.vue +83 -0
- package/templates/app/components/orionplace/products/ProductCardDescription.vue +46 -0
- package/templates/app/components/orionplace/products/ProductCardFavorite.vue +99 -0
- package/templates/app/components/orionplace/products/ProductCardPrice.vue +66 -0
- package/templates/app/components/orionplace/products/ProductCardRating.vue +65 -0
- package/templates/app/components/orionplace/products/ProductCardSeller.vue +66 -0
- package/templates/app/components/orionplace/products/ProductCardStockNotice.vue +43 -0
- package/templates/app/components/orionplace/products/ProductCardTitle.vue +46 -0
- package/templates/app/components/orionplace/products/ProductCardVariants.vue +388 -0
- package/templates/app/components/orionplace/products/ProductGroup.vue +257 -0
- package/templates/app/components/orionplace/products/ProductPreorderDialog.README.md +22 -0
- package/templates/app/components/orionplace/products/ProductPreorderDialog.vue +471 -0
- package/templates/app/components/orionplace/products/ProductReviewForm.README.md +39 -0
- package/templates/app/components/orionplace/products/ProductReviewForm.vue +312 -0
- package/templates/app/components/orionplace/products/ProductReviewGallery.README.md +28 -0
- package/templates/app/components/orionplace/products/ProductReviewGallery.vue +141 -0
- package/templates/app/components/orionplace/products/ProductReviewImageViewer.README.md +51 -0
- package/templates/app/components/orionplace/products/ProductReviewImageViewer.vue +351 -0
- package/templates/app/components/orionplace/products/ProductReviews.README.md +70 -0
- package/templates/app/components/orionplace/products/ProductReviews.vue +1025 -0
- package/templates/app/components/orionplace/products/ProductSecondaryVariantModal.vue +460 -0
- package/templates/app/components/orionplace/products/ProductSpecificationsDialog.README.md +65 -0
- package/templates/app/components/orionplace/products/ProductSpecificationsDialog.vue +174 -0
- package/templates/app/components/orionplace/products/StorefrontProduct.README.md +52 -0
- package/templates/app/components/orionplace/products/StorefrontProduct.vue +1466 -0
- package/templates/app/components/orionplace/products/StorefrontWishlist.README.md +33 -0
- package/templates/app/components/orionplace/products/StorefrontWishlist.vue +290 -0
- package/templates/app/components/orionplace/products/examples/FeaturedExample.vue +6 -0
- package/templates/app/components/orionplace/products/examples/FeaturedHoverImageViewerExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardActionsExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardBadgesExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardDescriptionExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardFavoriteExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardPriceExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardRatingExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardSellerExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardStockNoticeExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardTitleExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/FeaturedProductCardVariantsExample.vue +14 -0
- package/templates/app/components/orionplace/products/examples/ProductsExample.vue +6 -0
- package/templates/app/components/orionplace/products/examples/ProductsHoverImageViewerExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardActionsExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardBadgesExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardDescriptionExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardFavoriteExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardPriceExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardRatingExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardSellerExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardStockNoticeExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardTitleExample.vue +13 -0
- package/templates/app/components/orionplace/products/examples/ProductsProductCardVariantsExample.vue +13 -0
- package/templates/app/components/orionplace/promo/PromoProducts.README.md +45 -0
- package/templates/app/components/orionplace/promo/PromoProducts.vue +287 -0
- package/templates/app/components/orionplace/search/MainSearch.vue +342 -0
- package/templates/app/components/orionplace/search/ProductSearchResults.README.md +81 -0
- package/templates/app/components/orionplace/search/ProductSearchResults.vue +458 -0
- package/templates/app/components/orionplace/search/SearchFilters.vue +546 -0
- package/templates/app/components/orionplace/search/examples/MainSearchExample.vue +6 -0
- package/templates/app/components/orionplace/sellers/SellerFilters.README.md +32 -0
- package/templates/app/components/orionplace/sellers/SellerFilters.vue +317 -0
- package/templates/app/components/orionplace/sellers/SellerPhotoGallery.README.md +45 -0
- package/templates/app/components/orionplace/sellers/SellerPhotoGallery.vue +406 -0
- package/templates/app/components/orionplace/sellers/SellerSummary.README.md +33 -0
- package/templates/app/components/orionplace/sellers/SellerSummary.vue +162 -0
- package/templates/app/components/orionplace/sellers/StorefrontSellers.README.md +73 -0
- package/templates/app/components/orionplace/sellers/StorefrontSellers.vue +300 -0
- package/templates/app/components/orionplace/shared/OrionplaceAvatar.README.md +30 -0
- package/templates/app/components/orionplace/shared/OrionplaceAvatar.vue +83 -0
- package/templates/app/components/orionplace/shared/OrionplaceBreadcrumbs.README.md +65 -0
- package/templates/app/components/orionplace/shared/OrionplaceBreadcrumbs.vue +118 -0
- package/templates/app/components/orionplace/shared/OrionplaceEmptyState.README.md +38 -0
- package/templates/app/components/orionplace/shared/OrionplaceEmptyState.vue +143 -0
- package/templates/app/components/orionplace/shared/OrionplaceImage.vue +84 -0
- package/templates/app/components/orionplace/shared/OrionplaceInfoHint.README.md +32 -0
- package/templates/app/components/orionplace/shared/OrionplaceInfoHint.vue +158 -0
- package/templates/app/components/orionplace/shared/OrionplacePasswordInput.README.md +30 -0
- package/templates/app/components/orionplace/shared/OrionplacePasswordInput.vue +197 -0
- package/templates/app/components/orionplace/shared/OrionplaceSearchSelect.README.md +38 -0
- package/templates/app/components/orionplace/shared/OrionplaceSearchSelect.vue +411 -0
- package/templates/app/components/orionplace/shared/OrionplaceSelect.README.md +31 -0
- package/templates/app/components/orionplace/shared/OrionplaceSelect.vue +525 -0
- package/templates/app/components/orionplace/shared/StorefrontErrorPage.README.md +55 -0
- package/templates/app/components/orionplace/shared/StorefrontErrorPage.vue +151 -0
- package/templates/app/components/orionplace/shared/StorefrontPagination.README.md +45 -0
- package/templates/app/components/orionplace/shared/StorefrontPagination.vue +101 -0
- package/templates/app/components/orionplace/shared/dialogs.css +36 -0
- package/templates/app/components/orionplace/shared/features.css +364 -0
- package/templates/app/components/orionplace/social/SocialLinks.vue +72 -0
- package/templates/app/components/orionplace/social/examples/SocialLinksExample.vue +6 -0
- package/templates/app/components/orionplace/storefront/StorefrontAccount.README.md +47 -0
- package/templates/app/components/orionplace/storefront/StorefrontAccount.vue +332 -0
- package/templates/app/components/orionplace/storefront/StorefrontCartButton.vue +68 -0
- package/templates/app/components/orionplace/storefront/StorefrontFooter.README.md +26 -0
- package/templates/app/components/orionplace/storefront/StorefrontFooter.vue +222 -0
- package/templates/app/components/orionplace/storefront/StorefrontHeader.README.md +93 -0
- package/templates/app/components/orionplace/storefront/StorefrontHeader.vue +509 -0
- package/templates/app/components/orionplace/storefront/StorefrontHome.README.md +79 -0
- package/templates/app/components/orionplace/storefront/StorefrontHome.vue +315 -0
- package/templates/app/components/orionplace/storefront/StorefrontWishlistButton.vue +105 -0
- package/templates/app/components/orionplace/storefront/examples/StorefrontAccountExample.vue +7 -0
- package/templates/app/components/orionplace/stores/StorefrontStores.README.md +41 -0
- package/templates/app/components/orionplace/stores/StorefrontStores.vue +345 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontSubscriptions.README.md +151 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontSubscriptions.vue +851 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontTariff.README.md +38 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontTariff.vue +535 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontTariffs.README.md +36 -0
- package/templates/app/components/orionplace/subscriptions/StorefrontTariffs.vue +395 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionCancelDialog.README.md +39 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionCancelDialog.vue +292 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionChangeDialog.README.md +85 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionChangeDialog.vue +874 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionExtendDialog.README.md +53 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionExtendDialog.vue +536 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionPlanSummary.README.md +101 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionPlanSummary.vue +286 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionRemoteDetails.README.md +138 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionRemoteDetails.vue +134 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionRenewalDialog.README.md +85 -0
- package/templates/app/components/orionplace/subscriptions/SubscriptionRenewalDialog.vue +364 -0
- package/templates/app/components/orionplace/support/StorefrontSupport.README.md +39 -0
- package/templates/app/components/orionplace/support/StorefrontSupport.vue +484 -0
- package/templates/app/components/orionplace/support/TicketConversation.README.md +38 -0
- package/templates/app/components/orionplace/support/TicketConversation.vue +524 -0
- package/templates/app/components/orionplace/support/TicketImage.README.md +27 -0
- package/templates/app/components/orionplace/support/TicketImage.vue +186 -0
- package/templates/app/components/orionplace/support/TicketItemCard.README.md +59 -0
- package/templates/app/components/orionplace/support/TicketItemCard.vue +177 -0
- package/templates/app/components/orionplace/support/TicketMessageForm.README.md +35 -0
- package/templates/app/components/orionplace/support/TicketMessageForm.vue +258 -0
- package/templates/app/components/orionplace/support/TicketSubscriptionCard.README.md +40 -0
- package/templates/app/components/orionplace/support/TicketSubscriptionCard.vue +154 -0
- package/templates/app/components/orionplace/tariffs/TariffCard.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCard.vue +241 -0
- package/templates/app/components/orionplace/tariffs/TariffCardDescription.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCardDescription.vue +97 -0
- package/templates/app/components/orionplace/tariffs/TariffCardFeatures.README.md +14 -0
- package/templates/app/components/orionplace/tariffs/TariffCardFeatures.vue +172 -0
- package/templates/app/components/orionplace/tariffs/TariffCardImage.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCardImage.vue +33 -0
- package/templates/app/components/orionplace/tariffs/TariffCardPrices.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCardPrices.vue +280 -0
- package/templates/app/components/orionplace/tariffs/TariffCardTitle.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCardTitle.vue +30 -0
- package/templates/app/components/orionplace/tariffs/TariffCards.README.md +12 -0
- package/templates/app/components/orionplace/tariffs/TariffCards.vue +94 -0
- package/templates/app/components/orionplace/tariffs/TariffSubscriptionModal.README.md +31 -0
- package/templates/app/components/orionplace/tariffs/TariffSubscriptionModal.vue +411 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardDescriptionExample.vue +13 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardExample.vue +13 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardFeaturesExample.vue +14 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardImageExample.vue +13 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardPricesExample.vue +13 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardTitleExample.vue +13 -0
- package/templates/app/components/orionplace/tariffs/examples/TariffCardsExample.vue +6 -0
- package/templates/app/components/orionplace/theme/OrionplaceThemeProvider.vue +38 -0
- package/templates/app/components/orionplace/units/UnitSwitcher.vue +71 -0
- package/templates/app/components/orionplace/units/examples/LengthExample.vue +6 -0
- package/templates/app/components/orionplace/units/examples/WeightExample.vue +6 -0
- package/templates/app/components/orionplace/wallet/StorefrontWallet.README.md +117 -0
- package/templates/app/components/orionplace/wallet/StorefrontWallet.vue +863 -0
- package/templates/app/components/orionplace/wallet/WalletBalance.vue +47 -0
- package/templates/app/components/orionplace/wallet/WalletTopUpForm.README.md +32 -0
- package/templates/app/components/orionplace/wallet/WalletTopUpForm.vue +224 -0
- package/templates/app/components/orionplace/wallet/examples/WalletExample.vue +6 -0
- package/templates/app/composables/useOrionplaceActionMenu.ts +126 -0
- package/templates/app/composables/useOrionplaceAddressEditor.ts +343 -0
- package/templates/app/composables/useOrionplaceAddresses.ts +75 -0
- package/templates/app/composables/useOrionplaceApi.ts +174 -0
- package/templates/app/composables/useOrionplaceAppLoad.ts +74 -0
- package/templates/app/composables/useOrionplaceBlogComments.ts +325 -0
- package/templates/app/composables/useOrionplaceBlogReading.ts +270 -0
- package/templates/app/composables/useOrionplaceCart.ts +226 -0
- package/templates/app/composables/useOrionplaceCartPreview.ts +142 -0
- package/templates/app/composables/useOrionplaceCategoryLink.ts +24 -0
- package/templates/app/composables/useOrionplaceCategoryProducts.ts +16 -0
- package/templates/app/composables/useOrionplaceFeature.ts +100 -0
- package/templates/app/composables/useOrionplaceFeaturedProducts.ts +14 -0
- package/templates/app/composables/useOrionplaceGeolocation.ts +28 -0
- package/templates/app/composables/useOrionplaceHomeProducts.ts +90 -0
- package/templates/app/composables/useOrionplaceManufacturerIndex.ts +83 -0
- package/templates/app/composables/useOrionplaceMap.ts +240 -0
- package/templates/app/composables/useOrionplaceMediaFormat.ts +24 -0
- package/templates/app/composables/useOrionplaceMissingPage.ts +67 -0
- package/templates/app/composables/useOrionplaceOrders.ts +185 -0
- package/templates/app/composables/useOrionplacePageSeo.ts +38 -0
- package/templates/app/composables/useOrionplaceProductActions.ts +116 -0
- package/templates/app/composables/useOrionplaceProductLink.ts +24 -0
- package/templates/app/composables/useOrionplaceProductSearch.ts +259 -0
- package/templates/app/composables/useOrionplaceProductVariants.ts +176 -0
- package/templates/app/composables/useOrionplaceProfile.ts +309 -0
- package/templates/app/composables/useOrionplaceProgress.ts +89 -0
- package/templates/app/composables/useOrionplaceReviews.ts +242 -0
- package/templates/app/composables/useOrionplaceSearchHistory.ts +23 -0
- package/templates/app/composables/useOrionplaceSearchScopeNames.ts +99 -0
- package/templates/app/composables/useOrionplaceServerData.ts +72 -0
- package/templates/app/composables/useOrionplaceSignIn.ts +66 -0
- package/templates/app/composables/useOrionplaceStableHeight.ts +69 -0
- package/templates/app/composables/useOrionplaceStorefront.ts +29 -0
- package/templates/app/composables/useOrionplaceSubscriptions.ts +217 -0
- package/templates/app/composables/useOrionplaceTheme.ts +27 -0
- package/templates/app/composables/useOrionplaceTicketSubject.ts +180 -0
- package/templates/app/composables/useOrionplaceTickets.ts +335 -0
- package/templates/app/composables/useOrionplaceWallet.ts +166 -0
- package/templates/app/error.vue +108 -0
- package/templates/app/interfaces/orionplace/accounts/IContact.ts +21 -0
- package/templates/app/interfaces/orionplace/accounts/IEmailNotificationLocale.ts +17 -0
- package/templates/app/interfaces/orionplace/accounts/IEmailVerification.ts +59 -0
- package/templates/app/interfaces/orionplace/accounts/IProfileActions.ts +38 -0
- package/templates/app/interfaces/orionplace/accounts/IProfileData.ts +123 -0
- package/templates/app/interfaces/orionplace/accounts/IProfileMedia.ts +17 -0
- package/templates/app/interfaces/orionplace/accounts/IStorefrontProfile.ts +54 -0
- package/templates/app/interfaces/orionplace/address/IAddressCitySuggestion.ts +19 -0
- package/templates/app/interfaces/orionplace/address/IAddressEditor.ts +9 -0
- package/templates/app/interfaces/orionplace/address/IAddressLocationSuggestion.ts +22 -0
- package/templates/app/interfaces/orionplace/address/IAddressRegionSearch.ts +30 -0
- package/templates/app/interfaces/orionplace/address/IAddressSuggestion.ts +20 -0
- package/templates/app/interfaces/orionplace/address/IUserAddress.ts +87 -0
- package/templates/app/interfaces/orionplace/apiBase/TMethod.ts +1 -0
- package/templates/app/interfaces/orionplace/appBase/IAppLoad.ts +16 -0
- package/templates/app/interfaces/orionplace/appBase/IAppLoadCommon.ts +45 -0
- package/templates/app/interfaces/orionplace/appBase/IApploadUserProfile.ts +13 -0
- package/templates/app/interfaces/orionplace/appBase/IForm.ts +21 -0
- package/templates/app/interfaces/orionplace/appBase/ISEO.ts +21 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonBanner.ts +11 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonContact.ts +8 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonCurrency.ts +15 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonEvents.ts +18 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonLocale.ts +14 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonLogos.ts +6 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonPath.ts +22 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonSEO.ts +26 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonSocial.ts +15 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonTariff.ts +7 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonUnit.ts +12 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonVariables.ts +8 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonVisualSettings.ts +11 -0
- package/templates/app/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonWalletValue.ts +3 -0
- package/templates/app/interfaces/orionplace/blog/IBlogApi.ts +247 -0
- package/templates/app/interfaces/orionplace/blog/IBlogPostPreview.ts +30 -0
- package/templates/app/interfaces/orionplace/cart/ICartActions.ts +67 -0
- package/templates/app/interfaces/orionplace/cart/ICartData.ts +382 -0
- package/templates/app/interfaces/orionplace/cart/ICartDeliveryActions.ts +68 -0
- package/templates/app/interfaces/orionplace/cart/ICartModal.ts +22 -0
- package/templates/app/interfaces/orionplace/cart/IDeliveryMap.ts +29 -0
- package/templates/app/interfaces/orionplace/catalog/ICatalogDirectory.ts +75 -0
- package/templates/app/interfaces/orionplace/category/ICategory.ts +41 -0
- package/templates/app/interfaces/orionplace/domains/IDomain.ts +13 -0
- package/templates/app/interfaces/orionplace/forms/ICustomerSubfilter.ts +19 -0
- package/templates/app/interfaces/orionplace/index.ts +57 -0
- package/templates/app/interfaces/orionplace/marketing/IPromoActions.ts +51 -0
- package/templates/app/interfaces/orionplace/orders/IOrderActions.ts +99 -0
- package/templates/app/interfaces/orionplace/orders/IOrderHistory.ts +259 -0
- package/templates/app/interfaces/orionplace/orders/IProductPreorder.ts +31 -0
- package/templates/app/interfaces/orionplace/payments/IInvoice.ts +147 -0
- package/templates/app/interfaces/orionplace/products/IProduct.ts +262 -0
- package/templates/app/interfaces/orionplace/products/IProductFeedbackApi.ts +218 -0
- package/templates/app/interfaces/orionplace/products/IProductSearchApi.ts +146 -0
- package/templates/app/interfaces/orionplace/products/IProductSearchFacets.ts +35 -0
- package/templates/app/interfaces/orionplace/products/IProductSecondaryVariantRequest.ts +15 -0
- package/templates/app/interfaces/orionplace/products/IProductSpecification.ts +14 -0
- package/templates/app/interfaces/orionplace/products/IWishlist.ts +22 -0
- package/templates/app/interfaces/orionplace/sellers/ISellerDirectory.ts +70 -0
- package/templates/app/interfaces/orionplace/shared/IBreadcrumb.ts +10 -0
- package/templates/app/interfaces/orionplace/shared/IGeoCoordinates.ts +4 -0
- package/templates/app/interfaces/orionplace/shared/IStorefrontControls.ts +13 -0
- package/templates/app/interfaces/orionplace/shared/ITransformValue.ts +3 -0
- package/templates/app/interfaces/orionplace/state.ts +4 -0
- package/templates/app/interfaces/orionplace/stores/IStoreDirectory.ts +63 -0
- package/templates/app/interfaces/orionplace/subscribeOptions/ISubscribeOption.ts +9 -0
- package/templates/app/interfaces/orionplace/subscribeTariff/ISubscribeTariff.ts +56 -0
- package/templates/app/interfaces/orionplace/subscribeTariff/ITariffSelection.ts +11 -0
- package/templates/app/interfaces/orionplace/subscribes/ISubscribe.ts +28 -0
- package/templates/app/interfaces/orionplace/subscribes/ISubscriptionApi.ts +125 -0
- package/templates/app/interfaces/orionplace/tickets/ICustomerTicketApi.ts +223 -0
- package/templates/app/interfaces/orionplace/transport.ts +34 -0
- package/templates/app/layouts/default.vue +376 -0
- package/templates/app/middleware/00.orionplace.global.ts +27 -0
- package/templates/app/middleware/01.orionplace-sellers.global.ts +15 -0
- package/templates/app/middleware/orionplace-account.ts +40 -0
- package/templates/app/pages/activity.vue +19 -0
- package/templates/app/pages/addresses.vue +23 -0
- package/templates/app/pages/browse.vue +246 -0
- package/templates/app/pages/cart.vue +20 -0
- package/templates/app/pages/catalog.vue +17 -0
- package/templates/app/pages/category/[id].vue +142 -0
- package/templates/app/pages/contact.vue +17 -0
- package/templates/app/pages/featured.vue +144 -0
- package/templates/app/pages/index.vue +194 -0
- package/templates/app/pages/journal/[id].vue +128 -0
- package/templates/app/pages/journal/index.vue +67 -0
- package/templates/app/pages/logout.vue +71 -0
- package/templates/app/pages/manufacturers.vue +33 -0
- package/templates/app/pages/orders.vue +40 -0
- package/templates/app/pages/product/[id].vue +126 -0
- package/templates/app/pages/profile.vue +118 -0
- package/templates/app/pages/promo/[id].vue +67 -0
- package/templates/app/pages/promocodes.vue +21 -0
- package/templates/app/pages/sellers.vue +203 -0
- package/templates/app/pages/stores.vue +36 -0
- package/templates/app/pages/subscriptions.vue +21 -0
- package/templates/app/pages/tariffs/[slug]/[id].vue +126 -0
- package/templates/app/pages/tariffs/index.vue +50 -0
- package/templates/app/pages/tickets.vue +56 -0
- package/templates/app/pages/unsubscribe.vue +32 -0
- package/templates/app/pages/wallet.vue +23 -0
- package/templates/app/pages/wishlist.vue +48 -0
- package/templates/app/stores/orionplace.ts +493 -0
- package/templates/app/stores/orionplaceBrowse.ts +79 -0
- package/templates/app/stores/orionplaceCatalog.ts +121 -0
- package/templates/app/stores/orionplaceDomainAccess.ts +55 -0
- package/templates/app/stores/orionplaceProducts.ts +249 -0
- package/templates/app/stores/orionplaceSelections.ts +132 -0
- package/templates/app/themes/orionplace.ts +108 -0
- package/templates/app/utils/orionplace/accountLabels.ts +22 -0
- package/templates/app/utils/orionplace/activityLabels.ts +65 -0
- package/templates/app/utils/orionplace/activityPresentation.ts +16 -0
- package/templates/app/utils/orionplace/addressChanges.ts +26 -0
- package/templates/app/utils/orionplace/addressRegions.ts +17 -0
- package/templates/app/utils/orionplace/api.ts +333 -0
- package/templates/app/utils/orionplace/blogArticleHtml.ts +318 -0
- package/templates/app/utils/orionplace/blogComments.ts +133 -0
- package/templates/app/utils/orionplace/blogLabels.ts +111 -0
- package/templates/app/utils/orionplace/blogLayout.ts +95 -0
- package/templates/app/utils/orionplace/breadcrumbLabels.ts +11 -0
- package/templates/app/utils/orionplace/browseLabels.ts +98 -0
- package/templates/app/utils/orionplace/cartAddress.ts +94 -0
- package/templates/app/utils/orionplace/cartLabels.ts +261 -0
- package/templates/app/utils/orionplace/cartOptions.ts +143 -0
- package/templates/app/utils/orionplace/cartPreview.ts +108 -0
- package/templates/app/utils/orionplace/cartPromo.ts +150 -0
- package/templates/app/utils/orionplace/cartShipment.ts +74 -0
- package/templates/app/utils/orionplace/cartSnapshot.ts +20 -0
- package/templates/app/utils/orionplace/catalog.ts +106 -0
- package/templates/app/utils/orionplace/category.ts +52 -0
- package/templates/app/utils/orionplace/categoryLabels.ts +31 -0
- package/templates/app/utils/orionplace/contactLabels.ts +102 -0
- package/templates/app/utils/orionplace/currency.ts +128 -0
- package/templates/app/utils/orionplace/deliveryMap.ts +89 -0
- package/templates/app/utils/orionplace/directoryLabels.ts +131 -0
- package/templates/app/utils/orionplace/emptyStateArt.ts +231 -0
- package/templates/app/utils/orionplace/errorPageLabels.ts +80 -0
- package/templates/app/utils/orionplace/featureData.ts +25 -0
- package/templates/app/utils/orionplace/featureLabels.ts +271 -0
- package/templates/app/utils/orionplace/featuredLabels.ts +28 -0
- package/templates/app/utils/orionplace/files.ts +71 -0
- package/templates/app/utils/orionplace/footerLabels.ts +35 -0
- package/templates/app/utils/orionplace/guestSession.ts +50 -0
- package/templates/app/utils/orionplace/headerLabels.ts +68 -0
- package/templates/app/utils/orionplace/homeContent.ts +129 -0
- package/templates/app/utils/orionplace/homeLabels.ts +52 -0
- package/templates/app/utils/orionplace/htmlText.ts +59 -0
- package/templates/app/utils/orionplace/links.ts +14 -0
- package/templates/app/utils/orionplace/manufacturerIndex.ts +91 -0
- package/templates/app/utils/orionplace/modalWindow.ts +109 -0
- package/templates/app/utils/orionplace/nativeApp.ts +361 -0
- package/templates/app/utils/orionplace/notice.ts +22 -0
- package/templates/app/utils/orionplace/orderLabels.ts +309 -0
- package/templates/app/utils/orionplace/orderPresentation.ts +586 -0
- package/templates/app/utils/orionplace/pageSeo.ts +274 -0
- package/templates/app/utils/orionplace/paginationScroll.ts +131 -0
- package/templates/app/utils/orionplace/phone.ts +22 -0
- package/templates/app/utils/orionplace/presentation.ts +72 -0
- package/templates/app/utils/orionplace/productActionLabels.ts +60 -0
- package/templates/app/utils/orionplace/productActions.ts +547 -0
- package/templates/app/utils/orionplace/productAvailability.ts +36 -0
- package/templates/app/utils/orionplace/productGallery.ts +72 -0
- package/templates/app/utils/orionplace/productLabels.ts +82 -0
- package/templates/app/utils/orionplace/productManufacturer.ts +30 -0
- package/templates/app/utils/orionplace/productPage.ts +46 -0
- package/templates/app/utils/orionplace/productPhotos.ts +67 -0
- package/templates/app/utils/orionplace/productSearchScope.ts +237 -0
- package/templates/app/utils/orionplace/productSeller.ts +51 -0
- package/templates/app/utils/orionplace/profile.ts +136 -0
- package/templates/app/utils/orionplace/profileLabels.ts +151 -0
- package/templates/app/utils/orionplace/promoLabels.ts +75 -0
- package/templates/app/utils/orionplace/promoPresentation.ts +381 -0
- package/templates/app/utils/orionplace/reviewLabels.ts +172 -0
- package/templates/app/utils/orionplace/reviewScope.ts +41 -0
- package/templates/app/utils/orionplace/richText.ts +13 -0
- package/templates/app/utils/orionplace/searchFilters.ts +99 -0
- package/templates/app/utils/orionplace/searchHistory.ts +144 -0
- package/templates/app/utils/orionplace/sellerDirectory.ts +134 -0
- package/templates/app/utils/orionplace/seo.ts +52 -0
- package/templates/app/utils/orionplace/serverCookies.ts +88 -0
- package/templates/app/utils/orionplace/sessionLabels.ts +27 -0
- package/templates/app/utils/orionplace/signInReturn.ts +89 -0
- package/templates/app/utils/orionplace/storeDirectory.ts +50 -0
- package/templates/app/utils/orionplace/subscriptionChanges.ts +167 -0
- package/templates/app/utils/orionplace/subscriptionLabels.ts +67 -0
- package/templates/app/utils/orionplace/subscriptionManageLabels.ts +307 -0
- package/templates/app/utils/orionplace/subscriptionPlans.ts +162 -0
- package/templates/app/utils/orionplace/subscriptionRemote.ts +110 -0
- package/templates/app/utils/orionplace/subscriptionUsage.ts +82 -0
- package/templates/app/utils/orionplace/tariffLabels.ts +130 -0
- package/templates/app/utils/orionplace/tariffPage.ts +77 -0
- package/templates/app/utils/orionplace/tariffVariables.ts +165 -0
- package/templates/app/utils/orionplace/tariffs.ts +284 -0
- package/templates/app/utils/orionplace/ticketItems.ts +87 -0
- package/templates/app/utils/orionplace/ticketLabels.ts +335 -0
- package/templates/app/utils/orionplace/ticketLocation.ts +79 -0
- package/templates/app/utils/orionplace/walletTransaction.ts +135 -0
- package/templates/app/utils/orionplaceAppLoad.ts +73 -0
- package/templates/orionplace/COMPONENT-DOWNLOAD.md +40 -0
- package/templates/orionplace/COMPONENTS.md +1983 -0
- package/templates/orionplace/THEMES.md +94 -0
package/src/setup.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { backendUrl, frontendDomain } from './validation.mjs';
|
|
|
6
6
|
import { projectReadme } from './project-readme.mjs';
|
|
7
7
|
|
|
8
8
|
const metadata = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
|
|
9
|
-
const hash
|
|
9
|
+
const hash = text => createHash('sha256').update(text).digest('hex');
|
|
10
10
|
async function read(path) {
|
|
11
11
|
try { return await readFile(path, 'utf8'); }
|
|
12
12
|
catch (error) { if (error.code === 'ENOENT') return null; throw error; }
|
|
@@ -14,7 +14,7 @@ async function read(path) {
|
|
|
14
14
|
async function safePath(root, name) {
|
|
15
15
|
const target = resolve(root, name);
|
|
16
16
|
if (relative(root, target).startsWith('..') || target === root) throw new Error('Invalid generated path');
|
|
17
|
-
let cursor
|
|
17
|
+
let cursor = root;
|
|
18
18
|
for (const piece of relative(root, target).split(sep)) {
|
|
19
19
|
cursor = resolve(cursor, piece);
|
|
20
20
|
try { if ((await lstat(cursor)).isSymbolicLink()) throw new Error(`Refusing symbolic link: ${name}`); }
|
|
@@ -24,10 +24,12 @@ async function safePath(root, name) {
|
|
|
24
24
|
}
|
|
25
25
|
function configureNuxt(source) {
|
|
26
26
|
try {
|
|
27
|
-
const module
|
|
28
|
-
const options
|
|
27
|
+
const module = parseModule(source);
|
|
28
|
+
const options = module.exports.default.$type === 'function-call'
|
|
29
29
|
? module.exports.default.$args[0] : module.exports.default;
|
|
30
30
|
if (!options || options.$type !== 'object') throw new Error('Dynamic configuration');
|
|
31
|
+
// Pin the existing Nuxt fallback without changing a customer's chosen date.
|
|
32
|
+
if (options.compatibilityDate === undefined) options.compatibilityDate = '2025-07-15';
|
|
31
33
|
if (options.nitro?.preset && options.nitro.preset !== 'node-server') throw new Error('Unsupported Nitro preset');
|
|
32
34
|
if (options.srcDir || options.serverDir || options.extends) throw new Error('Custom directories or layers');
|
|
33
35
|
for (const route of ['/api', '/api/**', '/api/*']) {
|
|
@@ -35,6 +37,11 @@ function configureNuxt(source) {
|
|
|
35
37
|
}
|
|
36
38
|
if (options.vite?.server?.proxy?.['/api']) throw new Error('Conflicting Vite proxy');
|
|
37
39
|
options.modules ||= [];
|
|
40
|
+
if (!Array.from(options.modules).some(item => item === '@pinia/nuxt' || (Array.isArray(item) && item[0] === '@pinia/nuxt'))) {
|
|
41
|
+
options.modules.unshift('@pinia/nuxt');
|
|
42
|
+
}
|
|
43
|
+
if (options.pages === false) throw new Error('Route middleware requires Nuxt pages');
|
|
44
|
+
options.pages = true;
|
|
38
45
|
if (!Array.from(options.modules).some(item => item === 'orionplace-nuxt' || (Array.isArray(item) && item[0] === 'orionplace-nuxt'))) {
|
|
39
46
|
options.modules.push('orionplace-nuxt');
|
|
40
47
|
}
|
|
@@ -44,8 +51,8 @@ function configureNuxt(source) {
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
function updateEnvironment(source, domain) {
|
|
47
|
-
const lines
|
|
48
|
-
let updated
|
|
54
|
+
const lines = (source || '').split(/\r?\n/);
|
|
55
|
+
let updated = false;
|
|
49
56
|
const result = lines.flatMap(line => {
|
|
50
57
|
if (!/^\s*(?:export\s+)?MIMIC_FRONT_DOMAIN\s*=/.test(line)) return [line];
|
|
51
58
|
if (updated) return [];
|
|
@@ -57,27 +64,36 @@ function updateEnvironment(source, domain) {
|
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
export async function setupProject({ cwd = process.cwd(), action = 'set', field, value, dryRun = false } = {}) {
|
|
60
|
-
if (!['set', 'add', 'remove'].includes(action) ||
|
|
67
|
+
if (!['set', 'add', 'remove', 'update'].includes(action) ||
|
|
68
|
+
(['add', 'remove'].includes(action) && field !== 'frontend') || (action === 'update' && field)) {
|
|
61
69
|
throw new Error('Use set backend, add frontend, remove frontend, set mimic, or set frontend.');
|
|
62
70
|
}
|
|
63
|
-
const root
|
|
64
|
-
const setting
|
|
71
|
+
const root = resolve(cwd);
|
|
72
|
+
const setting = field === 'backend' ? backendUrl(value) : ['frontend', 'mimic'].includes(field) ? frontendDomain(value) : null;
|
|
65
73
|
if (field && !setting) throw new Error('Choose backend, frontend, or mimic.');
|
|
66
|
-
const names
|
|
67
|
-
const current
|
|
74
|
+
const names = ['package.json', 'nuxt.config.ts', 'nuxt.config.js', 'nuxt.config.mjs', 'orionplace/settings.json', 'orionplace/.generated.json', '.env', '.gitignore'];
|
|
75
|
+
const current = {};
|
|
68
76
|
for (const name of names) current[name] = await read(await safePath(root, name));
|
|
69
|
-
const pkg
|
|
70
|
-
const dependencies
|
|
77
|
+
const pkg = current['package.json'] ? JSON.parse(current['package.json']) : { name: 'orionplace-storefront', private: true, type: 'module' };
|
|
78
|
+
const dependencies = { ...pkg.devDependencies, ...pkg.dependencies };
|
|
79
|
+
for (const name of ['tailwindcss', '@tailwindcss/vite']) {
|
|
80
|
+
if (dependencies[name] && !/^(?:[~^]|>=)?4(?:\.|$)/.test(dependencies[name])) {
|
|
81
|
+
throw new Error(`Orionplace components require ${name} 4. Upgrade the existing dependency before setup. No files were changed.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (action === 'update' && (!dependencies.nuxt || !current['orionplace/settings.json'] || !current['orionplace/.generated.json'])) {
|
|
85
|
+
throw new Error('Update requires an initialized Orionplace Nuxt project. Run init first.');
|
|
86
|
+
}
|
|
71
87
|
if (!dependencies.nuxt && ['next', '@sveltejs/kit'].some(name => dependencies[name])) throw new Error('This package sets up Nuxt projects only.');
|
|
72
88
|
if (dependencies.nuxt && !/^(?:[~^]|>=)?4(?:\.|$)/.test(dependencies.nuxt)) {
|
|
73
89
|
throw new Error('This release supports Nuxt 4. Upgrade your Nuxt dependency before setup.');
|
|
74
90
|
}
|
|
75
|
-
const configs
|
|
91
|
+
const configs = ['nuxt.config.ts', 'nuxt.config.js', 'nuxt.config.mjs'].filter(name => current[name] !== null);
|
|
76
92
|
if (configs.length > 1) throw new Error('Multiple Nuxt configuration files found; keep one root config.');
|
|
77
|
-
const configName
|
|
78
|
-
const config
|
|
93
|
+
const configName = configs[0] || 'nuxt.config.ts';
|
|
94
|
+
const config = configureNuxt(current[configName] || 'export default defineNuxtConfig({ modules: [] });\n');
|
|
79
95
|
for (const directory of ['server/api', 'server/routes/api']) {
|
|
80
|
-
const path
|
|
96
|
+
const path = await safePath(root, directory);
|
|
81
97
|
let entries = [];
|
|
82
98
|
try { entries = await readdir(path); }
|
|
83
99
|
catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
@@ -85,17 +101,17 @@ export async function setupProject({ cwd = process.cwd(), action = 'set', field,
|
|
|
85
101
|
throw new Error(`Existing API catch-all in ${directory}. Resolve this route conflict first.`);
|
|
86
102
|
}
|
|
87
103
|
}
|
|
88
|
-
const settings
|
|
89
|
-
const previous
|
|
104
|
+
const settings = current['orionplace/settings.json'] ? JSON.parse(current['orionplace/settings.json']) : {};
|
|
105
|
+
const previous = current['orionplace/.generated.json'] ? JSON.parse(current['orionplace/.generated.json']) : {};
|
|
90
106
|
if (settings.backend) settings.backend = backendUrl(settings.backend);
|
|
91
107
|
if (settings.frontend) settings.frontend = frontendDomain(settings.frontend);
|
|
92
|
-
const oldFrontend
|
|
108
|
+
const oldFrontend = settings.frontend;
|
|
93
109
|
// Migrate the initial single-domain format, including its previously generated mappings.
|
|
94
|
-
const legacyDomains
|
|
110
|
+
const legacyDomains = Object.keys(previous)
|
|
95
111
|
.map(name => /^sitemaps\/([^/]+)\.cfg$/.exec(name)?.[1]).filter(Boolean);
|
|
96
|
-
const frontends
|
|
112
|
+
const frontends = settings.frontends ?? [settings.frontend, ...legacyDomains].filter(Boolean);
|
|
97
113
|
if (!Array.isArray(frontends)) throw new Error('settings.frontends must be an array of domain names.');
|
|
98
|
-
settings.frontends
|
|
114
|
+
settings.frontends = [...new Set(frontends.map(frontendDomain))];
|
|
99
115
|
if (settings.frontend && !settings.frontends.includes(settings.frontend)) settings.frontends.unshift(settings.frontend);
|
|
100
116
|
if (field === 'backend') settings.backend = setting;
|
|
101
117
|
if (field === 'mimic') {
|
|
@@ -115,13 +131,13 @@ export async function setupProject({ cwd = process.cwd(), action = 'set', field,
|
|
|
115
131
|
if (action === 'set' || !settings.frontend) settings.frontend = setting;
|
|
116
132
|
}
|
|
117
133
|
}
|
|
118
|
-
settings.frontend
|
|
134
|
+
settings.frontend ||= settings.frontends[0];
|
|
119
135
|
if (!settings.frontend) delete settings.frontend;
|
|
120
|
-
const manifest
|
|
121
|
-
const changes
|
|
122
|
-
const preserved
|
|
136
|
+
const manifest = { ...previous };
|
|
137
|
+
const changes = new Map();
|
|
138
|
+
const preserved = [];
|
|
123
139
|
async function plan(name, content, { managed = false, preserve = false } = {}) {
|
|
124
|
-
const path
|
|
140
|
+
const path = await safePath(root, name);
|
|
125
141
|
const existing = await read(path);
|
|
126
142
|
if (managed && existing !== null && existing !== content && previous[name] !== hash(existing)) {
|
|
127
143
|
if (preserve && previous[name]) { preserved.push(name); return; }
|
|
@@ -140,38 +156,71 @@ export async function setupProject({ cwd = process.cwd(), action = 'set', field,
|
|
|
140
156
|
}
|
|
141
157
|
// All checks and content generation happen before the first write.
|
|
142
158
|
await plan(configName, config);
|
|
143
|
-
const isNewNuxt
|
|
144
|
-
pkg.scripts
|
|
145
|
-
pkg.scripts.dev
|
|
146
|
-
pkg.scripts.build
|
|
147
|
-
pkg.scripts.preview
|
|
148
|
-
pkg.scripts['orionplace:backend']
|
|
149
|
-
pkg.scripts['orionplace:frontend']
|
|
150
|
-
pkg.scripts['orionplace:add-frontend']
|
|
159
|
+
const isNewNuxt = !dependencies.nuxt;
|
|
160
|
+
pkg.scripts ||= {};
|
|
161
|
+
pkg.scripts.dev ||= 'nuxt dev';
|
|
162
|
+
pkg.scripts.build ||= 'nuxt build';
|
|
163
|
+
pkg.scripts.preview ||= 'nuxt preview';
|
|
164
|
+
pkg.scripts['orionplace:backend'] ||= 'orionplace-nuxt set backend';
|
|
165
|
+
pkg.scripts['orionplace:frontend'] ||= 'orionplace-nuxt set frontend';
|
|
166
|
+
pkg.scripts['orionplace:add-frontend'] ||= 'orionplace-nuxt add frontend';
|
|
151
167
|
pkg.scripts['orionplace:remove-frontend'] ||= 'orionplace-nuxt remove frontend';
|
|
152
|
-
pkg.scripts['orionplace:mimic']
|
|
153
|
-
pkg.scripts['orionplace:help']
|
|
154
|
-
pkg.
|
|
155
|
-
pkg.dependencies
|
|
168
|
+
pkg.scripts['orionplace:mimic'] ||= 'orionplace-nuxt set mimic';
|
|
169
|
+
pkg.scripts['orionplace:help'] ||= 'orionplace-nuxt help';
|
|
170
|
+
pkg.scripts['orionplace:update'] ||= 'orionplace-nuxt update';
|
|
171
|
+
pkg.dependencies ||= {};
|
|
172
|
+
pkg.dependencies['libphonenumber-js'] ||= dependencies['libphonenumber-js'] || '^1.13.10';
|
|
173
|
+
pkg.dependencies['country-flag-icons'] ||= dependencies['country-flag-icons'] || '^1.6.20';
|
|
174
|
+
pkg.dependencies.dompurify ||= dependencies.dompurify || '^3.4.13';
|
|
175
|
+
pkg.dependencies.pinia ||= dependencies.pinia || '^4.0.2';
|
|
176
|
+
pkg.dependencies['@pinia/nuxt'] ||= dependencies['@pinia/nuxt'] || '^1.0.1';
|
|
177
|
+
pkg.dependencies['orionplace-nuxt'] ||= dependencies['orionplace-nuxt'] || `^${metadata.version}`;
|
|
178
|
+
if (action === 'update') {
|
|
179
|
+
pkg.dependencies['orionplace-nuxt'] = metadata.version;
|
|
180
|
+
if (pkg.devDependencies) delete pkg.devDependencies['orionplace-nuxt'];
|
|
181
|
+
}
|
|
156
182
|
if (isNewNuxt) {
|
|
157
|
-
pkg.dependencies.nuxt
|
|
158
|
-
pkg.dependencies.vue
|
|
183
|
+
pkg.dependencies.nuxt = '^4.5.0';
|
|
184
|
+
pkg.dependencies.vue ||= '^3.5.0';
|
|
159
185
|
pkg.dependencies['vue-router'] ||= '^5.0.0';
|
|
160
186
|
}
|
|
187
|
+
// Install the complete editable AppLoad source. Never replace a customer's app.
|
|
188
|
+
const appPath = 'app/app.vue';
|
|
189
|
+
const existingApp = await read(await safePath(root, appPath));
|
|
190
|
+
const installApp = existingApp === null || Boolean(previous[appPath]);
|
|
191
|
+
const templateRoot = new URL('../templates/', import.meta.url);
|
|
192
|
+
async function planTemplates(directory = '') {
|
|
193
|
+
for (const entry of await readdir(new URL(directory, templateRoot), { withFileTypes: true })) {
|
|
194
|
+
const name = directory + entry.name;
|
|
195
|
+
if (entry.isDirectory()) { await planTemplates(name + '/'); continue; }
|
|
196
|
+
if (name === appPath && !installApp) continue;
|
|
197
|
+
// A customer's own home page and editor settings stay theirs.
|
|
198
|
+
if (['app/pages/index.vue', '.vscode/settings.json'].includes(name) && !previous[name] && await read(await safePath(root, name)) !== null) continue;
|
|
199
|
+
await plan(name, await readFile(new URL(name, templateRoot), 'utf8'), { managed: true, preserve: true });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
await planTemplates();
|
|
203
|
+
pkg.devDependencies ||= {};
|
|
204
|
+
for (const name of ['tailwindcss', '@tailwindcss/vite']) {
|
|
205
|
+
if (!dependencies[name]) pkg.devDependencies[name] = '^4.3.3';
|
|
206
|
+
}
|
|
207
|
+
if (!await read(await safePath(root, 'tsconfig.json'))) {
|
|
208
|
+
await plan('tsconfig.json', JSON.stringify({ files: [], references: [
|
|
209
|
+
{ path: './.nuxt/tsconfig.app.json' }, { path: './.nuxt/tsconfig.server.json' },
|
|
210
|
+
{ path: './.nuxt/tsconfig.shared.json' }, { path: './.nuxt/tsconfig.node.json' },
|
|
211
|
+
] }, null, 2) + '\n', { managed: true });
|
|
212
|
+
}
|
|
161
213
|
await plan('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
162
214
|
for (const file of ['marketplace.mjs', 'api.mjs', 'domain.mjs']) {
|
|
163
215
|
await plan(`orionplace/runtime/${file}`, await readFile(new URL(`../runtime/${file}`, import.meta.url), 'utf8'), { managed: true, preserve: true });
|
|
164
216
|
}
|
|
165
217
|
await plan('orionplace/README.md', projectReadme(settings), { managed: true, preserve: true });
|
|
166
|
-
if (isNewNuxt && !(await read(await safePath(root, 'app/app.vue')))) {
|
|
167
|
-
await plan('app/app.vue', '<template>\n <main>\n <h1>Your marketplace</h1>\n <p>Domain setup and API instructions are in orionplace/README.md.</p>\n </main>\n</template>\n', { managed: true });
|
|
168
|
-
}
|
|
169
218
|
// A new project starts explicitly empty; keep a pre-existing manual setting on init.
|
|
170
|
-
const hasMimicSetting
|
|
171
|
-
if (settings.frontend || oldFrontend || !hasMimicSetting) {
|
|
219
|
+
const hasMimicSetting = /^\s*(?:export\s+)?MIMIC_FRONT_DOMAIN\s*=/m.test(current['.env'] || '');
|
|
220
|
+
if (action !== 'update' && (settings.frontend || oldFrontend || !hasMimicSetting)) {
|
|
172
221
|
await plan('.env', updateEnvironment(current['.env'], settings.frontend || ''));
|
|
173
222
|
}
|
|
174
|
-
if (settings.backend) {
|
|
223
|
+
if (settings.backend && action !== 'update') {
|
|
175
224
|
const mappings = action === 'remove' || field === 'mimic' ? []
|
|
176
225
|
: field === 'frontend' ? [setting] : settings.frontends;
|
|
177
226
|
for (const domain of mappings) {
|
|
@@ -179,16 +228,16 @@ export async function setupProject({ cwd = process.cwd(), action = 'set', field,
|
|
|
179
228
|
}
|
|
180
229
|
}
|
|
181
230
|
if (action === 'remove') await planRemoval(`sitemaps/${setting}.cfg`);
|
|
182
|
-
let ignore
|
|
231
|
+
let ignore = current['.gitignore'] || '';
|
|
183
232
|
for (const entry of ['node_modules/', '.nuxt/', '.output/', '.env', '.env.*', '!.env.example']) {
|
|
184
233
|
if (!ignore.split(/\r?\n/).includes(entry)) ignore = ignore.replace(/\n*$/, '\n') + entry + '\n';
|
|
185
234
|
}
|
|
186
235
|
await plan('.gitignore', ignore);
|
|
187
|
-
await plan('orionplace/settings.json', JSON.stringify(settings, null, 2) + '\n');
|
|
236
|
+
if (action !== 'update') await plan('orionplace/settings.json', JSON.stringify(settings, null, 2) + '\n');
|
|
188
237
|
await plan('orionplace/.generated.json', JSON.stringify(manifest, null, 2) + '\n');
|
|
189
238
|
if (!dryRun) {
|
|
190
239
|
for (const [name, content] of changes) {
|
|
191
|
-
const target
|
|
240
|
+
const target = await safePath(root, name);
|
|
192
241
|
if (content === null) { await unlink(target); continue; }
|
|
193
242
|
await mkdir(dirname(target), { recursive: true });
|
|
194
243
|
const temporary = `${target}.orionplace-${process.pid}.tmp`;
|
package/src/update.mjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { setupProject } from './setup.mjs';
|
|
4
|
+
|
|
5
|
+
export function runNpm(args, cwd) {
|
|
6
|
+
const npmCli = process.env.npm_execpath;
|
|
7
|
+
const command = npmCli ? process.execPath : 'npm';
|
|
8
|
+
const commandArgs = npmCli ? [npmCli, ...args] : args;
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const child = spawn(command, commandArgs, { cwd, stdio: 'inherit', shell: false });
|
|
11
|
+
child.once('error', reject);
|
|
12
|
+
child.once('exit', (code, signal) => code === 0 ? resolve() : reject(new Error(
|
|
13
|
+
`npm ${args[0]} failed (${signal || code}).`,
|
|
14
|
+
)));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function updateProject({ cwd = process.cwd(), dryRun = false, local = false, npm = runNpm } = {}) {
|
|
19
|
+
cwd = resolve(cwd);
|
|
20
|
+
// Validate before downloading or writing; the latest CLI repeats preflight with its own templates.
|
|
21
|
+
const preview = await setupProject({ cwd, action: 'update', dryRun: true });
|
|
22
|
+
if (!local) {
|
|
23
|
+
console.log('Checking the latest Orionplace Nuxt release…');
|
|
24
|
+
await npm(['exec', '--yes', '--prefer-online', '--package=orionplace-nuxt@latest', '--',
|
|
25
|
+
'orionplace-nuxt', 'update', '--local', '--cwd', cwd, ...(dryRun ? ['--dry-run'] : [])], cwd);
|
|
26
|
+
return null; // The latest CLI reports its own changes.
|
|
27
|
+
}
|
|
28
|
+
if (dryRun) return preview;
|
|
29
|
+
const result = await setupProject({ cwd, action: 'update' });
|
|
30
|
+
try {
|
|
31
|
+
await npm(['install', '--no-audit', '--no-fund'], cwd);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw new Error(`Source files were updated, but dependency installation failed. Run npm install in the project, then retry update. ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
package/src/validation.mjs
CHANGED
|
@@ -25,3 +25,9 @@ export function backendUrl(value) {
|
|
|
25
25
|
}
|
|
26
26
|
return `${url.origin}/api`;
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
// The Android app sends its API requests to this public storefront over HTTPS.
|
|
30
|
+
export function appOrigin(value) {
|
|
31
|
+
if (/^\s*http:/i.test(value)) throw new Error('ORIONPLACE_APP_ORIGIN must use HTTPS.');
|
|
32
|
+
return `https://${frontendDomain(value.trim())}`;
|
|
33
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { watch } from 'vue';
|
|
3
|
+
import { useOrionplaceStore } from '@/stores/orionplace';
|
|
4
|
+
import { NuxtLayout, NuxtLoadingIndicator, NuxtPage } from '#components';
|
|
5
|
+
import { showError, useHead, useRoute } from '#imports';
|
|
6
|
+
import OrionplaceThemeProvider from '@/components/orionplace/theme/OrionplaceThemeProvider.vue';
|
|
7
|
+
import { useOrionplaceTheme } from '@/composables/useOrionplaceTheme';
|
|
8
|
+
import { storefrontPageError } from '@/composables/useOrionplaceMissingPage';
|
|
9
|
+
|
|
10
|
+
const store = useOrionplaceStore();
|
|
11
|
+
const route = useRoute();
|
|
12
|
+
const { mode } = useOrionplaceTheme();
|
|
13
|
+
|
|
14
|
+
useHead(() => ({
|
|
15
|
+
htmlAttrs: { lang: store.localeCode },
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
// The middleware opens the 503 error page during navigation. A refresh that
|
|
19
|
+
// fails while a page is open, for example after sign-in, opens it too.
|
|
20
|
+
watch(
|
|
21
|
+
() => store.status,
|
|
22
|
+
(status) => {
|
|
23
|
+
const error = route.matched.length
|
|
24
|
+
? storefrontPageError(status, false, '')
|
|
25
|
+
: undefined;
|
|
26
|
+
|
|
27
|
+
if (error) {
|
|
28
|
+
void showError(error);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<OrionplaceThemeProvider
|
|
36
|
+
:mode="mode"
|
|
37
|
+
class="min-h-screen"
|
|
38
|
+
>
|
|
39
|
+
<NuxtLoadingIndicator
|
|
40
|
+
:height="2"
|
|
41
|
+
color="var(--orionplace-inverse-text)"
|
|
42
|
+
error-color="var(--orionplace-danger)"
|
|
43
|
+
/>
|
|
44
|
+
<NuxtLayout>
|
|
45
|
+
<NuxtPage />
|
|
46
|
+
</NuxtLayout>
|
|
47
|
+
</OrionplaceThemeProvider>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@theme inline {
|
|
2
|
+
--font-orionplace: "Inter", "Helvetica Neue", Helvetica, Arial, system-ui,
|
|
3
|
+
sans-serif;
|
|
4
|
+
--color-orionplace-background: var(--orionplace-background);
|
|
5
|
+
--color-orionplace-surface: var(--orionplace-surface);
|
|
6
|
+
--color-orionplace-muted-surface: var(--orionplace-muted-surface);
|
|
7
|
+
--color-orionplace-text: var(--orionplace-text);
|
|
8
|
+
--color-orionplace-muted: var(--orionplace-muted);
|
|
9
|
+
--color-orionplace-border: var(--orionplace-border);
|
|
10
|
+
--color-orionplace-accent: var(--orionplace-accent);
|
|
11
|
+
--color-orionplace-hover: var(--orionplace-hover);
|
|
12
|
+
--color-orionplace-inverse-surface: var(--orionplace-inverse-surface);
|
|
13
|
+
--color-orionplace-inverse-text: var(--orionplace-inverse-text);
|
|
14
|
+
--color-orionplace-inverse-muted: var(--orionplace-inverse-muted);
|
|
15
|
+
--color-orionplace-success: var(--orionplace-success);
|
|
16
|
+
--color-orionplace-success-surface: var(--orionplace-success-surface);
|
|
17
|
+
--color-orionplace-danger: var(--orionplace-danger);
|
|
18
|
+
--color-orionplace-danger-surface: var(--orionplace-danger-surface);
|
|
19
|
+
--color-orionplace-attention: var(--orionplace-attention);
|
|
20
|
+
--color-orionplace-attention-surface: var(--orionplace-attention-surface);
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@layer theme, base, components, utilities;
|
|
2
|
+
|
|
3
|
+
@import "tailwindcss/theme.css" layer(theme);
|
|
4
|
+
@import "tailwindcss/utilities.css" layer(utilities);
|
|
5
|
+
@import "@/assets/css/orionplace-tokens.css";
|
|
6
|
+
|
|
7
|
+
@source "../../components/";
|
|
8
|
+
@source "../../pages/";
|
|
9
|
+
@source "../../layouts/";
|
|
10
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
11
|
+
|
|
12
|
+
@layer base {
|
|
13
|
+
a {
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Tailwind's preflight is not loaded, so form controls would keep the
|
|
19
|
+
* browser's own font (system-ui) inside the storefront's theme font.
|
|
20
|
+
* Sizes stay with each component's classes.
|
|
21
|
+
*/
|
|
22
|
+
button,
|
|
23
|
+
input,
|
|
24
|
+
select,
|
|
25
|
+
textarea {
|
|
26
|
+
font-family: inherit;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# AccountActivity · Nuxt
|
|
2
|
+
|
|
3
|
+
The user’s promo codes, reviews and sign-in history.
|
|
4
|
+
|
|
5
|
+
The supplied storefront uses this component at `/activity`.
|
|
6
|
+
[English guide](https://orionmarket.place/en/sandbox/components/nuxt/activity) ·
|
|
7
|
+
[Russian guide](https://orionmarket.place/ru/sandbox/components/nuxt/activity)
|
|
8
|
+
|
|
9
|
+
## Contract and dependencies
|
|
10
|
+
|
|
11
|
+
Opening shows the promo codes. A `tab` in the address opens that section
|
|
12
|
+
instead, so `/activity?tab=logs` leads straight to the sign-in history; an
|
|
13
|
+
unknown value opens the promo codes. Switching sections creates the selected
|
|
14
|
+
component and loads its data. The parent `AccountSection` opens private
|
|
15
|
+
sections after sign-in.
|
|
16
|
+
|
|
17
|
+
The guide describes its inputs and events. Source is maintained in
|
|
18
|
+
`app/components/orionplace/account/AccountActivity.vue`; the primary interface is `app/interfaces/orionplace/accounts/IProfileData.ts`.
|
|
19
|
+
|
|
20
|
+
The configured Nuxt starter initializes Application Load and its named API client.
|
|
21
|
+
Component-source ZIPs contain imported children, types,
|
|
22
|
+
composables, labels and styles. The included `orionplace/COMPONENT-DOWNLOAD.md`
|
|
23
|
+
describes dependencies, theme and consumer configuration. Standalone file
|
|
24
|
+
copying requires the same dependencies. Links to storefront routes use the
|
|
25
|
+
pages supplied by the full starter.
|
|
26
|
+
|
|
27
|
+
## Endpoint coverage
|
|
28
|
+
|
|
29
|
+
- `profile_get_logs`
|
|
30
|
+
- `profile_promocodes_get`
|
|
31
|
+
- `products_feedbacks_mine_get`
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watch } from 'vue';
|
|
3
|
+
import { useRoute } from '#imports';
|
|
4
|
+
import { useOrionplaceSelectionsStore } from '@/stores/orionplaceSelections';
|
|
5
|
+
import { activityLabels } from '@/utils/orionplace/activityLabels';
|
|
6
|
+
import SignInHistory from '@/components/orionplace/account/SignInHistory.vue';
|
|
7
|
+
import AccountPromocodes from '@/components/orionplace/account/AccountPromocodes.vue';
|
|
8
|
+
import ProductReviews from '@/components/orionplace/products/ProductReviews.vue';
|
|
9
|
+
import '@/components/orionplace/shared/features.css';
|
|
10
|
+
import '@/components/orionplace/account/account.css';
|
|
11
|
+
|
|
12
|
+
const route = useRoute();
|
|
13
|
+
const selectionStore = useOrionplaceSelectionsStore();
|
|
14
|
+
const labels = computed(() => activityLabels(selectionStore.localeCode));
|
|
15
|
+
const tabs = computed(() => ({
|
|
16
|
+
promocodes: labels.value.promocodesTab,
|
|
17
|
+
reviews: labels.value.reviewsTab,
|
|
18
|
+
logs: labels.value.logsTab,
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
// A `tab` in the address opens that section, so a link can lead straight to
|
|
22
|
+
// the promo codes. Any other value opens the first section.
|
|
23
|
+
function requested() {
|
|
24
|
+
const value = String(route.query.tab ?? '');
|
|
25
|
+
|
|
26
|
+
return value in tabs.value ? value : 'promocodes';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const active = ref(requested());
|
|
30
|
+
|
|
31
|
+
watch(() => route.query.tab, () => {
|
|
32
|
+
active.value = requested();
|
|
33
|
+
});
|
|
34
|
+
</script>
|
|
35
|
+
<template>
|
|
36
|
+
<section
|
|
37
|
+
class="op-feature @container op-feature-stack op-account"
|
|
38
|
+
data-feature-part="AccountActivity"
|
|
39
|
+
>
|
|
40
|
+
<h1 class="op-feature-title">{{ labels.title }}</h1>
|
|
41
|
+
<div class="op-feature-actions op-account-tabs">
|
|
42
|
+
<button
|
|
43
|
+
class="op-feature-button"
|
|
44
|
+
v-for="[key, title] in Object.entries(tabs)"
|
|
45
|
+
:key="key"
|
|
46
|
+
type="button"
|
|
47
|
+
:data-activity-tab="key"
|
|
48
|
+
:aria-pressed="active === key"
|
|
49
|
+
@click="active = key"
|
|
50
|
+
>
|
|
51
|
+
{{ title }}
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
<AccountPromocodes v-if="active === 'promocodes'" />
|
|
55
|
+
<ProductReviews
|
|
56
|
+
v-else-if="active === 'reviews'"
|
|
57
|
+
own
|
|
58
|
+
/>
|
|
59
|
+
<SignInHistory v-else />
|
|
60
|
+
</section>
|
|
61
|
+
</template>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# AccountPromocodes · Nuxt
|
|
2
|
+
|
|
3
|
+
Available promo codes and applying a selected code to the cart.
|
|
4
|
+
|
|
5
|
+
The supplied storefront uses this component at `/activity`.
|
|
6
|
+
[English guide](https://orionmarket.place/en/sandbox/components/nuxt/account-promocodes) ·
|
|
7
|
+
[Russian guide](https://orionmarket.place/ru/sandbox/components/nuxt/account-promocodes)
|
|
8
|
+
|
|
9
|
+
## Contract and dependencies
|
|
10
|
+
|
|
11
|
+
`profile_promocodes_get` loads the codes issued to the user. Every code shows
|
|
12
|
+
its conditions in separate rows: the discount and, for a percentage code,
|
|
13
|
+
its maximum (`maximum_discount`), the products, categories or sellers the offer
|
|
14
|
+
covers, the minimum order (`minimum_order_amount`: what the covered products must cost
|
|
15
|
+
together, the whole cart when the offer names none;
|
|
16
|
+
a dollar amount, shown as “$ 544 ≈ 40 256 ₽” in another currency and “$ 544” in dollars), “Only for the first
|
|
17
|
+
purchase in the store” when `first_order_only` is `true`, whether items that
|
|
18
|
+
already have a discount count, the dates the offer runs between and how many
|
|
19
|
+
uses are left. A row whose field is missing is left out. A code without a use limit shows no counter.
|
|
20
|
+
|
|
21
|
+
The badge beside a code names the one reason it cannot be applied now: it is
|
|
22
|
+
already applied to the cart, it is not available, its offer has run out, or it
|
|
23
|
+
starts on a later date (a scheduled offer stays inactive until that day). Only
|
|
24
|
+
a code without such a reason shows Apply.
|
|
25
|
+
|
|
26
|
+
Applying sends `code_value` to `marketing_promo_promo_apply`. The
|
|
27
|
+
`applyed_to_cart` mark changes after confirmation, then the list refreshes. A
|
|
28
|
+
refused code shows the reason in its own card, under its buttons, where a
|
|
29
|
+
phone shows it; a list that fails to load shows its error above the list with
|
|
30
|
+
Retry. The
|
|
31
|
+
cart link opens the cart with its current totals. Each code also links to the
|
|
32
|
+
products its offer applies to, passing the code in that address so the path of
|
|
33
|
+
the products page can name it.
|
|
34
|
+
|
|
35
|
+
The guide describes its inputs and events. Source is maintained in
|
|
36
|
+
`app/components/orionplace/account/AccountPromocodes.vue`; the primary interface is `app/interfaces/orionplace/marketing/IPromoActions.ts`.
|
|
37
|
+
The component belongs to the `activity` composition; render it with that
|
|
38
|
+
parent's controller and context.
|
|
39
|
+
|
|
40
|
+
The configured Nuxt starter initializes Application Load and its named API client.
|
|
41
|
+
Component-source ZIPs contain imported children, types,
|
|
42
|
+
composables, labels and styles. The included `orionplace/COMPONENT-DOWNLOAD.md`
|
|
43
|
+
describes dependencies, theme and consumer configuration. Standalone file
|
|
44
|
+
copying requires the same dependencies. Links to storefront routes use the
|
|
45
|
+
pages supplied by the full starter.
|
|
46
|
+
|
|
47
|
+
## Endpoint coverage
|
|
48
|
+
|
|
49
|
+
- `profile_promocodes_get`
|
|
50
|
+
- `marketing_promo_promo_apply`
|