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,365 @@
1
+ module Spree
2
+ class CheckoutController < StoreController
3
+ include Spree::BaseHelper
4
+ include Spree::CheckoutHelper
5
+ include Spree::CheckoutAnalyticsHelper
6
+
7
+ before_action :require_user, unless: -> { current_store.prefers_guest_checkout? }
8
+ before_action :load_order
9
+ before_action :remove_out_of_stock_items, only: [:edit, :update]
10
+
11
+ before_action :set_cache_header, only: [:edit]
12
+ before_action :ensure_valid_state_lock_version, only: [:update]
13
+ before_action :set_state_if_present, only: [:edit, :update]
14
+
15
+ before_action :ensure_order_not_completed, only: [:edit, :update]
16
+ before_action :ensure_checkout_allowed
17
+ before_action :ensure_valid_state, only: [:edit, :update]
18
+
19
+ before_action :restart_checkout, only: :edit, if: :should_restart_checkout?
20
+
21
+ before_action :setup_for_current_state, only: [:edit, :update]
22
+
23
+ before_action :remove_expired_gift_card, only: :edit
24
+
25
+ before_action :store_location, only: :edit
26
+
27
+ after_action :clean_analytics_session, only: :edit
28
+ after_action :clear_checkout_completed_session, only: [:complete]
29
+
30
+ rescue_from Spree::Core::GatewayError, with: :rescue_from_spree_gateway_error
31
+
32
+ layout 'spree/checkout'
33
+
34
+ # GET /checkout/<token>
35
+ def edit
36
+ if checkout_started?
37
+ track_checkout_started
38
+
39
+ @order.accept_marketing = true # TODO: move this to store preferences
40
+ @order.signup_for_an_account = true # TODO: move this to store preferences
41
+ end
42
+
43
+ track_checkout_step_viewed
44
+ end
45
+
46
+ # PATCH /checkout/<token>
47
+ # Updates the order and advances to the next state (when possible.)
48
+ # Passing params[:do_not_advance] = true only updates order without the need to advance to the next state.
49
+ def update
50
+ @previous_state = @order.state
51
+
52
+ if @order.update_from_params(params, permitted_checkout_attributes, request.headers.env)
53
+ track_checkout_entered_email
54
+ track_payment_info_entered
55
+ track_checkout_step_completed
56
+
57
+ unless params[:do_not_advance]
58
+ @order.temporary_address = !params[:save_user_address]
59
+ unless @order.next
60
+ return if @order.address? && @order.line_items_without_shipping_rates.any? && turbo_stream_request? # render update trubo_stream
61
+
62
+ flash[:error] = @order.errors.messages.values.flatten.join("\n")
63
+ redirect_to(spree.checkout_state_path(@order.token, @order.state)) && return
64
+ end
65
+
66
+ if @order.completed?
67
+ track_checkout_completed
68
+ redirect_to spree.checkout_complete_path(@order.token), status: :see_other
69
+ else
70
+ redirect_to spree.checkout_state_path(@order.token, @order.state)
71
+ end
72
+ end
73
+ else
74
+ render :edit, status: :unprocessable_entity
75
+ end
76
+ end
77
+
78
+ # DELETE /checkout/<token>/remove_missing_items
79
+ def remove_missing_items
80
+ line_items_to_remove = @order.line_items.where(id: params[:line_item_ids])
81
+
82
+ ApplicationRecord.transaction do
83
+ line_items_to_remove.each do |line_item|
84
+ remove_line_item_service.call(order: @order, line_item: line_item)
85
+ end
86
+ end
87
+
88
+ redirect_to spree.checkout_path(@order.token)
89
+ end
90
+
91
+ # GET /checkout/<token>/complete
92
+ def complete
93
+ clear_order_token
94
+ end
95
+
96
+ # PATCH /checkout/<token>/coupon_code
97
+ def apply_coupon_code
98
+ @order.coupon_code = params[:coupon_code]
99
+ @result = coupon_handler.new(@order, { email: params[:promotion_email] }).apply
100
+
101
+ track_event('coupon_entered', coupon_tracking_params)
102
+
103
+ if @result&.successful?
104
+ track_event('coupon_applied', coupon_tracking_params)
105
+ else
106
+ track_event('coupon_denied', coupon_tracking_params)
107
+ end
108
+
109
+ respond_to do |format|
110
+ format.turbo_stream
111
+ format.html do
112
+ if @result&.successful?
113
+ flash[:success] = 'Coupon applied successfully'
114
+ else
115
+ flash[:error] = @result&.error
116
+ end
117
+ redirect_to spree.checkout_path(@order.token)
118
+ end
119
+ end
120
+ end
121
+
122
+ # DELETE /checkout/<token>/coupon_code
123
+ def remove_coupon_code
124
+ @result = coupon_handler.new(@order).remove(params[:coupon_code] || params[:gift_card])
125
+
126
+ track_event('coupon_removed', coupon_tracking_params) if @result.successful?
127
+ params.delete(:coupon_code)
128
+
129
+ respond_to do |format|
130
+ format.turbo_stream
131
+ format.html { redirect_to spree.checkout_path(@order.token) }
132
+ end
133
+ end
134
+
135
+ def apply_store_credit
136
+ add_store_credit_service.call(order: @order)
137
+
138
+ respond_to do |format|
139
+ format.turbo_stream
140
+ format.html { redirect_to spree.checkout_path(@order.token) }
141
+ end
142
+ end
143
+
144
+ def remove_store_credit
145
+ remove_store_credit_service.call(order: @order)
146
+
147
+ respond_to do |format|
148
+ format.turbo_stream
149
+ format.html { redirect_to spree.checkout_path(@order.token) }
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ # rather then using cookies like in old Spree we're going to fetch the order based on the
156
+ # token passed in the parameters, this allows us to share carts, send payment links, etc
157
+ def load_order
158
+ return @order if @order.present?
159
+
160
+ orders_scope = if action_name == 'complete'
161
+ current_store.orders.complete
162
+ else
163
+ current_store.orders.incomplete
164
+ end
165
+
166
+ # we shouldn't lock the order here, because we're not going to update it
167
+ lock = !['complete', 'edit'].include?(action_name)
168
+
169
+ @order = orders_scope.lock(lock).find_by(token: params[:token])
170
+
171
+ if @order.nil?
172
+ clear_order_token
173
+ redirect_to_cart and return
174
+ end
175
+
176
+ if @order.user_id.present?
177
+ if try_spree_current_user.present? && @order.user_id != try_spree_current_user.id
178
+ clear_order_token
179
+ flash[:error] = 'You cannot access this checkout'
180
+ redirect_to_cart
181
+ elsif try_spree_current_user.nil? && !@order.completed?
182
+ store_location
183
+ redirect_to spree_login_path
184
+ end
185
+ end
186
+
187
+ # completed orders shouldn't be updated anymore
188
+ unless @order.completed?
189
+ @order.assign_attributes(order_tracking_params)
190
+ @order.update_columns(order_tracking_params)
191
+ @order.associate_user!(try_spree_current_user) if try_spree_current_user && @order.user.nil?
192
+ end
193
+ @current_order = @order # for compatibility with the rest of storefront, analytics, etc
194
+ end
195
+
196
+ def remove_out_of_stock_items
197
+ _validated_order, messages = Spree::Cart::RemoveOutOfStockItems.call(order: @order).value
198
+
199
+ if messages.any?
200
+ flash[:error] = messages.to_sentence
201
+ redirect_to_cart
202
+ end
203
+ end
204
+
205
+ def unknown_state?
206
+ (params[:state] && !@order.has_checkout_step?(params[:state])) ||
207
+ (!params[:state] && !@order.has_checkout_step?(@order.state))
208
+ end
209
+
210
+ def insufficient_payment?
211
+ params[:state] == 'confirm' &&
212
+ @order.payment_required? &&
213
+ @order.payments.valid.sum(:amount) != @order.total
214
+ end
215
+
216
+ def correct_state
217
+ if unknown_state?
218
+ @order.checkout_steps.first
219
+ elsif insufficient_payment?
220
+ 'payment'
221
+ elsif @order.state == 'cart'
222
+ 'address'
223
+ elsif @order.digital? && @order.delivery?
224
+ 'address'
225
+ else
226
+ @order.state
227
+ end
228
+ end
229
+
230
+ def ensure_valid_state
231
+ redirect_to_state(correct_state) if @order.state != correct_state && !skip_state_validation?
232
+ end
233
+
234
+ def redirect_to_state(state)
235
+ flash.keep
236
+ @order.update_column(:state, state)
237
+ # GL is GA4 parameter needed to persist user's session between custom storefront and checkout
238
+ redirect_to spree.checkout_state_path(@order.token, @order.state, _gl: params[:_gl].presence)
239
+ end
240
+
241
+ def should_restart_checkout?
242
+ (@order.quick_checkout? || @order.ship_address.nil?) && (@order.delivery? || @order.payment?)
243
+ end
244
+
245
+ def restart_checkout
246
+ @order.update!(ship_address: nil)
247
+ redirect_to_state('address')
248
+ end
249
+
250
+ def skip_state_validation?
251
+ %w(complete).include?(params[:action])
252
+ end
253
+
254
+ def ensure_valid_state_lock_version
255
+ if params[:order] && params[:order][:state_lock_version]
256
+ changes = @order.changes.transform_values(&:last).symbolize_keys if @order.changed?
257
+ @order.reload.with_lock do
258
+ unless @order.state_lock_version == params[:order].delete(:state_lock_version).to_i
259
+ flash[:error] = Spree.t(:order_already_updated)
260
+ redirect_to(checkout_state_path(@order.token, @order.state)) && return
261
+ end
262
+ @order.increment!(:state_lock_version)
263
+ end
264
+ @order.assign_attributes(changes) if changes
265
+ end
266
+ end
267
+
268
+ def set_state_if_present
269
+ if params[:state] && params[:state] != 'complete'
270
+ redirect_to spree.checkout_state_path(@order.token, @order.state) if @order.can_go_to_state?(params[:state]) && !skip_state_validation?
271
+ @order.state = params[:state]
272
+ end
273
+ end
274
+
275
+ def ensure_checkout_allowed
276
+ return if @order.checkout_allowed?
277
+
278
+ redirect_to_cart
279
+ end
280
+
281
+ def ensure_order_not_completed
282
+ return unless @order.completed?
283
+
284
+ clear_order_token
285
+ redirect_to_cart
286
+ end
287
+
288
+ def setup_for_current_state
289
+ method_name = :"before_#{@order.state}"
290
+ send(method_name) if respond_to?(method_name, true)
291
+ end
292
+
293
+ def before_address
294
+ if try_spree_current_user.present?
295
+ @order.ship_address ||= try_spree_current_user.ship_address
296
+ @order.bill_address ||= try_spree_current_user.bill_address
297
+ end
298
+ # for guest users or users without addresses, we need to build an empty one here
299
+ @order.ship_address ||= Address.new(country: current_store.default_country, user: try_spree_current_user)
300
+ end
301
+
302
+ def before_delivery
303
+ return if params[:order].present?
304
+
305
+ packages = @order.shipments.map(&:to_package)
306
+ @differentiator = Spree::Stock::Differentiator.new(@order, packages)
307
+ end
308
+
309
+ def before_payment
310
+ @order.bill_address ||= @order.ship_address.clone
311
+
312
+ if @order.checkout_steps.include? 'delivery'
313
+ packages = @order.shipments.map(&:to_package)
314
+ @differentiator = Spree::Stock::Differentiator.new(@order, packages)
315
+ @differentiator.missing.each do |variant, quantity|
316
+ Spree::Dependencies.cart_remove_item_service.constantize.call(order: @order, variant: variant, quantity: quantity)
317
+ end
318
+ end
319
+ end
320
+
321
+ def rescue_from_spree_gateway_error(exception)
322
+ Rails.error.report(
323
+ exception,
324
+ context: { order_id: @order&.id, order_number: @order&.number, error_type: 'gateway_error' },
325
+ source: 'spree.storefront'
326
+ )
327
+
328
+ flash.now[:error] = Spree.t(:spree_gateway_error_flash_for_checkout)
329
+ @order.errors.add(:base, exception.message)
330
+ render :edit, status: :unprocessable_entity
331
+ end
332
+
333
+ # we don't want to browser cache the checkout page
334
+ def set_cache_header
335
+ response.headers['Cache-Control'] = 'no-store'
336
+ end
337
+
338
+ def add_store_credit_service
339
+ Spree::Dependencies.checkout_add_store_credit_service.constantize
340
+ end
341
+
342
+ def remove_store_credit_service
343
+ Spree::Dependencies.checkout_remove_store_credit_service.constantize
344
+ end
345
+
346
+ def remove_line_item_service
347
+ Spree::Dependencies.cart_remove_line_item_service.constantize
348
+ end
349
+
350
+ def coupon_handler
351
+ Spree::Dependencies.coupon_handler.constantize
352
+ end
353
+
354
+ def accurate_title
355
+ Spree.t(:checkout)
356
+ end
357
+
358
+ def remove_expired_gift_card
359
+ return unless defined?(Spree::GiftCards::Remove)
360
+ return unless @order.gift_card.present? && @order.gift_card.expired?
361
+
362
+ Spree::GiftCards::Remove.call(order: @order)
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,46 @@
1
+ module Spree
2
+ class ContactsController < StoreController
3
+ before_action :load_store
4
+ before_action :ensure_customer_support_email
5
+
6
+ def new
7
+ @contact = Spree::Contact.new
8
+ end
9
+
10
+ def create
11
+ @contact = Spree::Contact.new(params[:contact])
12
+ @contact.customer_support_email = current_store.customer_support_email
13
+ @contact.request = request
14
+
15
+ if @contact.deliver
16
+ flash[:success] = Spree.t('storefront.contacts.message_sent')
17
+ else
18
+ message_not_sent
19
+ end
20
+ redirect_to action: :new
21
+ end
22
+
23
+ private
24
+
25
+ def load_store
26
+ @store = current_store
27
+ end
28
+
29
+ def message_not_sent(exception = nil)
30
+ Rails.error.report(
31
+ exception || StandardError.new('Contact Form Message not sent'),
32
+ context: { contact_id: @contact&.id },
33
+ source: 'spree.storefront'
34
+ )
35
+
36
+ flash[:error] = Spree.t('storefront.contacts.message_not_sent')
37
+ end
38
+
39
+ def ensure_customer_support_email
40
+ return if current_store.customer_support_email.present?
41
+
42
+ flash[:error] = Spree.t('storefront.contacts.customer_support_email_not_configured')
43
+ redirect_back_or_default root_path
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ module Spree
2
+ class DigitalLinksController < StoreController
3
+ def show
4
+ if digital_link.authorize!
5
+ mark_shipment_as_fullfiled if digital_link.access_counter == 1
6
+
7
+ if defined?(ActiveStorage::Service::DiskService) && ActiveStorage::Blob.service.instance_of?(ActiveStorage::Service::DiskService)
8
+ send_file(
9
+ ActiveStorage::Blob.service.path_for(attachment.key),
10
+ filename: digital_link.filename.to_s,
11
+ type: digital_link.content_type.to_s,
12
+ status: :ok
13
+ ) and return
14
+ else
15
+ redirect_to attachment.url(
16
+ expires_in: current_store.preferred_digital_asset_link_expire_time.seconds,
17
+ disposition: 'attachment'
18
+ ), allow_other_host: true and return
19
+ end
20
+ end
21
+
22
+ flash[:error] = Spree.t(:digital_link_unauthorized)
23
+ redirect_to spree.order_path(digital_link.order)
24
+ end
25
+
26
+ private
27
+
28
+ def mark_shipment_as_fullfiled
29
+ ActiveRecord::Base.connected_to(role: :writing) do
30
+ Spree::Shipment.transaction do
31
+ shipments.each(&:ship)
32
+ end
33
+ end
34
+ end
35
+
36
+ def digital_link
37
+ @digital_link ||= current_store.digital_links.find_by!(token: params[:id])
38
+ end
39
+
40
+ def shipments
41
+ @shipments ||= digital_link.line_item.shipments.digital_delivery
42
+ end
43
+
44
+ def attachment
45
+ @attachment ||= digital_link.digital.attachment
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ class HomeController < Spree::StoreController
3
+ def index; end
4
+ end
5
+ end
@@ -0,0 +1,96 @@
1
+ module Spree
2
+ class LineItemsController < Spree::StoreController
3
+ include CartMethods
4
+
5
+ before_action :load_variant, only: :create
6
+ before_action :assign_order_with_lock, except: :create
7
+ before_action :load_line_item, except: :create
8
+
9
+ skip_before_action :verify_authenticity_token, only: :create
10
+
11
+ helper 'spree/products'
12
+
13
+ def create
14
+ @order = current_order(create_order_if_necessary: true)
15
+ @quantity = params[:quantity].to_i || 1
16
+ options = params[:options] || {}
17
+
18
+ cookies.permanent.signed[:token] = @order.token if @order.persisted?
19
+
20
+ result = cart_add_item_service.call(order: @order,
21
+ variant: @variant,
22
+ quantity: @quantity,
23
+ options: options)
24
+
25
+ flash.now[:error] = result.value.errors.full_messages.to_sentence if result.failure?
26
+
27
+ @line_item = result.value
28
+
29
+ if result.success?
30
+ load_line_items
31
+
32
+ track_event('product_added', { line_item: @line_item })
33
+ else
34
+ @error = result.value.errors.full_messages.to_sentence
35
+ flash.now[:error] = @error
36
+ end
37
+
38
+ respond_to do |format|
39
+ format.turbo_stream
40
+ format.html { redirect_to spree.cart_path(order_token: order_token) }
41
+ end
42
+ end
43
+
44
+ def update
45
+ quantity = line_item_params[:quantity]&.to_i || 1
46
+ result = cart_set_item_quantity_service.call(order: @order, line_item: @line_item, quantity: quantity)
47
+
48
+ @error = result.value.errors.full_messages.to_sentence if result.failure?
49
+
50
+ load_line_items if result.success?
51
+
52
+ respond_to do |format|
53
+ format.turbo_stream
54
+ format.html { redirect_to spree.cart_path(order_token: order_token) }
55
+ end
56
+ end
57
+
58
+ def destroy
59
+ result = cart_remove_line_item_service.call(order: @order, line_item: @line_item)
60
+ load_line_items if result.success?
61
+
62
+ track_event('product_removed', { line_item: @line_item })
63
+
64
+ respond_to do |format|
65
+ format.turbo_stream
66
+ format.html { redirect_to spree.cart_path(order_token: order_token) }
67
+ end
68
+ end
69
+
70
+ protected
71
+
72
+ def load_variant
73
+ @variant = current_store.variants.find(params[:variant_id])
74
+ end
75
+
76
+ def load_line_item
77
+ @line_item = @order.line_items.find(params[:id])
78
+ end
79
+
80
+ def line_item_params
81
+ params.require(:line_item).permit(*permitted_line_item_attributes)
82
+ end
83
+
84
+ def cart_add_item_service
85
+ Spree::Dependencies.cart_add_item_service.constantize
86
+ end
87
+
88
+ def cart_remove_line_item_service
89
+ Spree::Dependencies.cart_remove_line_item_service.constantize
90
+ end
91
+
92
+ def cart_set_item_quantity_service
93
+ Spree::Dependencies.cart_set_item_quantity_service.constantize
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ class NewsletterSubscribersController < StoreController
3
+ skip_before_action :redirect_to_password
4
+ before_action :load_newsletter_section, only: :create
5
+
6
+ # POST /newsletter_subscribers
7
+ def create
8
+ user = Spree.user_class.find_or_initialize_by(email: newsletter_params[:email])
9
+
10
+ if user.new_record? && user.respond_to?(:password) && user.respond_to?(:password_confirmation)
11
+ user.password ||= SecureRandom.hex(16) # we need to set a password to pass validation
12
+ user.password_confirmation ||= user.password
13
+ end
14
+
15
+ user.accepts_email_marketing = true if user.new_record? || try_spree_current_user == user
16
+
17
+ if user.save
18
+ track_event('subscribed_to_newsletter', { email: user.email, user: user })
19
+
20
+ flash[:success] = Spree.t('storefront.newsletter_subscribers.success')
21
+ else
22
+ flash[:error] = user.errors.full_messages.to_sentence.presence || Spree.t('something_went_wrong')
23
+ end
24
+
25
+ respond_to do |format|
26
+ format.html { redirect_to spree.root_path }
27
+ format.turbo_stream
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def newsletter_params
34
+ params.require(:newsletter).permit(:email)
35
+ end
36
+
37
+ def load_newsletter_section
38
+ return if params[:section_id].blank?
39
+
40
+ @newsletter_section = Spree::PageSections::Newsletter.find_by(id: params[:section_id])
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ module Spree
2
+ class OrderStatusController < StoreController
3
+ # page for user to input their email address and order number
4
+ # GET /order_status
5
+ def new; end
6
+
7
+ # validate email/order number and redirect to order page
8
+ # POST /order_status
9
+ def create
10
+ raise ActiveRecord::RecordNotFound if params[:number].blank?
11
+
12
+ @order = order_finder.new(number: params[:number], email: params[:email], store: current_store).execute.first
13
+
14
+ if @order
15
+ redirect_to spree.order_path(@order, token: @order.token), status: :see_other
16
+ else
17
+ flash[:error] = Spree.t(:order_not_found)
18
+ render :new, status: :unprocessable_entity
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def accurate_title
25
+ Spree.t(:order_status)
26
+ end
27
+
28
+ def order_finder
29
+ Spree::Dependencies.completed_order_finder.constantize
30
+ end
31
+ end
32
+ end