@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,233 @@
1
+ <template>
2
+ <div
3
+ class="w-full flex flex-col justify-center items-center gap-5 font-body"
4
+ >
5
+ <div
6
+ class="flex flex-col w-full xlg1:w-[70%] shadow-md border border-gray-100 bg-gray-50"
7
+ >
8
+ <div class="w-full flex flex-col justify-center items-center pb-10 gap-5">
9
+ <div
10
+ class="w-[80px] s:w-[100px] h-[80px] s:h-[100px] rounded-full border border-gray-50 shadow-md flex justify-center items-center p-1 bg-white absolute"
11
+ >
12
+ <img
13
+ v-if="logoSrc"
14
+ :src="logoSrc"
15
+ :alt="store?.name || 'Logo'"
16
+ class="w-full object-cover"
17
+ />
18
+ </div>
19
+ </div>
20
+ <div
21
+ class="h-fit p-5 flex flex-col md:flex-row md:gap-10 md:justify-center items-start md:items-center"
22
+ >
23
+ <a
24
+ @click="selectStep('profileDetails')"
25
+ class="cursor-pointer w-full md:w-auto"
26
+ >
27
+ <div
28
+ class="w-full py-3 border-b border-gray-100 md:border-none flex justify-start items-center gap-2"
29
+ :class="{
30
+ 'text-primaryColor': activeStep === 'profileDetails',
31
+ 'text-gray-500': activeStep !== 'profileDetails',
32
+ }"
33
+ >
34
+ <svg
35
+ xmlns="http://www.w3.org/2000/svg"
36
+ viewBox="0 0 24 24"
37
+ width="24"
38
+ height="24"
39
+ fill="none"
40
+ stroke="currentColor"
41
+ stroke-width="1.5"
42
+ stroke-linecap="round"
43
+ stroke-linejoin="round"
44
+ >
45
+ <path
46
+ d="M6.57757 15.4816C5.1628 16.324 1.45336 18.0441 3.71266 20.1966C4.81631 21.248 6.04549 22 7.59087 22H16.4091C17.9545 22 19.1837 21.248 20.2873 20.1966C22.5466 18.0441 18.8372 16.324 17.4224 15.4816C14.1048 13.5061 9.89519 13.5061 6.57757 15.4816Z"
47
+ />
48
+ <path
49
+ d="M16.5 6.5C16.5 8.98528 14.4853 11 12 11C9.51472 11 7.5 8.98528 7.5 6.5C7.5 4.01472 9.51472 2 12 2C14.4853 2 16.5 4.01472 16.5 6.5Z"
50
+ />
51
+ </svg>
52
+ <p>Profile Details</p>
53
+ </div>
54
+ </a>
55
+
56
+ <a
57
+ class="group cursor-pointer w-full md:w-auto"
58
+ @click="selectStep('Whishlist')"
59
+ >
60
+ <div
61
+ class="w-full py-3 border-b border-gray-100 md:border-none flex justify-start items-center gap-2 group-hover:text-primaryColor"
62
+ :class="{
63
+ 'text-primaryColor': activeStep === 'Whishlist',
64
+ 'text-gray-500': activeStep !== 'Whishlist',
65
+ }"
66
+ >
67
+ <svg
68
+ xmlns="http://www.w3.org/2000/svg"
69
+ viewBox="0 0 24 24"
70
+ width="24"
71
+ height="24"
72
+ class="group-hover:text-primaryColor duration-300"
73
+ fill="none"
74
+ >
75
+ <path
76
+ d="M19.4626 3.99415C16.7809 2.34923 14.4404 3.01211 13.0344 4.06801C12.4578 4.50096 12.1696 4.71743 12 4.71743C11.8304 4.71743 11.5422 4.50096 10.9656 4.06801C9.55962 3.01211 7.21909 2.34923 4.53744 3.99415C1.01807 6.15294 0.221721 13.2749 8.33953 19.2834C9.88572 20.4278 10.6588 21 12 21C13.3412 21 14.1143 20.4278 15.6605 19.2834C23.7783 13.2749 22.9819 6.15294 19.4626 3.99415Z"
77
+ stroke="currentColor"
78
+ stroke-width="1.5"
79
+ stroke-linecap="round"
80
+ />
81
+ </svg>
82
+
83
+ <p class="duration-300">Wishlist</p>
84
+ </div>
85
+ </a>
86
+
87
+ <a
88
+ class="group cursor-pointer w-full md:w-auto"
89
+ @click="selectStep('Orders')"
90
+ >
91
+ <div
92
+ class="w-full py-3 border-b border-gray-100 md:border-none group-hover:text-primaryColor flex justify-start items-center gap-2"
93
+ :class="{
94
+ 'text-primaryColor': activeStep === 'Orders',
95
+ 'text-gray-500': activeStep !== 'Orders',
96
+ }"
97
+ >
98
+ <svg
99
+ xmlns="http://www.w3.org/2000/svg"
100
+ viewBox="0 0 24 24"
101
+ width="24"
102
+ height="24"
103
+ class="group-hover:text-primaryColor duration-300"
104
+ fill="none"
105
+ >
106
+ <path
107
+ d="M3.87289 17.0194L2.66933 9.83981C2.48735 8.75428 2.39637 8.21152 2.68773 7.85576C2.9791 7.5 3.51461 7.5 4.58564 7.5H19.4144C20.4854 7.5 21.0209 7.5 21.3123 7.85576C21.6036 8.21152 21.5126 8.75428 21.3307 9.83981L20.1271 17.0194C19.7282 19.3991 19.5287 20.5889 18.7143 21.2945C17.9 22 16.726 22 14.3782 22H9.62182C7.27396 22 6.10003 22 5.28565 21.2945C4.47127 20.5889 4.27181 19.3991 3.87289 17.0194Z"
108
+ stroke="currentColor"
109
+ stroke-width="1.5"
110
+ />
111
+ <path
112
+ d="M17.5 7.5C17.5 4.46243 15.0376 2 12 2C8.96243 2 6.5 4.46243 6.5 7.5"
113
+ stroke="currentColor"
114
+ stroke-width="1.5"
115
+ />
116
+ </svg>
117
+
118
+ <p class="duration-300">Orders</p>
119
+ </div>
120
+ </a>
121
+
122
+ <a
123
+ class="group cursor-pointer w-full md:w-auto"
124
+ @click="selectStep('settings')"
125
+ >
126
+ <div
127
+ class="w-full border-b border-gray-100 md:border-none py-3 flex justify-start items-center gap-2"
128
+ :class="{
129
+ 'text-primaryColor': activeStep === 'settings',
130
+ 'text-gray-500': activeStep !== 'settings',
131
+ }"
132
+ >
133
+ <svg
134
+ xmlns="http://www.w3.org/2000/svg"
135
+ viewBox="0 0 24 24"
136
+ class="group-hover:text-primaryColor duration-300"
137
+ width="24"
138
+ height="24"
139
+ fill="none"
140
+ >
141
+ <path
142
+ d="M15.5 12C15.5 13.933 13.933 15.5 12 15.5C10.067 15.5 8.5 13.933 8.5 12C8.5 10.067 10.067 8.5 12 8.5C13.933 8.5 15.5 10.067 15.5 12Z"
143
+ stroke="currentColor"
144
+ stroke-width="1.5"
145
+ />
146
+ <path
147
+ d="M21.011 14.0965C21.5329 13.9558 21.7939 13.8854 21.8969 13.7508C22 13.6163 22 13.3998 22 12.9669V11.0332C22 10.6003 22 10.3838 21.8969 10.2493C21.7938 10.1147 21.5329 10.0443 21.011 9.90358C19.0606 9.37759 17.8399 7.33851 18.3433 5.40087C18.4817 4.86799 18.5509 4.60156 18.4848 4.44529C18.4187 4.28902 18.2291 4.18134 17.8497 3.96596L16.125 2.98673C15.7528 2.77539 15.5667 2.66972 15.3997 2.69222C15.2326 2.71472 15.0442 2.90273 14.6672 3.27873C13.208 4.73448 10.7936 4.73442 9.33434 3.27864C8.95743 2.90263 8.76898 2.71463 8.60193 2.69212C8.43489 2.66962 8.24877 2.77529 7.87653 2.98663L6.15184 3.96587C5.77253 4.18123 5.58287 4.28891 5.51678 4.44515C5.45068 4.6014 5.51987 4.86787 5.65825 5.4008C6.16137 7.3385 4.93972 9.37763 2.98902 9.9036C2.46712 10.0443 2.20617 10.1147 2.10308 10.2492C2 10.3838 2 10.6003 2 11.0332V12.9669C2 13.3998 2 13.6163 2.10308 13.7508C2.20615 13.8854 2.46711 13.9558 2.98902 14.0965C4.9394 14.6225 6.16008 16.6616 5.65672 18.5992C5.51829 19.1321 5.44907 19.3985 5.51516 19.5548C5.58126 19.7111 5.77092 19.8188 6.15025 20.0341L7.87495 21.0134C8.24721 21.2247 8.43334 21.3304 8.6004 21.3079C8.76746 21.2854 8.95588 21.0973 9.33271 20.7213C10.7927 19.2644 13.2088 19.2643 14.6689 20.7212C15.0457 21.0973 15.2341 21.2853 15.4012 21.3078C15.5682 21.3303 15.7544 21.2246 16.1266 21.0133L17.8513 20.034C18.2307 19.8187 18.4204 19.711 18.4864 19.5547C18.5525 19.3984 18.4833 19.132 18.3448 18.5991C17.8412 16.6616 19.0609 14.6226 21.011 14.0965Z"
148
+ stroke="currentColor"
149
+ stroke-width="1.5"
150
+ stroke-linecap="round"
151
+ />
152
+ </svg>
153
+
154
+ <p class="group-hover:text-primaryColor duration-300">Settings</p>
155
+ </div>
156
+ </a>
157
+
158
+ <router-link @click="logout" class="group" to="/">
159
+ <div
160
+ class="w-full py-3 flex justify-start items-center gap-2 text-gray-500"
161
+ >
162
+ <svg
163
+ xmlns="http://www.w3.org/2000/svg"
164
+ viewBox="0 0 24 24"
165
+ class="text-gray-500 group-hover:text-primaryColor duration-300"
166
+ width="24"
167
+ height="24"
168
+ color="#000000"
169
+ fill="none"
170
+ >
171
+ <circle
172
+ cx="12"
173
+ cy="12"
174
+ r="10"
175
+ stroke="currentColor"
176
+ stroke-width="1.5"
177
+ />
178
+ <path
179
+ d="M16 12H8M16 12C16 11.2998 14.0057 9.99153 13.5 9.5M16 12C16 12.7002 14.0057 14.0085 13.5 14.5"
180
+ stroke="currentColor"
181
+ stroke-width="1.5"
182
+ stroke-linecap="round"
183
+ stroke-linejoin="round"
184
+ />
185
+ </svg>
186
+
187
+ <p class="group-hover:text-primaryColor duration-300">Logout</p>
188
+ </div>
189
+ </router-link>
190
+ </div>
191
+ </div>
192
+ </div>
193
+ </template>
194
+
195
+ <script>
196
+ import { computed } from "vue";
197
+ import { authBus } from "../../../services/AuthBus";
198
+ import { useStorefront } from "#osi/composables/useStorefront";
199
+ import { useMediaUrl } from "#osi/composables/useMediaUrl";
200
+
201
+ export default {
202
+ setup() {
203
+ const { storeLogo, store } = useStorefront();
204
+ const { mediaUrl } = useMediaUrl();
205
+
206
+ const logoSrc = computed(() => mediaUrl(storeLogo.value));
207
+
208
+ return {
209
+ storeLogo,
210
+ store,
211
+ logoSrc,
212
+ };
213
+ },
214
+ props: {
215
+ activeStep: String,
216
+ user: {
217
+ type: Object,
218
+ required: true,
219
+ },
220
+ },
221
+ methods: {
222
+ async logout() {
223
+ await authBus.logout();
224
+ this.$router.push("/");
225
+ },
226
+ selectStep(step) {
227
+ this.$emit("select-step", step);
228
+ },
229
+ },
230
+ };
231
+ </script>
232
+
233
+ <style></style>
@@ -0,0 +1,162 @@
1
+ <template>
2
+ <div
3
+ class="w-full xlg1:w-[70%] h-fit shadow-md bg-gray-50 px-5 pb-5 font-body"
4
+ >
5
+ <div v-if="allOrders.length">
6
+ <div class="w-full flex flex-col mt-5 gap-5">
7
+ <div
8
+ v-for="order in sortedOrders"
9
+ :key="order.id"
10
+ class="w-full flex bg-white flex-col py-5 px-5"
11
+ >
12
+ <div class="flex flex-col gap-5">
13
+ <div class="flex justify-between">
14
+ <div>
15
+ <p class="text-gray-500 uppercase text-[17px]">
16
+ {{ getLatestStatus(order) || "NA" }}
17
+ </p>
18
+ <p class="text-gray-500 font-heading uppercase text-[17px]">
19
+ {{ new Date(order?.purchased_at).toLocaleString() }}
20
+ </p>
21
+ </div>
22
+ <div
23
+ class="text-gray-500 cursor-pointer"
24
+ @click="goToOrderHistory(order?.id)"
25
+ >
26
+ Go to order
27
+ </div>
28
+ </div>
29
+ <div class="pb-5">
30
+ <p class="text-gray-500 font-bold">
31
+ {{ currency }}{{ order?.checkout_cart_price + order?.checkout_delivery_fees }}
32
+ </p>
33
+ </div>
34
+ </div>
35
+ <div class="w-full max-w-[1800px] grid grid-cols-2 sm:grid-cols-4">
36
+ <div
37
+ v-for="(item, index) in getCartItemsWithLink(order?.items || [])"
38
+ :key="index"
39
+ class="transition-all w-full sm:w-[200px] duration-300"
40
+ >
41
+ <component
42
+ :is="item.productLink ? 'RouterLink' : 'div'"
43
+ :to="item.productLink"
44
+ class="border w-full sm:w-[200px] flex border-gray-100 relative"
45
+ >
46
+ <div
47
+ class="absolute top-3 right-3 bg-white h-[30px] w-[30px] p-1 border border-primaryColor flex justify-center items-center text-primaryColor"
48
+ >
49
+ {{ item.quantity }}
50
+ </div>
51
+ <img
52
+ :src="mediaUrl(item.image?.path)"
53
+ :alt="item.name"
54
+ class="w-full sm:w-[200px] h-[300px] object-cover"
55
+ />
56
+ </component>
57
+ <div class="w-full flex gap-2 p-2 justify-between items-start">
58
+ <div class="flex flex-col gap-2">
59
+ <p class="text-gray-500 text-sm line-clamp-1">
60
+ {{ item.name }}
61
+ </p>
62
+ <p
63
+ class="text-gray-500 text-xs mt-1"
64
+ v-if="item.variant_values"
65
+ >
66
+ {{ item.variant_values }}
67
+ </p>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ <div v-else>
77
+ <div class="w-full flex flex-col pt-5 justify-center items-center gap-5">
78
+ <svg
79
+ xmlns="http://www.w3.org/2000/svg"
80
+ fill="none"
81
+ viewBox="0 0 24 24"
82
+ stroke-width="1.5"
83
+ stroke="currentColor"
84
+ class="w-[50%] s:w-[200px] text-primaryColor opacity-10"
85
+ >
86
+ <path
87
+ stroke-linecap="round"
88
+ stroke-linejoin="round"
89
+ d="M15.75 10.5V6a3.75 3.75 0 1 0-7.5 0v4.5m11.356-1.993 1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 0 1-1.12-1.243l1.264-12A1.125 1.125 0 0 1 5.513 7.5h12.974c.576 0 1.059.435 1.119 1.007ZM8.625 10.5a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm7.5 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
90
+ />
91
+ </svg>
92
+ <p
93
+ class="text-primaryColor font-body text-xl s:text-2xl text-center"
94
+ >
95
+ You have no orders at the moment.
96
+ </p>
97
+ <div class="text-center text-gray-500">
98
+ <p class="font-body text-sm">You don't have any orders yet.</p>
99
+ <p class="font-body text-sm">
100
+ You will find many interesting products on the "Shopping" page.
101
+ </p>
102
+ </div>
103
+ <router-link to="/" class="osi-btn mb-5">Continue Shopping</router-link>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </template>
108
+
109
+ <script setup>
110
+ import { computed } from "vue";
111
+ import { useRouter } from "vue-router";
112
+
113
+ const props = defineProps({
114
+ allOrders: {
115
+ type: Array,
116
+ required: true,
117
+ },
118
+ });
119
+
120
+ const { mediaUrl } = useMediaUrl();
121
+ const router = useRouter();
122
+ const { store } = useStorefront();
123
+
124
+ const currency = computed(
125
+ () => store.value?.default_currency?.symbol || store.value?.default_currency?.code || "$"
126
+ );
127
+
128
+ const sortedOrders = computed(() =>
129
+ [...props.allOrders].sort(
130
+ (a, b) => new Date(b.purchased_at) - new Date(a.purchased_at),
131
+ ),
132
+ );
133
+
134
+ const goToOrderHistory = (id) => {
135
+ sessionStorage.setItem("orderId", id);
136
+ router.push("/order-detail/");
137
+ };
138
+
139
+ const getLatestStatus = (order) => {
140
+ if (!order?.statuses?.length) return null;
141
+
142
+ const latest = order.statuses.reduce((latest, status) =>
143
+ new Date(status.date) > new Date(latest.date) ? status : latest,
144
+ );
145
+
146
+ return latest.status_name;
147
+ };
148
+
149
+ const getCartItemsWithLink = (items = []) => {
150
+ return items.map((item) => {
151
+ const product = item?.product?.product;
152
+ const categorySlug = product?.categories?.[0]?.category?.slugified_name;
153
+ const productSlug = product?.slugified_name;
154
+
155
+ return {
156
+ ...item,
157
+ productLink:
158
+ categorySlug && productSlug ? `/${categorySlug}/${productSlug}` : null,
159
+ };
160
+ });
161
+ };
162
+ </script>