spree_storefront 5.0.0.rc1

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 (341) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +13 -0
  3. data/Rakefile +15 -0
  4. data/app/assets/config/spree_storefront_manifest.js +6 -0
  5. data/app/assets/stylesheets/storefront_page_builder.css +51 -0
  6. data/app/controllers/concerns/spree/cart_methods.rb +40 -0
  7. data/app/controllers/concerns/spree/locale_urls.rb +23 -0
  8. data/app/controllers/concerns/spree/password_protected.rb +17 -0
  9. data/app/controllers/concerns/spree/theme_concern.rb +29 -0
  10. data/app/controllers/spree/account/addresses_controller.rb +16 -0
  11. data/app/controllers/spree/account/base_controller.rb +20 -0
  12. data/app/controllers/spree/account/newsletter_controller.rb +34 -0
  13. data/app/controllers/spree/account/orders_controller.rb +34 -0
  14. data/app/controllers/spree/account/profile_controller.rb +23 -0
  15. data/app/controllers/spree/account/store_credits_controller.rb +23 -0
  16. data/app/controllers/spree/account/wished_items_controller.rb +45 -0
  17. data/app/controllers/spree/addresses_controller.rb +101 -0
  18. data/app/controllers/spree/checkout_controller.rb +365 -0
  19. data/app/controllers/spree/contacts_controller.rb +46 -0
  20. data/app/controllers/spree/digital_links_controller.rb +48 -0
  21. data/app/controllers/spree/home_controller.rb +5 -0
  22. data/app/controllers/spree/line_items_controller.rb +96 -0
  23. data/app/controllers/spree/newsletter_subscribers_controller.rb +43 -0
  24. data/app/controllers/spree/order_status_controller.rb +32 -0
  25. data/app/controllers/spree/orders_controller.rb +104 -0
  26. data/app/controllers/spree/page_sections_controller.rb +17 -0
  27. data/app/controllers/spree/pages_controller.rb +13 -0
  28. data/app/controllers/spree/password_controller.rb +21 -0
  29. data/app/controllers/spree/policies_controller.rb +17 -0
  30. data/app/controllers/spree/posts_controller.rb +76 -0
  31. data/app/controllers/spree/products_controller.rb +99 -0
  32. data/app/controllers/spree/search_controller.rb +39 -0
  33. data/app/controllers/spree/seo_controller.rb +25 -0
  34. data/app/controllers/spree/settings_controller.rb +68 -0
  35. data/app/controllers/spree/store_controller.rb +247 -0
  36. data/app/controllers/spree/taxonomies_controller.rb +30 -0
  37. data/app/controllers/spree/taxons_controller.rb +46 -0
  38. data/app/controllers/spree/wishlists_controller.rb +19 -0
  39. data/app/finders/spree/storefront/variant_finder.rb +80 -0
  40. data/app/helpers/spree/analytics_helper.rb +28 -0
  41. data/app/helpers/spree/cart_helper.rb +48 -0
  42. data/app/helpers/spree/checkout_analytics_helper.rb +77 -0
  43. data/app/helpers/spree/checkout_helper.rb +58 -0
  44. data/app/helpers/spree/filters_helper.rb +180 -0
  45. data/app/helpers/spree/fonts_helper.rb +58 -0
  46. data/app/helpers/spree/orders_helper.rb +7 -0
  47. data/app/helpers/spree/page_helper.rb +67 -0
  48. data/app/helpers/spree/posts_helper.rb +42 -0
  49. data/app/helpers/spree/products_helper.rb +205 -0
  50. data/app/helpers/spree/storefront_helper.rb +86 -0
  51. data/app/helpers/spree/storefront_locale_helper.rb +42 -0
  52. data/app/helpers/spree/theme_helper.rb +244 -0
  53. data/app/helpers/spree/turbo_helper.rb +13 -0
  54. data/app/helpers/spree/turbo_stream_actions_helper.rb +13 -0
  55. data/app/helpers/spree/wishlist_helper.rb +7 -0
  56. data/app/javascript/spree/storefront/application.js +156 -0
  57. data/app/javascript/spree/storefront/controllers/accordion_controller.js +25 -0
  58. data/app/javascript/spree/storefront/controllers/account_nav_controller.js +10 -0
  59. data/app/javascript/spree/storefront/controllers/card_validation_controller.js +103 -0
  60. data/app/javascript/spree/storefront/controllers/carousel_controller.js +44 -0
  61. data/app/javascript/spree/storefront/controllers/cart_controller.js +10 -0
  62. data/app/javascript/spree/storefront/controllers/checkout_address_book_controller.js +28 -0
  63. data/app/javascript/spree/storefront/controllers/checkout_delivery_controller.js +39 -0
  64. data/app/javascript/spree/storefront/controllers/checkout_promotions_controller.js +28 -0
  65. data/app/javascript/spree/storefront/controllers/checkout_summary_controller.js +46 -0
  66. data/app/javascript/spree/storefront/controllers/clear_input_controller.js +23 -0
  67. data/app/javascript/spree/storefront/controllers/copy_input_controller.js +19 -0
  68. data/app/javascript/spree/storefront/controllers/dropdown_controller.js +14 -0
  69. data/app/javascript/spree/storefront/controllers/header_controller.js +33 -0
  70. data/app/javascript/spree/storefront/controllers/infinite_scroll_controller.js +31 -0
  71. data/app/javascript/spree/storefront/controllers/lightbox_controller.js +138 -0
  72. data/app/javascript/spree/storefront/controllers/mobile_nav_controller.js +17 -0
  73. data/app/javascript/spree/storefront/controllers/modal_controller.js +15 -0
  74. data/app/javascript/spree/storefront/controllers/no_ui_slider_controller.js +55 -0
  75. data/app/javascript/spree/storefront/controllers/pdp_desktop_gallery_controller.js +28 -0
  76. data/app/javascript/spree/storefront/controllers/plp_variant_picker_controller.js +151 -0
  77. data/app/javascript/spree/storefront/controllers/product_form_controller.js +136 -0
  78. data/app/javascript/spree/storefront/controllers/quantity_picker_controller.js +43 -0
  79. data/app/javascript/spree/storefront/controllers/search_suggestions_controller.js +61 -0
  80. data/app/javascript/spree/storefront/controllers/searchable_list_controller.js +25 -0
  81. data/app/javascript/spree/storefront/controllers/slideover_controller.js +40 -0
  82. data/app/javascript/spree/storefront/controllers/sticky_button_controller.js +32 -0
  83. data/app/javascript/spree/storefront/controllers/toggle_menu_controller.js +32 -0
  84. data/app/javascript/spree/storefront/controllers/turbo_stream_form_controller.js +51 -0
  85. data/app/javascript/spree/storefront/controllers/wished_item_controller.js +69 -0
  86. data/app/javascript/spree/storefront/helpers/lazy_load_controllers_with_manifest.js +78 -0
  87. data/app/javascript/spree/storefront/helpers/show_flash_message.js +25 -0
  88. data/app/models/spree/color_names.rb +35 -0
  89. data/app/models/spree/contact.rb +24 -0
  90. data/app/presenters/spree/colors_preview_styles_presenter.rb +84 -0
  91. data/app/presenters/spree/featured_product_presenter.rb +42 -0
  92. data/app/presenters/spree/mega_nav_presenter.rb +55 -0
  93. data/app/views/devise/passwords/edit.html.erb +22 -0
  94. data/app/views/devise/passwords/new.html.erb +16 -0
  95. data/app/views/devise/registrations/_form.html.erb +21 -0
  96. data/app/views/devise/registrations/edit.html.erb +24 -0
  97. data/app/views/devise/registrations/new.html.erb +27 -0
  98. data/app/views/devise/sessions/new.html.erb +25 -0
  99. data/app/views/devise/shared/_links.html.erb +22 -0
  100. data/app/views/layouts/spree/checkout.html.erb +58 -0
  101. data/app/views/layouts/spree/password.html.erb +34 -0
  102. data/app/views/layouts/spree/storefront.html.erb +38 -0
  103. data/app/views/spree/account/wished_items/create.turbo_stream.erb +8 -0
  104. data/app/views/spree/account/wished_items/destroy.turbo_stream.erb +20 -0
  105. data/app/views/spree/addresses/destroy.turbo_stream.erb +1 -0
  106. data/app/views/spree/addresses/edit.html.erb +57 -0
  107. data/app/views/spree/addresses/new.html.erb +71 -0
  108. data/app/views/spree/checkout/_address.html.erb +153 -0
  109. data/app/views/spree/checkout/_button_processing.html.erb +7 -0
  110. data/app/views/spree/checkout/_coupon_code.html.erb +55 -0
  111. data/app/views/spree/checkout/_credit_card.html.erb +12 -0
  112. data/app/views/spree/checkout/_delivery.html.erb +70 -0
  113. data/app/views/spree/checkout/_line_item.html.erb +26 -0
  114. data/app/views/spree/checkout/_line_items.html.erb +7 -0
  115. data/app/views/spree/checkout/_missing_all_line_items.html.erb +17 -0
  116. data/app/views/spree/checkout/_missing_line_items.html.erb +28 -0
  117. data/app/views/spree/checkout/_payment.html.erb +35 -0
  118. data/app/views/spree/checkout/_payment_methods.html.erb +72 -0
  119. data/app/views/spree/checkout/_payment_sources.html.erb +24 -0
  120. data/app/views/spree/checkout/_quick_checkout.html.erb +1 -0
  121. data/app/views/spree/checkout/_sidebar.html.erb +34 -0
  122. data/app/views/spree/checkout/_store_credit.html.erb +21 -0
  123. data/app/views/spree/checkout/_summary.html.erb +116 -0
  124. data/app/views/spree/checkout/_user_account.html.erb +9 -0
  125. data/app/views/spree/checkout/apply_coupon_code.turbo_stream.erb +45 -0
  126. data/app/views/spree/checkout/apply_store_credit.turbo_stream.erb +19 -0
  127. data/app/views/spree/checkout/edit.html.erb +98 -0
  128. data/app/views/spree/checkout/payment/_check.html.erb +0 -0
  129. data/app/views/spree/checkout/payment/_gateway.html.erb +74 -0
  130. data/app/views/spree/checkout/payment/_store_credit.html.erb +13 -0
  131. data/app/views/spree/checkout/remove_coupon_code.turbo_stream.erb +34 -0
  132. data/app/views/spree/checkout/remove_store_credit.turbo_stream.erb +19 -0
  133. data/app/views/spree/checkout/update.turbo_stream.erb +25 -0
  134. data/app/views/spree/home/index.html.erb +1 -0
  135. data/app/views/spree/line_items/create.turbo_stream.erb +13 -0
  136. data/app/views/spree/line_items/destroy.turbo_stream.erb +11 -0
  137. data/app/views/spree/line_items/update.turbo_stream.erb +10 -0
  138. data/app/views/spree/newsletter_subscribers/create.turbo_stream.erb +7 -0
  139. data/app/views/spree/order_status/new.html.erb +16 -0
  140. data/app/views/spree/page_sections/show.html.erb +3 -0
  141. data/app/views/spree/pages/show.html.erb +1 -0
  142. data/app/views/spree/password/show.html.erb +1 -0
  143. data/app/views/spree/posts/index.html.erb +1 -0
  144. data/app/views/spree/posts/related_products.html.erb +7 -0
  145. data/app/views/spree/posts/show.html.erb +1 -0
  146. data/app/views/spree/products/index.html.erb +1 -0
  147. data/app/views/spree/products/index.turbo_stream.erb +1 -0
  148. data/app/views/spree/products/related.html.erb +3 -0
  149. data/app/views/spree/products/show.html.erb +1 -0
  150. data/app/views/spree/search/show.html.erb +6 -0
  151. data/app/views/spree/search/show.turbo_stream.erb +1 -0
  152. data/app/views/spree/search/suggestions.turbo_stream.erb +8 -0
  153. data/app/views/spree/seo/robots.text.erb +31 -0
  154. data/app/views/spree/seo/sitemap.xml.erb +25 -0
  155. data/app/views/spree/shared/_fonts.html.erb +14 -0
  156. data/app/views/spree/shared/_head.html.erb +36 -0
  157. data/app/views/spree/shared/_load_more_products.turbo_stream.erb +7 -0
  158. data/app/views/spree/shared/_product_listing_page.html.erb +11 -0
  159. data/app/views/spree/shared/_products.html.erb +1 -0
  160. data/app/views/spree/taxonomies/show.html.erb +1 -0
  161. data/app/views/spree/taxons/show.html.erb +1 -0
  162. data/app/views/spree/taxons/show.turbo_stream.erb +1 -0
  163. data/app/views/spree/waitlists/create.turbo_stream.erb +9 -0
  164. data/app/views/themes/default/kaminari/storefront/_first_page.html.erb +8 -0
  165. data/app/views/themes/default/kaminari/storefront/_gap.html.erb +8 -0
  166. data/app/views/themes/default/kaminari/storefront/_last_page.html.erb +8 -0
  167. data/app/views/themes/default/kaminari/storefront/_next_page.html.erb +13 -0
  168. data/app/views/themes/default/kaminari/storefront/_page.html.erb +10 -0
  169. data/app/views/themes/default/kaminari/storefront/_paginator.html.erb +27 -0
  170. data/app/views/themes/default/kaminari/storefront/_prev_page.html.erb +13 -0
  171. data/app/views/themes/default/spree/account/_account_nav.html.erb +46 -0
  172. data/app/views/themes/default/spree/account/_order.html.erb +39 -0
  173. data/app/views/themes/default/spree/account/_orders.html.erb +16 -0
  174. data/app/views/themes/default/spree/account/addresses/_address.html.erb +42 -0
  175. data/app/views/themes/default/spree/account/addresses/index.html.erb +28 -0
  176. data/app/views/themes/default/spree/account/newsletter/_newsletter_settings.html.erb +13 -0
  177. data/app/views/themes/default/spree/account/newsletter/edit.html.erb +16 -0
  178. data/app/views/themes/default/spree/account/newsletter/update.html.erb +1 -0
  179. data/app/views/themes/default/spree/account/orders/index.html.erb +24 -0
  180. data/app/views/themes/default/spree/account/orders/show.html.erb +22 -0
  181. data/app/views/themes/default/spree/account/profile/edit.html.erb +36 -0
  182. data/app/views/themes/default/spree/account/store_credits/_store_credit_event.html.erb +29 -0
  183. data/app/views/themes/default/spree/account/store_credits/index.html.erb +31 -0
  184. data/app/views/themes/default/spree/checkout/_footer.html.erb +10 -0
  185. data/app/views/themes/default/spree/checkout/complete.html.erb +84 -0
  186. data/app/views/themes/default/spree/contacts/new.html.erb +23 -0
  187. data/app/views/themes/default/spree/orders/_cart.html.erb +14 -0
  188. data/app/views/themes/default/spree/orders/_empty.html.erb +11 -0
  189. data/app/views/themes/default/spree/orders/_line_item.html.erb +47 -0
  190. data/app/views/themes/default/spree/orders/_line_item_quantity.html.erb +11 -0
  191. data/app/views/themes/default/spree/orders/_summary.html.erb +41 -0
  192. data/app/views/themes/default/spree/orders/edit.html.erb +18 -0
  193. data/app/views/themes/default/spree/orders/show.html.erb +6 -0
  194. data/app/views/themes/default/spree/page_sections/_announcement_bar.html.erb +10 -0
  195. data/app/views/themes/default/spree/page_sections/_custom_code.html.erb +5 -0
  196. data/app/views/themes/default/spree/page_sections/_featured_product.html.erb +136 -0
  197. data/app/views/themes/default/spree/page_sections/_featured_taxon.html.erb +116 -0
  198. data/app/views/themes/default/spree/page_sections/_featured_taxons.html.erb +71 -0
  199. data/app/views/themes/default/spree/page_sections/_footer.html.erb +62 -0
  200. data/app/views/themes/default/spree/page_sections/_header.html.erb +166 -0
  201. data/app/views/themes/default/spree/page_sections/_image_banner.html.erb +57 -0
  202. data/app/views/themes/default/spree/page_sections/_image_with_text.html.erb +66 -0
  203. data/app/views/themes/default/spree/page_sections/_main_password_footer.html.erb +64 -0
  204. data/app/views/themes/default/spree/page_sections/_main_password_header.html.erb +54 -0
  205. data/app/views/themes/default/spree/page_sections/_newsletter.html.erb +47 -0
  206. data/app/views/themes/default/spree/page_sections/_page_title.html.erb +7 -0
  207. data/app/views/themes/default/spree/page_sections/_post_details.html.erb +19 -0
  208. data/app/views/themes/default/spree/page_sections/_post_grid.html.erb +11 -0
  209. data/app/views/themes/default/spree/page_sections/_product_details.html.erb +102 -0
  210. data/app/views/themes/default/spree/page_sections/_product_grid.html.erb +52 -0
  211. data/app/views/themes/default/spree/page_sections/_related_products.html.erb +15 -0
  212. data/app/views/themes/default/spree/page_sections/_rich_text.html.erb +18 -0
  213. data/app/views/themes/default/spree/page_sections/_taxon_banner.html.erb +37 -0
  214. data/app/views/themes/default/spree/page_sections/_taxon_grid.html.erb +103 -0
  215. data/app/views/themes/default/spree/page_sections/_video.html.erb +27 -0
  216. data/app/views/themes/default/spree/page_sections/nav/_desktop.html.erb +49 -0
  217. data/app/views/themes/default/spree/page_sections/nav/_mobile.html.erb +136 -0
  218. data/app/views/themes/default/spree/policies/show.html.erb +11 -0
  219. data/app/views/themes/default/spree/posts/_json_ld.html.erb +20 -0
  220. data/app/views/themes/default/spree/posts/_pagination.html.erb +1 -0
  221. data/app/views/themes/default/spree/posts/_post.html.erb +13 -0
  222. data/app/views/themes/default/spree/products/_add_to_cart_button.html.erb +58 -0
  223. data/app/views/themes/default/spree/products/_add_to_waitlist.html.erb +36 -0
  224. data/app/views/themes/default/spree/products/_add_to_wishlist.html.erb +33 -0
  225. data/app/views/themes/default/spree/products/_breadcrumbs.html.erb +23 -0
  226. data/app/views/themes/default/spree/products/_color_picker.html.erb +19 -0
  227. data/app/views/themes/default/spree/products/_color_swatches.html.erb +61 -0
  228. data/app/views/themes/default/spree/products/_details.html.erb +55 -0
  229. data/app/views/themes/default/spree/products/_featured_image.html.erb +37 -0
  230. data/app/views/themes/default/spree/products/_filters.html.erb +45 -0
  231. data/app/views/themes/default/spree/products/_json_ld.html.erb +38 -0
  232. data/app/views/themes/default/spree/products/_json_ld_list.html.erb +9 -0
  233. data/app/views/themes/default/spree/products/_json_ld_variant.html.erb +10 -0
  234. data/app/views/themes/default/spree/products/_label.html.erb +26 -0
  235. data/app/views/themes/default/spree/products/_media_gallery.html.erb +94 -0
  236. data/app/views/themes/default/spree/products/_price.html.erb +59 -0
  237. data/app/views/themes/default/spree/products/_product.html.erb +62 -0
  238. data/app/views/themes/default/spree/products/_quantity_selector.html.erb +32 -0
  239. data/app/views/themes/default/spree/products/_returns_policy_modal.html.erb +22 -0
  240. data/app/views/themes/default/spree/products/_show_more_button.html.erb +8 -0
  241. data/app/views/themes/default/spree/products/_sort.html.erb +45 -0
  242. data/app/views/themes/default/spree/products/_swiper.html.erb +85 -0
  243. data/app/views/themes/default/spree/products/_tags.html.erb +0 -0
  244. data/app/views/themes/default/spree/products/_variant_options.html.erb +71 -0
  245. data/app/views/themes/default/spree/products/_variant_picker.html.erb +50 -0
  246. data/app/views/themes/default/spree/products/filters/_availability.html.erb +32 -0
  247. data/app/views/themes/default/spree/products/filters/_colors.html.erb +23 -0
  248. data/app/views/themes/default/spree/products/filters/_generic.html.erb +75 -0
  249. data/app/views/themes/default/spree/products/filters/_price.html.erb +35 -0
  250. data/app/views/themes/default/spree/products/filters/_taxons.erb +78 -0
  251. data/app/views/themes/default/spree/search/_suggestions.html.erb +92 -0
  252. data/app/views/themes/default/spree/settings/show.html.erb +32 -0
  253. data/app/views/themes/default/spree/shared/_account_pane.html.erb +28 -0
  254. data/app/views/themes/default/spree/shared/_address.html.erb +35 -0
  255. data/app/views/themes/default/spree/shared/_cart_icon.html.erb +13 -0
  256. data/app/views/themes/default/spree/shared/_cart_pane.html.erb +38 -0
  257. data/app/views/themes/default/spree/shared/_css_variables.html.erb +54 -0
  258. data/app/views/themes/default/spree/shared/_custom_head.html.erb +0 -0
  259. data/app/views/themes/default/spree/shared/_error_messages.html.erb +9 -0
  260. data/app/views/themes/default/spree/shared/_error_messages_without_base_attribute.html.erb +15 -0
  261. data/app/views/themes/default/spree/shared/_flash.html.erb +16 -0
  262. data/app/views/themes/default/spree/shared/_flashes.html.erb +10 -0
  263. data/app/views/themes/default/spree/shared/_json_ld.html.erb +32 -0
  264. data/app/views/themes/default/spree/shared/_line_item_options.html.erb +18 -0
  265. data/app/views/themes/default/spree/shared/_logo.html.erb +42 -0
  266. data/app/views/themes/default/spree/shared/_meta_tags.html.erb +45 -0
  267. data/app/views/themes/default/spree/shared/_order_details.html.erb +106 -0
  268. data/app/views/themes/default/spree/shared/_order_line_item.html.erb +65 -0
  269. data/app/views/themes/default/spree/shared/_order_shipment.html.erb +71 -0
  270. data/app/views/themes/default/spree/shared/_search.html.erb +32 -0
  271. data/app/views/themes/default/spree/shared/_title.html.erb +3 -0
  272. data/app/views/themes/default/spree/shared/_wishlist_icon.html.erb +13 -0
  273. data/app/views/themes/default/spree/shared/icons/_account.html.erb +17 -0
  274. data/app/views/themes/default/spree/shared/icons/_arrow-left.html.erb +8 -0
  275. data/app/views/themes/default/spree/shared/icons/_arrow-right.html.erb +3 -0
  276. data/app/views/themes/default/spree/shared/icons/_bell.html.erb +9 -0
  277. data/app/views/themes/default/spree/shared/icons/_cart.html.erb +10 -0
  278. data/app/views/themes/default/spree/shared/icons/_cart_48.html.erb +6 -0
  279. data/app/views/themes/default/spree/shared/icons/_check.html.erb +4 -0
  280. data/app/views/themes/default/spree/shared/icons/_chevron.html.erb +15 -0
  281. data/app/views/themes/default/spree/shared/icons/_chevron_down.html.erb +5 -0
  282. data/app/views/themes/default/spree/shared/icons/_chevron_right.html.erb +15 -0
  283. data/app/views/themes/default/spree/shared/icons/_chevron_up.html.erb +3 -0
  284. data/app/views/themes/default/spree/shared/icons/_close.html.erb +9 -0
  285. data/app/views/themes/default/spree/shared/icons/_cross.html.erb +16 -0
  286. data/app/views/themes/default/spree/shared/icons/_delete.html.erb +3 -0
  287. data/app/views/themes/default/spree/shared/icons/_delivery.html.erb +5 -0
  288. data/app/views/themes/default/spree/shared/icons/_disabled.html.erb +13 -0
  289. data/app/views/themes/default/spree/shared/icons/_edit.html.erb +3 -0
  290. data/app/views/themes/default/spree/shared/icons/_facebook.html.erb +16 -0
  291. data/app/views/themes/default/spree/shared/icons/_filter.html.erb +8 -0
  292. data/app/views/themes/default/spree/shared/icons/_heart.html.erb +12 -0
  293. data/app/views/themes/default/spree/shared/icons/_info.html.erb +7 -0
  294. data/app/views/themes/default/spree/shared/icons/_instagram.html.erb +18 -0
  295. data/app/views/themes/default/spree/shared/icons/_lock.html.erb +13 -0
  296. data/app/views/themes/default/spree/shared/icons/_menu.html.erb +10 -0
  297. data/app/views/themes/default/spree/shared/icons/_minus.html.erb +5 -0
  298. data/app/views/themes/default/spree/shared/icons/_pinch.html.erb +6 -0
  299. data/app/views/themes/default/spree/shared/icons/_pinterest.html.erb +8 -0
  300. data/app/views/themes/default/spree/shared/icons/_plus.html.erb +17 -0
  301. data/app/views/themes/default/spree/shared/icons/_return.html.erb +11 -0
  302. data/app/views/themes/default/spree/shared/icons/_search.html.erb +17 -0
  303. data/app/views/themes/default/spree/shared/icons/_spinner.html.erb +1 -0
  304. data/app/views/themes/default/spree/shared/icons/_spotify.html.erb +8 -0
  305. data/app/views/themes/default/spree/shared/icons/_tiktok.html.erb +9 -0
  306. data/app/views/themes/default/spree/shared/icons/_twitter.html.erb +16 -0
  307. data/app/views/themes/default/spree/shared/icons/_youtube.html.erb +9 -0
  308. data/app/views/themes/default/spree/shared/icons/_zoom.html.erb +10 -0
  309. data/app/views/themes/default/spree/wishlists/_no_wished_items.html.erb +10 -0
  310. data/app/views/themes/default/spree/wishlists/_wished_item.html.erb +38 -0
  311. data/app/views/themes/default/spree/wishlists/show.html.erb +17 -0
  312. data/config/i18n-tasks.yml +176 -0
  313. data/config/importmap.rb +22 -0
  314. data/config/initializers/assets.rb +1 -0
  315. data/config/initializers/heroicon.rb +10 -0
  316. data/config/locales/en.yml +76 -0
  317. data/config/routes.rb +88 -0
  318. data/lib/generators/spree/storefront/install/install_generator.rb +45 -0
  319. data/lib/generators/spree/storefront/install/templates/application.tailwind.css +1760 -0
  320. data/lib/generators/spree/storefront/install/templates/dev +16 -0
  321. data/lib/generators/spree/storefront/install/templates/tailwind.config.js +128 -0
  322. data/lib/generators/spree/storefront/theme/templates/model.rb.tt +12 -0
  323. data/lib/generators/spree/storefront/theme/theme_generator.rb +41 -0
  324. data/lib/spree/storefront/configuration.rb +11 -0
  325. data/lib/spree/storefront/engine.rb +51 -0
  326. data/lib/spree/storefront/testing_support/capybara_utils.rb +13 -0
  327. data/lib/spree/storefront.rb +16 -0
  328. data/lib/spree_storefront.rb +1 -0
  329. data/vendor/colornames.json +1 -0
  330. data/vendor/javascript/@kanety--stimulus-accordion.js +4 -0
  331. data/vendor/javascript/@stimulus-components--carousel.js +4 -0
  332. data/vendor/javascript/card-validator.js +4 -0
  333. data/vendor/javascript/credit-card-type.js +4 -0
  334. data/vendor/javascript/headroom.js.js +19 -0
  335. data/vendor/javascript/nouislider.js +4 -0
  336. data/vendor/javascript/photoswipe--dist--photoswipe-lightbox.esm.js.js +667 -0
  337. data/vendor/javascript/photoswipe.js +1675 -0
  338. data/vendor/javascript/stimulus-read-more.js +4 -0
  339. data/vendor/javascript/stimulus-scroll-to.js +4 -0
  340. data/vendor/javascript/swiper--bundle.js +4 -0
  341. metadata +567 -0
@@ -0,0 +1,84 @@
1
+ <div id="<%= dom_id(@order) %>" class="text-muted">
2
+ <p class="text-sm mb-1 mt-3">
3
+ <%= Spree.t(:order) %> <strong><%= @order.number %></strong>
4
+ </p>
5
+ <h4 class="mb-4 text-green-600 font-semibold text-lg font-body">
6
+ <%= Spree.t('storefront.checkout.thanks_for_your_order', name: @order.bill_address_firstname) %>
7
+ </h4>
8
+
9
+ <div class="border p-3 rounded-md">
10
+ <h5 class="mb-3 font-semibold pb-3 border-b font-body">
11
+ <%= Spree.t("storefront.checkout.order_success") %>
12
+ </h5>
13
+ <p class="mb-0">
14
+ <%= Spree.t('storefront.checkout.order_success_message') %>
15
+ </p>
16
+ </div>
17
+
18
+ <% if @order.payments.valid.any? %>
19
+ <div class="border p-3 mt-4 rounded-md">
20
+ <h5 class="mb-3 font-bold pb-3 border-b font-body"><%= Spree.t(:payment) %></h5>
21
+ <div class="flex mb-3 text-sm gap-4 items-top">
22
+ <%= render partial: 'spree/shared/payment', collection: @order.payments.valid %>
23
+ </div>
24
+ <div class="mt-3 border-t pt-3">
25
+ <span class="text-sm"><%= Spree.t(:status) %></span>
26
+ <% if @order.payment_state.present? %>
27
+ <span class="badge-<%= @order.payment_state %>"><%= Spree.t("payment_states.#{@order.payment_state}").titleize %></span>
28
+ <% else %>
29
+ <span class="badge-pending"><%= Spree.t(:pending) %></span>
30
+ <% end %>
31
+ </div>
32
+
33
+ <% unless @order.payment_state.present? %>
34
+ <p class="mb-0 mt-3 text-sm"><%= Spree.t('storefront.checkout.payment_processing_message') %></p>
35
+ <% end %>
36
+ </div>
37
+ <% end %>
38
+
39
+ <div class="border p-3 rounded-md mt-4">
40
+ <h5 class="mb-3 font-bold pb-3 border-b font-body"><%= Spree.t(:contact_information) %></h5>
41
+ <p class="mb-4"><%= @order.email %></p>
42
+
43
+ <div class="flex w-full">
44
+ <% if @order.ship_address.present? %>
45
+ <div class="w-1/2">
46
+ <h6 class="mb-3 font-bold pb-2 border-b font-body"><%= Spree.t(:shipping_address) %></h6>
47
+ <p class="mb-1 word-break"><%= @order.ship_address.to_s.html_safe %></p>
48
+ <p class="mb-0"><%= @order.ship_address.phone %></p>
49
+ </div>
50
+ <% end %>
51
+ <% if @order.bill_address.present? %>
52
+ <div class="w-1/2">
53
+ <h6 class="mb-3 font-bold pb-2 border-b font-body"><%= Spree.t(:billing_address) %></h6>
54
+ <p class="mb-1 word-break"><%= @order.bill_address.to_s.html_safe %></p>
55
+ <p class="mb-0"><%= @order.bill_address.phone %></p>
56
+ </div>
57
+ <% end %>
58
+ </div>
59
+ </div>
60
+
61
+ <% if @order.digital_links.any? %>
62
+ <div class="border p-3 rounded-md mt-4">
63
+ <h5 class="mb-3 font-bold pb-3 border-b font-body"><%= Spree.t(:attachments) %></h5>
64
+
65
+ <ul class="flex flex-col gap-2">
66
+ <% @order.digital_line_items.each do |line_item| %>
67
+ <li class="flex flex-col gap-1">
68
+ <span class="font-bold"><%= line_item.product.name %></span>
69
+ <ul class="flex flex-col gap-1">
70
+ <% line_item.digital_links.each do |digital_link| %>
71
+ <li>
72
+ <%= link_to "#{Spree.t(:download)} #{digital_link.filename}",
73
+ spree.digital_link_path(digital_link.token) %>
74
+ </li>
75
+ <% end %>
76
+ </ul>
77
+ </li>
78
+ <% end %>
79
+ </ul>
80
+ </div>
81
+ <% end %>
82
+ </div>
83
+
84
+ <%= render_storefront_partials(:checkout_complete_partials) if order_just_completed? %>
@@ -0,0 +1,23 @@
1
+ <div class="page-container">
2
+ <div class="card-dialog mx-auto lg:w-1/3 pt-5">
3
+ <h3 class="mb-5 font-semibold"><%= Spree.t(:contact_us) %></h3>
4
+ <%= form_for @contact, data: { controller: 'recaptcha-form', recaptcha_form_action_value: 'contacts/create' } do |f| %>
5
+ <div class="mb-5">
6
+ <p>
7
+ <%= f.text_field :name, required: true, class: "text-input w-full", placeholder: Spree.t(:name) %>
8
+ </p>
9
+ </div>
10
+ <div class="mb-5">
11
+ <p>
12
+ <%= f.email_field :email, required: true, class: "text-input w-full", placeholder: Spree.t(:email) %>
13
+ </p>
14
+ </div>
15
+ <div class="mb-5">
16
+ <p>
17
+ <%= f.text_area :message, rows: 8, cols: 40, required: true, class: "text-input w-full", placeholder: Spree.t(:send_us_a_message), style: 'min-height: 8rem' %>
18
+ </p>
19
+ </div>
20
+ <%= f.submit Spree.t(:send_message), class: 'btn btn-primary' %>
21
+ <% end %>
22
+ </div>
23
+ </div>
@@ -0,0 +1,14 @@
1
+ <div data-controller="cart" class="h-full">
2
+ <div class="h-full flex flex-col" id="cart-container" data-cart-target="container">
3
+ <%== color_options_style_for_line_items(@line_items) %>
4
+ <ul class="w-full" id="line-items">
5
+ <%= render collection: @line_items, partial: 'spree/orders/line_item', cached: spree_base_cache_scope %>
6
+ </ul>
7
+ <%= render 'spree/orders/summary', order: @order %>
8
+ </div>
9
+ <div class="hidden absolute w-full flex justify-center" style="top: 40%;left: 0" data-cart-target="spinner">
10
+ <span class="group-aria-[busy]:inline-flex gap-2 items-center">
11
+ <span class="w-10 h-10 border-dotted border-[3px] inline-block rounded-full animate-[spin_2s_linear_infinite] border-current"></span>
12
+ </span>
13
+ </div>
14
+ </div>
@@ -0,0 +1,11 @@
1
+ <div class="flex flex-col justify-between h-full">
2
+ <div class="h-full flex flex-col items-center place-content-center py-10">
3
+ <%= render 'spree/shared/icons/cart_48' %>
4
+ <p class="mb-8 mt-4 uppercase text-sm">
5
+ <%= Spree.t('cart_page.empty_info').html_safe %>
6
+ </p>
7
+ <div class="mx-10">
8
+ <%= link_to Spree.t(:continue_shopping), spree.products_path, class: 'btn-primary !no-underline', data: { 'turbo-frame': '_top' } %>
9
+ </div>
10
+ </div>
11
+ </div>
@@ -0,0 +1,47 @@
1
+ <%= turbo_frame_tag dom_id(line_item), data: { controller: 'reveal' } do %>
2
+ <li class="cart-line-item flex items-top py-6 px-4 w-full" data-reveal-target="item">
3
+ <div class="line-item-overlay"></div>
4
+ <div class="cart-product-image flex-shrink-0" id="<%= dom_id(line_item) %>-image" data-turbo-permanent>
5
+ <% image = line_item.variant.default_image %>
6
+ <% if image.present? && image.attached? && image.variable? %>
7
+ <%= link_to spree_storefront_resource_url(line_item.product), data: { 'turbo-frame': '_top' } do %>
8
+ <%= image_tag main_app.cdn_image_url(image.variant(spree_image_variant_options(resize_to_fit: [256, 256]))), width: 128, height: 128, class: 'object-cover', loading: :lazy %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+ <div class="ml-3 w-full">
13
+ <div class="flex justify-between">
14
+ <%= link_to line_item.name, spree_storefront_resource_url(line_item.product), class: 'font-semibold text-text', data: { 'turbo-frame': '_top' } %>
15
+
16
+ <%= form_for line_item, url: spree.line_item_url(line_item, order_token: line_item.order.token), method: :delete, data: { controller: 'turbo-stream-form' } do |item_form| %>
17
+ <%= button_tag type: :submit, class: 'remove-line-item-button h-100', data: { action: "click->reveal#hide click->cart#disableCart" } do %>
18
+ <%= render 'spree/shared/icons/cross', size: 16 %>
19
+ <% end %>
20
+ <% end %>
21
+ </div>
22
+ <div class="mb-2 text-sm">
23
+ <% if line_item.variant.on_sale?(current_currency) %>
24
+ <span class="">
25
+ <del><%= line_item.variant.display_compare_at_price %></del>
26
+ </span>
27
+ <span class="text-danger">
28
+ <%= line_item.display_price %>
29
+ </span>
30
+ <% else %>
31
+ <span><%= line_item.display_price %></span>
32
+ <% end %>
33
+ </div>
34
+ <div class="flex flex-wrap gap-2">
35
+ <%= render 'spree/shared/line_item_options', line_item: line_item %>
36
+ </div>
37
+ <div class="flex flex-row-reverse w-full mt-3">
38
+ <%= render 'spree/orders/line_item_quantity', line_item: line_item %>
39
+ </div>
40
+ <% if !line_item.variant.backorderable? && line_item.variant.total_on_hand < 5 %>
41
+ <div class="text-sm -mt-5 text-center text-danger" style="width: 117px">
42
+ <%= Spree.t(:only_left, count: line_item.variant.total_on_hand) %>
43
+ </div>
44
+ <% end %>
45
+ </div>
46
+ </li>
47
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <div class="flex items-center">
2
+ <%= form_for line_item, url: spree.line_item_url(line_item, order_token: line_item.order.token), data: { controller: 'turbo-stream-form' } do |item_form| %>
3
+ <div class="quantity-picker" data-controller="quantity-picker">
4
+ <!-- this is a dummy button to work with turbo frame forms when hitting ENTER -->
5
+ <%= button_tag render('spree/shared/icons/minus'), type: 'submit', class: 'hidden' %>
6
+ <%= quantity_modifier_button_tag render('spree/shared/icons/minus'), type: 'submit', action: 'decrease', class: 'quantity-decrease-button' %>
7
+ <%= item_form.number_field(:quantity, quantity_field_options(max: line_item.maximum_quantity)) %>
8
+ <%= quantity_modifier_button_tag render('spree/shared/icons/plus'), type: 'submit', action: 'increase', class: 'quantity-increase-button' %>
9
+ </div>
10
+ <% end %>
11
+ </div>
@@ -0,0 +1,41 @@
1
+ <%= turbo_frame_tag :cart_summary do %>
2
+ <% if order.line_items.any? %>
3
+ <div class="cart-summary-container p-4">
4
+ <p class="text-center lg:text-right text-sm mb-3">
5
+ <%= Spree.t('storefront.cart.shipping_and_taxes_calculated_at_checkout') %>
6
+ </p>
7
+
8
+ <div class="shopping-cart-total-text text-center lg:text-right uppercase font-medium">
9
+ <%= Spree.t(:total) %>
10
+ <span class="shopping-cart-total-amount">
11
+ <%= order.display_item_total %>
12
+ </span>
13
+ </div>
14
+
15
+ <% unless order.cart_promo_total.zero? %>
16
+ <div class="shopping-cart-total-text mt-3 text-center lg:text-right uppercase font-medium">
17
+ <%= Spree.t(:promotion) %>
18
+ <span class="shopping-cart-total-amount">
19
+ <%= order.display_cart_promo_total %>
20
+ </span>
21
+ </div>
22
+ <% end %>
23
+ <div class="flex <%= !turbo_frame_request? && !turbo_stream_request? ? 'flex-row' : 'flex-col' %> gap-4 mt-4 w-full justify-end items-end">
24
+ <% if quick_checkout_enabled?(@order) %>
25
+ <div class="min-h-[46px] w-full has-[turbo-frame]:block group no-separator">
26
+ <% if !turbo_frame_request? && !turbo_stream_request? %>
27
+ <%= render partial: 'spree/checkout/quick_checkout', locals: { height: 46, theme: 'black', button_width: 320, container_class: "w-full flex justify-end" } %>
28
+ <% else %>
29
+ <%= render partial: 'spree/checkout/quick_checkout', locals: { height: 46, theme: 'white', max_columns: 2, max_rows: 2 } %>
30
+ <% end %>
31
+ </div>
32
+ <% end %>
33
+ <div class="flex flex-col gap-4 <%= 'w-full' if turbo_frame_request? || turbo_stream_request? %>">
34
+ <%= link_to Spree.t(:checkout), spree.checkout_path(order.token),
35
+ class: 'btn-primary block w-full lg:w-80 text-center !no-underline !mt-0',
36
+ data: { 'turbo': 'false', 'cart-target': 'checkoutButton' } %>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <% end %>
41
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <% if !turbo_frame_request? && !turbo_stream_request? %>
2
+ <div class="page-container">
3
+ <%= render 'spree/shared/title' %>
4
+ <% end %>
5
+
6
+ <%= render 'spree/shared/error_messages', target: @order %>
7
+
8
+ <%= turbo_frame_tag :cart_contents, class: 'cart-contents' do %>
9
+ <% if !@line_items || @line_items.empty? %>
10
+ <%= render 'spree/orders/empty' %>
11
+ <% else %>
12
+ <%= render 'spree/orders/cart' %>
13
+ <% end %>
14
+ <% end %>
15
+
16
+ <% if !turbo_frame_request? && !turbo_stream_request? %>
17
+ </div>
18
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <div class="page-container">
2
+ <h1 class="text-2xl uppercase font-medium tracking-tight py-5 text-center lg:text-left mt-5">
3
+ <%= accurate_title %>
4
+ </h1>
5
+ <%= render 'spree/shared/order_details', order: @order, shipments: @shipments %>
6
+ </div>
@@ -0,0 +1,10 @@
1
+ <% cache_unless page_builder_enabled?, spree_base_cache_scope.call(section) do %>
2
+ <% if section.present? && section.text.body.to_plain_text.present? %>
3
+ <div
4
+ class='w-full justify-center items-center flex announcement-bar'
5
+ style='<%= section_styles(section) %>'
6
+ >
7
+ <div class='text-sm tracking-widest'><%= section.text.body %></div>
8
+ </div>
9
+ <% end %>
10
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% cache_unless page_builder_enabled?, spree_base_cache_scope.call(section) do %>
2
+ <div style="<%= section_styles(section) %>">
3
+ <%= raw(section.preferred_custom_code) %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,136 @@
1
+ <% view_full_details_rendered = false %>
2
+ <%= turbo_frame_tag "section-#{section.id}" do %>
3
+ <% options_param_name = "featured-product-#{section.id}-options" %>
4
+ <% presenter = Spree::FeaturedProductPresenter.new(section, params: params[options_param_name], currency: current_currency) %>
5
+ <% images = presenter.product.present? ? product_media_gallery_images(presenter.product, selected_variant: presenter.selected_variant, variant_from_options: presenter.variant_from_options, options_param_name: options_param_name) : [] %>
6
+ <% current_variant = presenter.selected_variant || presenter.variant_from_options || presenter.product&.first_or_default_variant(current_currency) %>
7
+ <% @selected_variant = presenter.selected_variant %>
8
+ <% @variant_from_options = presenter.variant_from_options %>
9
+ <div style="<%= section_styles(section) %>">
10
+ <div
11
+ class="page-container py-5"
12
+ data-controller="product-form"
13
+ data-product-form-no-cache-value="true"
14
+ data-product-form-url-value="<%= spree.page_section_url(section.id, host: current_store.url) %>"
15
+ data-product-form-frame-name-value="section-<%= section.id %>"
16
+ data-product-form-options-param-name-value="<%= options_param_name %>"
17
+ data-product-form-required-options-value='<%= presenter.product&.option_type_ids&.map(&:to_s)&.to_json %>'
18
+ data-product-form-variant-from-options-disabled-value='<%= !presenter.variant_from_options&.in_stock? %>'
19
+ >
20
+ <% if presenter.product %>
21
+ <div class="lg:hidden -ml-4 -mr-4">
22
+ <%= render 'spree/products/media_gallery', images: images, product: presenter.product %>
23
+ </div>
24
+ <% end %>
25
+ <div id="product-details-page" class="grid-cols-1 lg:grid-cols-12 gap-x-14 <%= presenter.product ? 'grid' : 'flex justify-center w-full' %>">
26
+ <% if presenter.product %>
27
+ <div class="lg:col-span-7 relative">
28
+ <!-- media gallery for desktop -->
29
+ <div class="hidden lg:block">
30
+ <%= render 'spree/products/media_gallery', images: images, product: presenter.product, desktop: true %>
31
+ </div>
32
+ </div>
33
+ <% end %>
34
+ <div class="lg:col-span-5 lg:col-start-8">
35
+ <% show_waitlist_modal = spree.respond_to?(:waitlists_path) && current_variant.present? %>
36
+ <div
37
+ <% if show_waitlist_modal %>
38
+ data-controller="modal"
39
+ <% end %>
40
+ data-modal-allow-background-close="true"
41
+ class="h-full w-full waitlist-modal"
42
+ data-modal-backdrop-color-value="rgba(0,0,0,0.32)">
43
+ <%= form_with url: spree.line_items_path, method: :post, data: { controller: 'sticky-button', 'product-form-target': 'form' } do %>
44
+ <% if presenter.product %>
45
+ <div class='pt-[4.25rem] lg:pt-0'></div>
46
+ <% section.blocks.each do |block| %>
47
+ <div <%= block_attributes(block) %>>
48
+ <% case block.type %>
49
+ <% when 'Spree::PageBlocks::Products::Brand' %>
50
+ <% if presenter.product&.brand&.page_builder_url %>
51
+ <%= link_to spree_storefront_resource_url(presenter.product&.brand), title: strip_tags(presenter.product&.brand&.name).strip, data: { turbo_frame: '_top' } do %>
52
+ <h3 class="text-sm uppercase font-semibold">
53
+ <%= presenter.product&.brand&.name %>
54
+ </h3>
55
+ <% end %>
56
+ <% else %>
57
+ <h3 class="text-sm uppercase font-semibold">
58
+ <%= presenter.product&.brand&.name %>
59
+ </h3>
60
+ <% end %>
61
+ <% when 'Spree::PageBlocks::Products::Title' %>
62
+ <h2 class="tracking-tight <%= block.preferred_size == 'small' ? 'text-base lg:text-xl' : block.preferred_size == 'medium' ? 'text-xl lg:text-2xl' : 'text-2xl lg:text-2xl' %> uppercase font-medium">
63
+ <%= presenter.product ? presenter.product.name : 'Example product' %>
64
+ </h2>
65
+ <% when 'Spree::PageBlocks::Products::Price' %>
66
+ <%=
67
+ render 'spree/products/price',
68
+ product: presenter.product,
69
+ use_variant: true,
70
+ selected_variant: presenter.selected_variant,
71
+ price_class: "lg:text-lg lg:font-medium"
72
+ %>
73
+ <% when 'Spree::PageBlocks::Products::QuantitySelector' %>
74
+ <%= render 'spree/products/quantity_selector', product: presenter.product, selected_variant: presenter.selected_variant %>
75
+ <% when 'Spree::PageBlocks::Products::BuyButtons' %>
76
+ <div class="flex w-full my-5">
77
+ <%= render 'spree/products/add_to_cart_button', product: presenter.product, selected_variant: presenter.selected_variant, sticky_button_classes: "w-full", without_fixed_button: true, options_param_name: options_param_name %>
78
+ <%= render 'spree/products/add_to_wishlist', variant: current_variant, css_classes: 'btn-secondary ml-5 h-12 !py-0 !px-3 border-default', icon_size: 24 %>
79
+ </div>
80
+ <% when 'Spree::PageBlocks::Products::Share' %>
81
+ <div class="flex justify-between">
82
+ <details>
83
+ <summary class="inline-flex space-x-2 group cursor-pointer">
84
+ <%= heroicon 'arrow-up-tray'%>
85
+ <div class="group-hover:underline">
86
+ <%= block.text %>
87
+ </div>
88
+ </summary>
89
+ <% if presenter.product %>
90
+ <div class="absolute flex" data-controller="copy-input">
91
+ <div class="has-float-label flex flex-col max-w-[200px]">
92
+ <%= text_field_tag "product-#{presenter.product.id}-share-link", spree.product_url(presenter.product, host: current_store.url), class: 'text-ellipsis text-input border-r-0 !rounded-r-none !rounded-l-md', readonly: true, type: 'text', onclick: 'this.select()', data: { copy_input_target: 'input' } %>
93
+ <%= label_tag "product-#{presenter.product.id}-share-link", Spree.t(:link) %>
94
+ </div>
95
+ <button
96
+ class="bg-input-bg block border-t-2 border-r-2 border-b-2 rounded-r-md pr-3"
97
+ data-copy-input-target="copyButton"
98
+ type="button">
99
+ <%= heroicon 'clipboard', variant: :outline %>
100
+ <span class="sr-only"><%= Spree.t(:copy_link) %></span>
101
+ </button>
102
+ </div>
103
+ <% end %>
104
+ </details>
105
+ <% if block == section.blocks.last %>
106
+ <% view_full_details_rendered = true %>
107
+ <%= link_to spree_storefront_resource_url(presenter.product) || '#', class: class_names('hover:underline flex space-x-2 group', {'cursor-not-allowed' => presenter.product.nil?}), data: { turbo: 'false' }, aria: { disabled: presenter.product.nil? } do %>
108
+ <span>
109
+ <%= Spree.t(:view_full_details) %>
110
+ </span>
111
+ <%= heroicon 'arrow-long-right' %>
112
+ <% end %>
113
+ <% end %>
114
+ </div>
115
+ <% when 'Spree::PageBlocks::Products::VariantPicker' %>
116
+ <%= render 'spree/products/variant_picker', product: presenter.product, selected_variant: presenter.selected_variant, options_param_name: options_param_name %>
117
+ <% end %>
118
+ </div>
119
+ <% end %>
120
+ <% end %>
121
+ <% unless view_full_details_rendered %>
122
+ <%= link_to spree_storefront_resource_url(presenter.product) || '#', class: class_names('hover:underline flex space-x-2 group', {'cursor-not-allowed' => presenter.product.nil?}), data: { turbo: 'false' }, aria: { disabled: presenter.product.nil? } do %>
123
+ <span>
124
+ <%= Spree.t(:view_full_details) %>
125
+ </span>
126
+ <%= heroicon 'arrow-long-right' %>
127
+ <% end %>
128
+ <% end %>
129
+ <% end %>
130
+ <%= render('spree/products/add_to_waitlist', variant: current_variant) if show_waitlist_modal %>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </div>
136
+ <% end %>
@@ -0,0 +1,116 @@
1
+ <div style='<%= section_styles(section) %>' class='animate-fadeIn'>
2
+ <div class='page-container'>
3
+ <% heading_size = case section.preferred_heading_size
4
+ when 'small' then 'text-base font-medium'
5
+ when 'medium' then 'text-lg lg:text-xl font-medium'
6
+ when 'large' then 'text-xl lg:text-2xl font-medium'
7
+ end %>
8
+ <% if section.taxon&.image&.attached? && section.preferred_show_taxon_image %>
9
+ <% desktop_slides_amount = 2.5 %>
10
+ <% section_with_image = true %>
11
+ <% arrows_on_top = false %>
12
+ <% else %>
13
+ <% desktop_slides_amount = 4 %>
14
+ <% section_with_image = false %>
15
+ <% arrows_on_top = true %>
16
+ <% end %>
17
+ <% if section.preferred_heading.present? %>
18
+ <div class='mb-8 flex justify-between items-end'>
19
+ <div class="md:basis-2/5">
20
+ <h3
21
+ class='<%= heading_size %> featured-taxon--title font-medium text-<%= section.preferred_heading_alignment %>'
22
+ data-title="<%= section.preferred_heading.downcase %>"
23
+ style='<%= section_heading_styles(section) %>'>
24
+ <% if section.taxon.present? %>
25
+ <%= link_to section.preferred_heading, spree_storefront_resource_url(section.taxon), data: { turbo_frame: "_top" } %>
26
+ <% else %>
27
+ <%= section.preferred_heading %>
28
+ <% end %>
29
+ </h3>
30
+
31
+ <% if section.description_to_use.present? %>
32
+ <div class='pt-4 text-<%= section.preferred_description_alignment %>'>
33
+ <%= section.description_to_use %>
34
+ </div>
35
+ <% end %>
36
+ </div>
37
+ <% if section.taxon.present? %>
38
+ <%= link_to spree_storefront_resource_url(section.taxon), class: class_names(section.preferred_button_style == "primary" ? "btn-primary" : "btn-secondary", " text-center hidden md:inline-block"), data: { turbo_frame: '_top' } do %>
39
+ <%= section.preferred_button_text %>
40
+ <% end %>
41
+ <% end %>
42
+ </div>
43
+ <% end %>
44
+ <% if loaded && section.taxon.present? %>
45
+ <% if section.products(current_currency).any? %>
46
+ <div class='grid grid-cols-1 lg:grid-cols-12 gap-4 lg:gap-6'>
47
+ <% if section_with_image %>
48
+ <div class='lg:col-span-5'>
49
+ <%= link_to spree.nested_taxons_path(section.taxon), data: { turbo_frame: "_top" } do %>
50
+ <%= image_tag main_app.cdn_image_url(section.taxon.image.variant(spree_image_variant_options(resize_to_fill: [1000, 1000]))), height: 500, width: 500, class: 'h-full w-full object-cover object-center', loading: :lazy %>
51
+ <% end %>
52
+ </div>
53
+ <% end %>
54
+ <div class='<%= section_with_image ? "lg:col-span-7" : "lg:col-span-12" %>'>
55
+ <%= render 'spree/products/swiper', products: section.products(current_currency).first(section.preferred_max_products_to_show), desktop_slides: desktop_slides_amount, pagination: 'bottom', arrows_on_top: arrows_on_top, section: section %>
56
+ </div>
57
+ </div>
58
+ <% end %>
59
+ <% else %>
60
+ <div class='grid grid-cols-1 md:grid-cols-12 gap-4 md:gap-6'>
61
+ <% if section_with_image %>
62
+ <div class='md:col-span-5 w-full aspect-1 md:h-[536px] bg-accent'></div>
63
+ <% end %>
64
+ <div class='<%= section_with_image ? "md:col-span-7" : "md:col-span-12" %> flex justify-between flex-col overflow-hidden'>
65
+ <% if section_with_image %>
66
+ <div class='grid gap-4 md:gap-6 grid-cols-8 md:grid-cols-5'>
67
+ <div class='col-span-6 md:col-span-2'>
68
+ <div class='aspect-1 bg-accent w-full'></div>
69
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
70
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
71
+ </div>
72
+ <div class='col-span-2 flex flex-col h-full overflow-hidden'>
73
+ <div class='h-full md:aspect-1 bg-accent w-full'></div>
74
+ <div class='h-6 mt-2 w-32 bg-accent rounded shrink-0'></div>
75
+ <div class='h-8 mt-2 w-16 bg-accent rounded shrink-0'></div>
76
+ </div>
77
+ <div class='hidden md:block'>
78
+ <div class='aspect-[1/2] bg-accent w-full'></div>
79
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
80
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
81
+ </div>
82
+ </div>
83
+ <div class='md:flex <%= section.preferred_show_more_button ? "justify-between" : "justify-end" %> items-end'>
84
+ <div class='bg-accent h-12 rounded-full w-full md:w-56 mt-8 md:order-1 hidden md:block'></div>
85
+ <div class='<%= section.preferred_show_more_button ? "" : "hidden" %> bg-accent h-12 rounded-button w-full md:w-72 mt-6'></div>
86
+ </div>
87
+ <% else %>
88
+ <div class='grid gap-4 md:gap-6 grid-cols-8 relative'>
89
+ <div class='col-span-6 md:col-span-2'>
90
+ <div class='aspect-1 bg-accent w-full'></div>
91
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
92
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
93
+ </div>
94
+ <div class='col-span-2 md:col-span-2 flex flex-col'>
95
+ <div class='aspect-[1/3] md:aspect-1 bg-accent w-full flex-1'></div>
96
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
97
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
98
+ </div>
99
+ <div class='col-span-2 hidden md:block'>
100
+ <div class='aspect-1 bg-accent w-full'></div>
101
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
102
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
103
+ </div>
104
+ <div class='col-span-2 hidden md:block'>
105
+ <div class='aspect-1 bg-accent w-full'></div>
106
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
107
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
108
+ </div>
109
+ </div>
110
+ <div class="md:hidden w-full block rounded-button bg-accent h-12 mt-8"></div>
111
+ <% end %>
112
+ </div>
113
+ </div>
114
+ <% end %>
115
+ </div>
116
+ </div>
@@ -0,0 +1,71 @@
1
+ <% cache_unless page_builder_enabled?, spree_base_cache_scope.call(section) do %>
2
+ <div class="page-container py-5" style="<%= section_styles(section) %>">
3
+ <% heading_size = case section.preferred_heading_size
4
+ when 'small' then 'text-base font-medium'
5
+ when 'medium' then 'text-lg lg:text-xl font-medium'
6
+ when 'large' then 'text-xl lg:text-2xl font-medium'
7
+ end
8
+ %>
9
+ <h3 class="<%= heading_size %> mb-4 text-<%= section.preferred_heading_alignment %>">
10
+ <%= section.preferred_heading %>
11
+ </h3>
12
+ <div class="gap-6 grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 xl:gap-x-8 mb-7 hidden md:grid">
13
+ <% section.links.each do |link| %>
14
+ <%= page_builder_link_to link, title: link.label, class: 'group block overflow-hidden', target: link.open_in_new_tab.presence && '_blank' do %>
15
+ <% if link.linkable.image&.attached? && link.linkable.image&.variable? %>
16
+ <div class="flex space-y-2 flex-col">
17
+ <%= image_tag main_app.cdn_image_url(link.linkable.image.variant(spree_image_variant_options(resize_to_fill: [600, 600]))), height: 300, width: 300, class: 'h-full w-full object-cover object-center group-hover:opacity-75 rounded-md bg-gray-200', loading: :lazy, alt: link.label %>
18
+ <span><%= link.label %></span>
19
+ </div>
20
+ <% else %>
21
+ <div class="aspect-1 w-full group-hover:bg-gray-100 bg-gray-200 rounded-md flex items-center justify-center relative">
22
+ <span><%= link.label %></span>
23
+ </div>
24
+ <% end %>
25
+ <% end %>
26
+ <% end %>
27
+ </div>
28
+ <div class="pt-5 flex items-center space-x-2 md:hidden">
29
+ <button class='swiper-custom-button-prev'>
30
+ <%= render 'spree/shared/icons/arrow-left' %>
31
+ </button>
32
+ <div class="swiper-container overflow-hidden mb-7 relative flex-1" data-controller='carousel' data-carousel-options-value='{
33
+ "slidesPerView": "auto",
34
+ "centeredSlides": false,
35
+ "spaceBetween": 10,
36
+ "grabCursor": true,
37
+ "freeMode": true,
38
+ "navigation": {
39
+ "nextEl": ".swiper-custom-button-next",
40
+ "prevEl": ".swiper-custom-button-prev"
41
+ },
42
+ "pagination": {
43
+ "el": ".swiper-pagination"
44
+ }
45
+ }'>
46
+ <div class='swiper-wrapper'>
47
+ <% section.links.each do |link| %>
48
+ <div class='swiper-slide w-[200px]'>
49
+ <%= page_builder_link_to link, title: link.label, class: 'group block overflow-hidden', target: link.open_in_new_tab.presence && '_blank' do %>
50
+ <% if link.linkable.image&.attached? && link.linkable.image&.variable? %>
51
+ <div class="flex space-y-2 flex-col">
52
+ <%= image_tag main_app.cdn_image_url(link.linkable.image.variant(spree_image_variant_options(resize_to_fill: [400, 400]))), height: 200, width: 200, class: 'h-full w-full object-cover object-center group-hover:opacity-75 rounded-md bg-gray-200', loading: :lazy, alt: link.label %>
53
+ <span><%= link.label %></span>
54
+ </div>
55
+ <% else %>
56
+ <div class="aspect-1 w-full group-hover:bg-gray-100 bg-gray-200 flex items-center justify-center relative">
57
+ <span><%= link.label %></span>
58
+ </div>
59
+ <% end %>
60
+ <% end %>
61
+ </div>
62
+ <% end %>
63
+ </div>
64
+ <div class="swiper-pagination !relative mt-10 items-center flex mx-auto align-center justify-center"></div>
65
+ </div>
66
+ <button class='swiper-custom-button-next'>
67
+ <%= render 'spree/shared/icons/arrow-right' %>
68
+ </button>
69
+ </div>
70
+ </div>
71
+ <% end %>