@osimart/create-storefront 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/README.md +80 -2
  2. package/THEME_DEV_API.md +80 -0
  3. package/app/app.vue +154 -0
  4. package/app/assets/css/osi-controls.css +824 -0
  5. package/app/components/SectionRenderer.vue +46 -0
  6. package/app/components/builder/BuilderOverlay.vue +582 -0
  7. package/app/components/checkout/ExtraFees.vue +329 -0
  8. package/app/components/checkout/PaymentHandoff.vue +388 -0
  9. package/app/components/common/Banner.vue +35 -0
  10. package/app/components/common/ConfirmDeleteModal.vue +117 -0
  11. package/app/components/common/DropdownSelect.vue +432 -0
  12. package/app/components/common/Loader.vue +32 -0
  13. package/app/components/common/OsiField.vue +218 -0
  14. package/app/components/common/PhoneNumInput.vue +434 -0
  15. package/app/composables/UseBodyScrollLock.js +122 -0
  16. package/app/composables/UseThemeGroup.js +575 -0
  17. package/app/composables/useAddToCart.js +87 -0
  18. package/app/composables/useAnalytics.js +15 -0
  19. package/app/composables/useAnnouncements.js +29 -0
  20. package/app/composables/useApiErrorToast.js +104 -0
  21. package/app/composables/useAuth.js +99 -0
  22. package/app/composables/useBanners.js +25 -0
  23. package/app/composables/useBuilderPreview.js +320 -0
  24. package/app/composables/useButtonStyle.js +107 -0
  25. package/app/composables/useCarousel.js +160 -0
  26. package/app/composables/useCart.js +109 -0
  27. package/app/composables/useCheckout.js +76 -0
  28. package/app/composables/useClassificationItems.js +269 -0
  29. package/app/composables/useClassificationPage.js +545 -0
  30. package/app/composables/useClassificationUrl.js +63 -0
  31. package/app/composables/useColorScheme.js +44 -0
  32. package/app/composables/useContactForm.js +53 -0
  33. package/app/composables/useContentTree.js +770 -0
  34. package/app/composables/useDragScroll.js +73 -0
  35. package/app/composables/useFooterSocials.js +107 -0
  36. package/app/composables/useInputStyle.js +45 -0
  37. package/app/composables/useLayoutShell.js +114 -0
  38. package/app/composables/useLazyVideo.js +36 -0
  39. package/app/composables/useMediaTypes.js +66 -0
  40. package/app/composables/useMediaUrl.js +71 -0
  41. package/app/composables/useMenu.js +100 -0
  42. package/app/composables/useNavStyle.js +219 -0
  43. package/app/composables/usePlaceholders.js +294 -0
  44. package/app/composables/usePolicies.js +26 -0
  45. package/app/composables/useProductCardMedia.js +135 -0
  46. package/app/composables/useProductCardStyle.js +132 -0
  47. package/app/composables/useProductDetail.js +982 -0
  48. package/app/composables/useProductGallery.js +166 -0
  49. package/app/composables/useProductItems.js +270 -0
  50. package/app/composables/useProductUrl.js +60 -0
  51. package/app/composables/useProductVariants.js +210 -0
  52. package/app/composables/useQuickShop.js +115 -0
  53. package/app/composables/useRelatedProducts.js +186 -0
  54. package/app/composables/useRenderContext.js +45 -0
  55. package/app/composables/useScopedCss.js +106 -0
  56. package/app/composables/useSearch.js +35 -0
  57. package/app/composables/useSectionData.js +462 -0
  58. package/app/composables/useSectionShell.js +113 -0
  59. package/app/composables/useSidebar.js +69 -0
  60. package/app/composables/useStoreData.js +57 -0
  61. package/app/composables/useStoreInit.js +52 -0
  62. package/app/composables/useStorefront.js +239 -0
  63. package/app/composables/useT.js +21 -0
  64. package/app/composables/useTextStyles.js +84 -0
  65. package/app/composables/useThemeControls.js +34 -0
  66. package/app/composables/useThemeSeo.js +91 -0
  67. package/app/composables/useThemeTokens.js +171 -0
  68. package/app/composables/useWishlist.js +66 -0
  69. package/app/logic/components/AnnouncementBar.js +118 -0
  70. package/app/logic/components/CardGrid.js +125 -0
  71. package/app/logic/components/CardList.js +98 -0
  72. package/app/logic/components/CartDrawer.js +273 -0
  73. package/app/logic/components/CartItem.js +31 -0
  74. package/app/logic/components/ClassificationBento.js +6 -0
  75. package/app/logic/components/ClassificationCard.js +6 -0
  76. package/app/logic/components/ClassificationCarousel.js +115 -0
  77. package/app/logic/components/ClassificationEditorial.js +41 -0
  78. package/app/logic/components/ClassificationFeatured.js +57 -0
  79. package/app/logic/components/ClassificationGrid.js +6 -0
  80. package/app/logic/components/ClassificationNav.js +61 -0
  81. package/app/logic/components/ClassificationPart.js +72 -0
  82. package/app/logic/components/FooterBlock.js +91 -0
  83. package/app/logic/components/FooterSocials.js +60 -0
  84. package/app/logic/components/HeaderDropdownList.js +29 -0
  85. package/app/logic/components/HeaderIcon.js +68 -0
  86. package/app/logic/components/HeaderLogo.js +39 -0
  87. package/app/logic/components/HeaderNav.js +268 -0
  88. package/app/logic/components/MobileMenu.js +280 -0
  89. package/app/logic/components/ProductBuyButtons.js +66 -0
  90. package/app/logic/components/ProductCard.js +160 -0
  91. package/app/logic/components/ProductFilters.js +37 -0
  92. package/app/logic/components/ProductGallery.js +19 -0
  93. package/app/logic/components/ProductInfoBlock.js +411 -0
  94. package/app/logic/components/ProductLightbox.js +12 -0
  95. package/app/logic/components/ProductQuantity.js +31 -0
  96. package/app/logic/components/ProductVariantPicker.js +125 -0
  97. package/app/logic/components/QuickBuy.js +194 -0
  98. package/app/logic/components/SearchOverlay.js +41 -0
  99. package/app/logic/components/SidebarMenuItem.js +39 -0
  100. package/app/logic/components/SiteFooter.js +476 -0
  101. package/app/logic/components/SiteHeader.js +266 -0
  102. package/app/logic/components/WhatsAppButton.js +75 -0
  103. package/app/logic/layouts/default.js +66 -0
  104. package/app/logic/sections/AnnouncementBarSection.js +6 -0
  105. package/app/logic/sections/BlockCarousel.js +103 -0
  106. package/app/logic/sections/ClassificationListSection.js +40 -0
  107. package/app/logic/sections/ContactFormSection.js +294 -0
  108. package/app/logic/sections/ContactInfoSection.js +419 -0
  109. package/app/logic/sections/ContentNode.js +189 -0
  110. package/app/logic/sections/CountdownSection.js +254 -0
  111. package/app/logic/sections/CustomHtmlSection.js +51 -0
  112. package/app/logic/sections/DividerSection.js +31 -0
  113. package/app/logic/sections/FaqSection.js +53 -0
  114. package/app/logic/sections/FeatureListSection.js +6 -0
  115. package/app/logic/sections/FeaturedProductSection.js +40 -0
  116. package/app/logic/sections/FooterSection.js +16 -0
  117. package/app/logic/sections/FooterUtilitiesSection.js +24 -0
  118. package/app/logic/sections/GallerySection.js +232 -0
  119. package/app/logic/sections/HeaderSection.js +24 -0
  120. package/app/logic/sections/HeroSection.js +24 -0
  121. package/app/logic/sections/LogoListSection.js +6 -0
  122. package/app/logic/sections/MainClassificationSection.js +473 -0
  123. package/app/logic/sections/MainProductSection.js +211 -0
  124. package/app/logic/sections/MainSearchSection.js +6 -0
  125. package/app/logic/sections/MapSection.js +92 -0
  126. package/app/logic/sections/MediaContentSection.js +38 -0
  127. package/app/logic/sections/MediaWithTextSection.js +238 -0
  128. package/app/logic/sections/NewsletterSection.js +126 -0
  129. package/app/logic/sections/ProductHighlightSection.js +201 -0
  130. package/app/logic/sections/ProductListSection.js +45 -0
  131. package/app/logic/sections/ProductRecommendationsSection.js +113 -0
  132. package/app/logic/sections/RichTextSection.js +6 -0
  133. package/app/logic/sections/ScrollingTextSection.js +69 -0
  134. package/app/logic/sections/SearchHeaderSection.js +22 -0
  135. package/app/logic/sections/SlideshowSection.js +118 -0
  136. package/app/logic/sections/SpacerSection.js +37 -0
  137. package/app/logic/sections/SplitShowcaseSection.js +6 -0
  138. package/app/logic/sections/TestimonialListSection.js +6 -0
  139. package/app/logic/sections/VideoSection.js +235 -0
  140. package/app/pages/[category]/[product].vue +196 -0
  141. package/app/pages/__builder-preview.vue +38 -0
  142. package/app/pages/categories/[slug].vue +208 -0
  143. package/app/pages/checkout.vue +1972 -0
  144. package/app/pages/forgot-password.vue +115 -0
  145. package/app/pages/index.vue +64 -0
  146. package/app/pages/login.vue +585 -0
  147. package/app/pages/order-detail.vue +442 -0
  148. package/app/pages/pages/[handle].vue +58 -0
  149. package/app/pages/privacy-policy.vue +46 -0
  150. package/app/pages/resetpassword.vue +138 -0
  151. package/app/pages/resetverificationcode.vue +163 -0
  152. package/app/pages/result.vue +203 -0
  153. package/app/pages/return-policy.vue +50 -0
  154. package/app/pages/search.vue +100 -0
  155. package/app/pages/shipping-policy.vue +46 -0
  156. package/app/pages/user-profile/components/AddAddressModal.vue +452 -0
  157. package/app/pages/user-profile/components/Whishlist.vue +137 -0
  158. package/app/pages/user-profile/components/left-bar.vue +233 -0
  159. package/app/pages/user-profile/components/orders.vue +162 -0
  160. package/app/pages/user-profile/components/profile-details.vue +566 -0
  161. package/app/pages/user-profile/components/settings.vue +194 -0
  162. package/app/pages/user-profile/index.vue +252 -0
  163. package/app/pages/verificationcode.vue +188 -0
  164. package/app/plugins/analytics.client.js +99 -0
  165. package/app/plugins/geo.js +24 -0
  166. package/app/plugins/reveal.client.js +53 -0
  167. package/app/plugins/toast.js +10 -0
  168. package/app/plugins/vue-query.js +5 -0
  169. package/app/services/ApiServices.js +74 -0
  170. package/app/services/AuthBus.js +162 -0
  171. package/app/services/Authentication/AuthenticationService.js +133 -0
  172. package/app/services/Authentication/TokenService.js +62 -0
  173. package/app/services/CartServices.js +91 -0
  174. package/app/services/CartToken.js +26 -0
  175. package/app/services/CategoryServices.js +54 -0
  176. package/app/services/CheckoutServices.js +113 -0
  177. package/app/services/HomeServices.js +133 -0
  178. package/app/services/NewsletterServices.js +29 -0
  179. package/app/services/PaymentServices.js +71 -0
  180. package/app/services/PoliciesServices.js +16 -0
  181. package/app/services/ProductServices.js +79 -0
  182. package/app/services/SearchServices.js +18 -0
  183. package/app/services/UserServices.js +105 -0
  184. package/app/services/UtilsServices.js +46 -0
  185. package/app/services/WishlistServices.js +51 -0
  186. package/app/services/storefront.service.js +57 -0
  187. package/app/stores/userStore.js +13 -0
  188. package/app/theme/categoryTree.js +68 -0
  189. package/app/theme/controls.js +88 -0
  190. package/app/theme/registry.js +56 -0
  191. package/app/utils/analytics.js +864 -0
  192. package/app/utils/device.js +50 -0
  193. package/app/utils/eventBus.js +24 -0
  194. package/app/utils/icon-presets.js +24 -0
  195. package/app/utils/productOffers.js +118 -0
  196. package/app/utils/requestCache.js +36 -0
  197. package/app/utils/scrollToError.js +59 -0
  198. package/app/utils/toPlainError.js +30 -0
  199. package/bin/osimart-theme.mjs +282 -0
  200. package/nuxt/osi-sections.ts +56 -0
  201. package/nuxt.config.ts +60 -0
  202. package/package.json +44 -4
  203. package/public/css/input.css +29 -0
  204. package/public/css/output.css +2716 -0
  205. package/public/favicon-32x32.png +0 -0
  206. package/public/robots.txt +2 -0
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <banner pageTitle="Forgot password" />
3
+
4
+ <div class="osi-auth-wrap font-body">
5
+ <form class="osi-auth-card" novalidate @submit.prevent="submitForm">
6
+ <p class="osi-auth-title">Enter your email to reset your password</p>
7
+
8
+ <div class="osi-auth-stack">
9
+ <OsiField
10
+ v-model="email"
11
+ id="forgot-email"
12
+ label="Email"
13
+ type="email"
14
+ autocomplete="email"
15
+ required
16
+ :error="errors.email"
17
+ @input="clearError('email')"
18
+ />
19
+
20
+ <button
21
+ type="submit"
22
+ class="osi-btn osi-btn--block osi-auth-submit"
23
+ :disabled="isLoading"
24
+ :aria-busy="isLoading"
25
+ >
26
+ <span v-if="isLoading" class="osi-btn-spinner" aria-hidden="true" />
27
+ <span>Submit</span>
28
+ </button>
29
+ </div>
30
+ </form>
31
+ </div>
32
+ </template>
33
+
34
+ <script>
35
+ import { Banner as banner } from "#components";
36
+ import { OsiField } from "#components";
37
+ import AuthenticationService from "../services/Authentication/AuthenticationService";
38
+ import { useToast } from "vue-toastification";
39
+ export default {
40
+ data() {
41
+ return {
42
+ isLoading: false,
43
+ email: "",
44
+ errors: {
45
+ email: false,
46
+ },
47
+ };
48
+ },
49
+ components: {
50
+ OsiField,
51
+ banner,
52
+ },
53
+ methods: {
54
+ validateEmail(email) {
55
+ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
56
+ return emailPattern.test(email);
57
+ },
58
+ async submitForm() {
59
+ const toast = useToast();
60
+ this.errors.email = "";
61
+
62
+ if (!this.email) {
63
+ this.errors.email = "Email is required.";
64
+ } else if (!this.validateEmail(this.email)) {
65
+ this.errors.email = "Invalid email format.";
66
+ }
67
+
68
+ if (!this.errors.email) {
69
+ try {
70
+ this.isLoading = true;
71
+ const response = await AuthenticationService.forgotPassword(
72
+ this.email
73
+ );
74
+ toast.success("An email has been sent to your account!");
75
+ this.$router.push({
76
+ path: "/resetverificationcode",
77
+ query: { email: this.email },
78
+ });
79
+ } catch (error) {
80
+ this.isLoading = false;
81
+ const message = error.data?.email?.[0] || error.data?.detail || error.message || "Something went wrong.";
82
+ toast.error(message);
83
+ } finally {
84
+ this.isLoading = false;
85
+ }
86
+ }
87
+ },
88
+ clearError(field) {
89
+ this.errors[field] = "";
90
+ },
91
+ },
92
+ };
93
+ </script>
94
+
95
+ <style scoped>
96
+ .osi-auth-wrap {
97
+ display: flex;
98
+ justify-content: center;
99
+ padding: 2.5rem 1.25rem;
100
+ }
101
+ @media (min-width: 768px) {
102
+ .osi-auth-wrap {
103
+ padding-block: 5rem;
104
+ }
105
+ }
106
+ .osi-auth-title {
107
+ margin: 0 0 1.25rem;
108
+ text-align: center;
109
+ font-size: 1.5rem;
110
+ line-height: 1.3;
111
+ }
112
+ .osi-auth-submit {
113
+ margin-top: 0.5rem;
114
+ }
115
+ </style>
@@ -0,0 +1,64 @@
1
+ <script setup>
2
+ /**
3
+ * Homepage.
4
+ *
5
+ * Every theme-driven route is this same shape: ask the backend which template
6
+ * serves this path, publish the payload, hand the sections to SectionRenderer.
7
+ * Nothing here knows what a hero is.
8
+ *
9
+ * `render()` returns sections already filtered (disabled and out-of-window
10
+ * dropped), media already resolved to URLs, and products already fetched into
11
+ * `section.data` — so no section component makes a request of its own. A
12
+ * six-section homepage is one round trip.
13
+ */
14
+ import { useRenderContext } from '#osi/composables/useRenderContext';
15
+
16
+ const { render, store } = useStorefront();
17
+ const { setRenderContext } = useRenderContext();
18
+
19
+ const { data, error } = await useAsyncData("render:/", () => render("/"));
20
+ console.log("[render] API response:", JSON.stringify(data.value, null, 2))
21
+
22
+ // Publish before the sections mount. MAIN_* sections read `resource` from here
23
+ // rather than taking it as a prop — SectionRenderer only passes `section` and
24
+ // `index`, and in the builder there's no page render to drill from anyway.
25
+ // INDEX resolves no resource, but the template still belongs in the context.
26
+ setRenderContext(data.value);
27
+ watch(data, (payload) => setRenderContext(payload));
28
+
29
+ // Read here, not in the template: import.meta is module syntax and Vue compiles
30
+ // template expressions as scripts.
31
+ const isDev = import.meta.dev;
32
+
33
+ </script>
34
+
35
+ <template>
36
+ <div>
37
+ <SectionRenderer v-if="data?.sections?.length" :sections="data.sections" />
38
+
39
+ <!-- A theme with no INDEX sections isn't an error — a merchant who hasn't
40
+ built a homepage yet should see something, not a blank page. -->
41
+ <div v-else-if="!error" class="osi-empty">
42
+ <p>This store's homepage hasn't been set up yet.</p>
43
+ </div>
44
+
45
+ <div v-else class="osi-empty">
46
+ <p>We couldn't load this page.</p>
47
+ <pre v-if="isDev" class="osi-empty-detail">{{ error.message }}</pre>
48
+ </div>
49
+ </div>
50
+ </template>
51
+
52
+ <style scoped>
53
+ .osi-empty {
54
+ padding: 6rem 1rem;
55
+ text-align: center;
56
+ color: var(--osi-text);
57
+ opacity: 0.7;
58
+ }
59
+ .osi-empty-detail {
60
+ margin-top: 1rem;
61
+ font-size: 12px;
62
+ white-space: pre-wrap;
63
+ }
64
+ </style>