@merchi/cart 1.4.4

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 (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/esm/Cart.js +62 -0
  4. package/esm/CartAlert.js +47 -0
  5. package/esm/CartHeader.js +29 -0
  6. package/esm/CartProvider.js +1101 -0
  7. package/esm/CartTotals.js +89 -0
  8. package/esm/assets/merchi-monster-loader.gif +0 -0
  9. package/esm/assets/merchi-swipe-outline.png +0 -0
  10. package/esm/assets/product-not-found.png +0 -0
  11. package/esm/assets/stripe-payment-secure.png +0 -0
  12. package/esm/buttons/Button.js +23 -0
  13. package/esm/buttons/ButtonBack.js +35 -0
  14. package/esm/buttons/ButtonClearCart.js +17 -0
  15. package/esm/buttons/ButtonInvoiceDownload.js +88 -0
  16. package/esm/buttons/ButtonNext.js +39 -0
  17. package/esm/buttons/ButtonNextDynamic.js +19 -0
  18. package/esm/buttons/ButtonOpenCartMerchiCartModal.js +47 -0
  19. package/esm/buttons/ButtonPay.js +26 -0
  20. package/esm/buttons/ButtonShipmentTabNext.js +28 -0
  21. package/esm/buttons/index.js +7 -0
  22. package/esm/components/Alert.js +26 -0
  23. package/esm/components/CartBody.js +14 -0
  24. package/esm/components/CartClient.js +62 -0
  25. package/esm/components/CartFooter.js +12 -0
  26. package/esm/components/CartItemRow.js +230 -0
  27. package/esm/components/CartPaymentSettingsInvalid.js +13 -0
  28. package/esm/components/CartShipment.js +52 -0
  29. package/esm/components/CartTabContent.js +12 -0
  30. package/esm/components/CartTabPanel.js +25 -0
  31. package/esm/components/CartTableContainer.js +12 -0
  32. package/esm/components/CartTitle.js +26 -0
  33. package/esm/components/CartTotalsListGroup.js +71 -0
  34. package/esm/components/Collapse.js +32 -0
  35. package/esm/components/CustomCartProductForm.js +128 -0
  36. package/esm/components/CustomerCheckoutMethodTabs.js +94 -0
  37. package/esm/components/DiscountInputGroup.js +293 -0
  38. package/esm/components/LoadingTemplate.js +23 -0
  39. package/esm/components/NoCartItems.js +20 -0
  40. package/esm/components/ShipmentGroupCard.js +207 -0
  41. package/esm/components/Table.js +13 -0
  42. package/esm/components/containers.js +31 -0
  43. package/esm/components/index.js +18 -0
  44. package/esm/components/product-form-sdk-externals.js +36 -0
  45. package/esm/forms/FormNewCustomer.js +243 -0
  46. package/esm/forms/FormReturningCustomer.js +165 -0
  47. package/esm/forms/FormShipmentAddressAndNotes.js +195 -0
  48. package/esm/forms/FormSquarePayment.js +19 -0
  49. package/esm/forms/FormStripePayment.js +19 -0
  50. package/esm/forms/FormWhatsappCustomer.js +253 -0
  51. package/esm/forms/InputAcceptUserTermsAndConditions.js +35 -0
  52. package/esm/forms/InputError.js +16 -0
  53. package/esm/forms/InputSelect.js +48 -0
  54. package/esm/forms/InputText.js +56 -0
  55. package/esm/forms/InputsAddress.js +476 -0
  56. package/esm/forms/index.js +8 -0
  57. package/esm/index.js +13 -0
  58. package/esm/modals.js +51 -0
  59. package/esm/panels/PanelCartItems.js +49 -0
  60. package/esm/panels/PanelCartShipment.js +66 -0
  61. package/esm/panels/PanelClearCart.js +56 -0
  62. package/esm/panels/PanelClientCheckout.js +81 -0
  63. package/esm/panels/PanelEditCartItem.js +199 -0
  64. package/esm/panels/PanelPaymentSuccess.js +63 -0
  65. package/esm/panels/index.js +7 -0
  66. package/esm/square/SquareCard.js +106 -0
  67. package/esm/stripe/LegacyStripeCardForm.js +157 -0
  68. package/esm/stripe/StripeCardFields.js +126 -0
  69. package/esm/stripe/StripeCardForm.js +33 -0
  70. package/esm/stripe/StripePaymentButtons.js +98 -0
  71. package/esm/stripe/actions.js +192 -0
  72. package/esm/stripe/utils.js +20 -0
  73. package/esm/styles/globals.css +463 -0
  74. package/esm/styles/globals.css.map +1 -0
  75. package/esm/tabs/CartNav.js +28 -0
  76. package/esm/tabs/NavTab.js +31 -0
  77. package/esm/types/assets.d.js +0 -0
  78. package/esm/types/index.js +1 -0
  79. package/esm/types/merchi_product_form/index.d.js +0 -0
  80. package/esm/types/merchi_sdk_ts/index.d.js +0 -0
  81. package/esm/types/react-redux/index.d.js +0 -0
  82. package/esm/utilities/address.js +457 -0
  83. package/esm/utilities/area.js +297 -0
  84. package/esm/utilities/cart.js +95 -0
  85. package/esm/utilities/company.js +6 -0
  86. package/esm/utilities/cookie.js +156 -0
  87. package/esm/utilities/currency.js +219 -0
  88. package/esm/utilities/customForm.js +57 -0
  89. package/esm/utilities/helpers.js +229 -0
  90. package/esm/utilities/index.js +14 -0
  91. package/esm/utilities/invoice.js +112 -0
  92. package/esm/utilities/job.js +9 -0
  93. package/esm/utilities/local_storage.js +85 -0
  94. package/esm/utilities/product.js +13 -0
  95. package/esm/utilities/shipment.js +11 -0
  96. package/esm/utilities/tabs.js +51 -0
  97. package/esm/utilities/user.js +65 -0
  98. package/esm/utilities/variations.js +58 -0
  99. package/lib/Cart.d.ts +9 -0
  100. package/lib/Cart.js +69 -0
  101. package/lib/CartAlert.d.ts +3 -0
  102. package/lib/CartAlert.js +53 -0
  103. package/lib/CartHeader.d.ts +3 -0
  104. package/lib/CartHeader.js +37 -0
  105. package/lib/CartProvider.d.ts +236 -0
  106. package/lib/CartProvider.js +1107 -0
  107. package/lib/CartTotals.d.ts +7 -0
  108. package/lib/CartTotals.js +96 -0
  109. package/lib/assets/merchi-monster-loader.gif +0 -0
  110. package/lib/assets/merchi-swipe-outline.png +0 -0
  111. package/lib/assets/product-not-found.png +0 -0
  112. package/lib/assets/stripe-payment-secure.png +0 -0
  113. package/lib/buttons/Button.d.ts +11 -0
  114. package/lib/buttons/Button.js +31 -0
  115. package/lib/buttons/ButtonBack.d.ts +6 -0
  116. package/lib/buttons/ButtonBack.js +44 -0
  117. package/lib/buttons/ButtonClearCart.d.ts +3 -0
  118. package/lib/buttons/ButtonClearCart.js +24 -0
  119. package/lib/buttons/ButtonInvoiceDownload.d.ts +3 -0
  120. package/lib/buttons/ButtonInvoiceDownload.js +96 -0
  121. package/lib/buttons/ButtonNext.d.ts +3 -0
  122. package/lib/buttons/ButtonNext.js +48 -0
  123. package/lib/buttons/ButtonNextDynamic.d.ts +3 -0
  124. package/lib/buttons/ButtonNextDynamic.js +28 -0
  125. package/lib/buttons/ButtonOpenCartMerchiCartModal.d.ts +9 -0
  126. package/lib/buttons/ButtonOpenCartMerchiCartModal.js +57 -0
  127. package/lib/buttons/ButtonPay.d.ts +7 -0
  128. package/lib/buttons/ButtonPay.js +35 -0
  129. package/lib/buttons/ButtonShipmentTabNext.d.ts +2 -0
  130. package/lib/buttons/ButtonShipmentTabNext.js +37 -0
  131. package/lib/buttons/index.d.ts +7 -0
  132. package/lib/buttons/index.js +48 -0
  133. package/lib/components/Alert.d.ts +7 -0
  134. package/lib/components/Alert.js +34 -0
  135. package/lib/components/CartBody.d.ts +7 -0
  136. package/lib/components/CartBody.js +22 -0
  137. package/lib/components/CartClient.d.ts +4 -0
  138. package/lib/components/CartClient.js +71 -0
  139. package/lib/components/CartFooter.d.ts +6 -0
  140. package/lib/components/CartFooter.js +20 -0
  141. package/lib/components/CartItemRow.d.ts +7 -0
  142. package/lib/components/CartItemRow.js +236 -0
  143. package/lib/components/CartPaymentSettingsInvalid.d.ts +2 -0
  144. package/lib/components/CartPaymentSettingsInvalid.js +21 -0
  145. package/lib/components/CartShipment.d.ts +6 -0
  146. package/lib/components/CartShipment.js +59 -0
  147. package/lib/components/CartTabContent.d.ts +6 -0
  148. package/lib/components/CartTabContent.js +20 -0
  149. package/lib/components/CartTabPanel.d.ts +7 -0
  150. package/lib/components/CartTabPanel.js +31 -0
  151. package/lib/components/CartTableContainer.d.ts +6 -0
  152. package/lib/components/CartTableContainer.js +20 -0
  153. package/lib/components/CartTitle.d.ts +2 -0
  154. package/lib/components/CartTitle.js +34 -0
  155. package/lib/components/CartTotalsListGroup.d.ts +3 -0
  156. package/lib/components/CartTotalsListGroup.js +78 -0
  157. package/lib/components/Collapse.d.ts +3 -0
  158. package/lib/components/Collapse.js +40 -0
  159. package/lib/components/CustomCartProductForm.d.ts +18 -0
  160. package/lib/components/CustomCartProductForm.js +136 -0
  161. package/lib/components/CustomerCheckoutMethodTabs.d.ts +6 -0
  162. package/lib/components/CustomerCheckoutMethodTabs.js +103 -0
  163. package/lib/components/DiscountInputGroup.d.ts +2 -0
  164. package/lib/components/DiscountInputGroup.js +301 -0
  165. package/lib/components/LoadingTemplate.d.ts +7 -0
  166. package/lib/components/LoadingTemplate.js +30 -0
  167. package/lib/components/NoCartItems.d.ts +3 -0
  168. package/lib/components/NoCartItems.js +27 -0
  169. package/lib/components/ShipmentGroupCard.d.ts +7 -0
  170. package/lib/components/ShipmentGroupCard.js +215 -0
  171. package/lib/components/Table.d.ts +7 -0
  172. package/lib/components/Table.js +19 -0
  173. package/lib/components/containers.d.ts +14 -0
  174. package/lib/components/containers.js +40 -0
  175. package/lib/components/index.d.ts +18 -0
  176. package/lib/components/index.js +133 -0
  177. package/lib/components/product-form-sdk-externals.d.ts +46 -0
  178. package/lib/components/product-form-sdk-externals.js +43 -0
  179. package/lib/forms/FormNewCustomer.d.ts +4 -0
  180. package/lib/forms/FormNewCustomer.js +252 -0
  181. package/lib/forms/FormReturningCustomer.d.ts +3 -0
  182. package/lib/forms/FormReturningCustomer.js +173 -0
  183. package/lib/forms/FormShipmentAddressAndNotes.d.ts +15 -0
  184. package/lib/forms/FormShipmentAddressAndNotes.js +203 -0
  185. package/lib/forms/FormSquarePayment.d.ts +3 -0
  186. package/lib/forms/FormSquarePayment.js +27 -0
  187. package/lib/forms/FormStripePayment.d.ts +3 -0
  188. package/lib/forms/FormStripePayment.js +27 -0
  189. package/lib/forms/FormWhatsappCustomer.d.ts +3 -0
  190. package/lib/forms/FormWhatsappCustomer.js +261 -0
  191. package/lib/forms/InputAcceptUserTermsAndConditions.d.ts +7 -0
  192. package/lib/forms/InputAcceptUserTermsAndConditions.js +41 -0
  193. package/lib/forms/InputError.d.ts +8 -0
  194. package/lib/forms/InputError.js +24 -0
  195. package/lib/forms/InputSelect.d.ts +14 -0
  196. package/lib/forms/InputSelect.js +55 -0
  197. package/lib/forms/InputText.d.ts +12 -0
  198. package/lib/forms/InputText.js +63 -0
  199. package/lib/forms/InputsAddress.d.ts +11 -0
  200. package/lib/forms/InputsAddress.js +485 -0
  201. package/lib/forms/index.d.ts +8 -0
  202. package/lib/forms/index.js +63 -0
  203. package/lib/index.d.ts +13 -0
  204. package/lib/index.js +93 -0
  205. package/lib/modals.d.ts +17 -0
  206. package/lib/modals.js +59 -0
  207. package/lib/panels/PanelCartItems.d.ts +3 -0
  208. package/lib/panels/PanelCartItems.js +56 -0
  209. package/lib/panels/PanelCartShipment.d.ts +3 -0
  210. package/lib/panels/PanelCartShipment.js +72 -0
  211. package/lib/panels/PanelClearCart.d.ts +3 -0
  212. package/lib/panels/PanelClearCart.js +62 -0
  213. package/lib/panels/PanelClientCheckout.d.ts +3 -0
  214. package/lib/panels/PanelClientCheckout.js +88 -0
  215. package/lib/panels/PanelEditCartItem.d.ts +6 -0
  216. package/lib/panels/PanelEditCartItem.js +206 -0
  217. package/lib/panels/PanelPaymentSuccess.d.ts +3 -0
  218. package/lib/panels/PanelPaymentSuccess.js +69 -0
  219. package/lib/panels/index.d.ts +7 -0
  220. package/lib/panels/index.js +48 -0
  221. package/lib/square/SquareCard.d.ts +3 -0
  222. package/lib/square/SquareCard.js +114 -0
  223. package/lib/stripe/LegacyStripeCardForm.d.ts +3 -0
  224. package/lib/stripe/LegacyStripeCardForm.js +166 -0
  225. package/lib/stripe/StripeCardFields.d.ts +15 -0
  226. package/lib/stripe/StripeCardFields.js +135 -0
  227. package/lib/stripe/StripeCardForm.d.ts +2 -0
  228. package/lib/stripe/StripeCardForm.js +42 -0
  229. package/lib/stripe/StripePaymentButtons.d.ts +8 -0
  230. package/lib/stripe/StripePaymentButtons.js +106 -0
  231. package/lib/stripe/actions.d.ts +4 -0
  232. package/lib/stripe/actions.js +200 -0
  233. package/lib/stripe/utils.d.ts +18 -0
  234. package/lib/stripe/utils.js +27 -0
  235. package/lib/styles/globals.css +463 -0
  236. package/lib/styles/globals.css.map +1 -0
  237. package/lib/tabs/CartNav.d.ts +3 -0
  238. package/lib/tabs/CartNav.js +36 -0
  239. package/lib/tabs/NavTab.d.ts +9 -0
  240. package/lib/tabs/NavTab.js +39 -0
  241. package/lib/types/index.d.ts +13 -0
  242. package/lib/types/index.js +1 -0
  243. package/lib/utilities/address.d.ts +30 -0
  244. package/lib/utilities/address.js +468 -0
  245. package/lib/utilities/area.d.ts +77 -0
  246. package/lib/utilities/area.js +328 -0
  247. package/lib/utilities/cart.d.ts +9 -0
  248. package/lib/utilities/cart.js +108 -0
  249. package/lib/utilities/company.d.ts +2 -0
  250. package/lib/utilities/company.js +13 -0
  251. package/lib/utilities/cookie.d.ts +4 -0
  252. package/lib/utilities/cookie.js +165 -0
  253. package/lib/utilities/currency.d.ts +5 -0
  254. package/lib/utilities/currency.js +229 -0
  255. package/lib/utilities/customForm.d.ts +17 -0
  256. package/lib/utilities/customForm.js +64 -0
  257. package/lib/utilities/helpers.d.ts +24 -0
  258. package/lib/utilities/helpers.js +240 -0
  259. package/lib/utilities/index.d.ts +14 -0
  260. package/lib/utilities/index.js +159 -0
  261. package/lib/utilities/invoice.d.ts +3 -0
  262. package/lib/utilities/invoice.js +118 -0
  263. package/lib/utilities/job.d.ts +1 -0
  264. package/lib/utilities/job.js +15 -0
  265. package/lib/utilities/local_storage.d.ts +31 -0
  266. package/lib/utilities/local_storage.js +96 -0
  267. package/lib/utilities/product.d.ts +2 -0
  268. package/lib/utilities/product.js +21 -0
  269. package/lib/utilities/shipment.d.ts +2 -0
  270. package/lib/utilities/shipment.js +18 -0
  271. package/lib/utilities/tabs.d.ts +14 -0
  272. package/lib/utilities/tabs.js +60 -0
  273. package/lib/utilities/user.d.ts +5 -0
  274. package/lib/utilities/user.js +75 -0
  275. package/lib/utilities/variations.d.ts +18 -0
  276. package/lib/utilities/variations.js +66 -0
  277. package/package.json +109 -0
  278. package/src/Cart.tsx +96 -0
  279. package/src/CartAlert.tsx +35 -0
  280. package/src/CartHeader.tsx +28 -0
  281. package/src/CartProvider.tsx +992 -0
  282. package/src/CartTotals.tsx +102 -0
  283. package/src/assets/merchi-monster-loader.gif +0 -0
  284. package/src/assets/merchi-swipe-outline.png +0 -0
  285. package/src/assets/product-not-found.png +0 -0
  286. package/src/assets/stripe-payment-secure.png +0 -0
  287. package/src/buttons/Button.tsx +35 -0
  288. package/src/buttons/ButtonBack.tsx +42 -0
  289. package/src/buttons/ButtonClearCart.tsx +17 -0
  290. package/src/buttons/ButtonInvoiceDownload.tsx +60 -0
  291. package/src/buttons/ButtonNext.tsx +35 -0
  292. package/src/buttons/ButtonNextDynamic.tsx +31 -0
  293. package/src/buttons/ButtonOpenCartMerchiCartModal.tsx +61 -0
  294. package/src/buttons/ButtonPay.tsx +32 -0
  295. package/src/buttons/ButtonShipmentTabNext.tsx +24 -0
  296. package/src/buttons/index.ts +15 -0
  297. package/src/components/Alert.tsx +31 -0
  298. package/src/components/CartBody.tsx +16 -0
  299. package/src/components/CartClient.tsx +52 -0
  300. package/src/components/CartFooter.tsx +15 -0
  301. package/src/components/CartItemRow.tsx +212 -0
  302. package/src/components/CartPaymentSettingsInvalid.tsx +12 -0
  303. package/src/components/CartShipment.tsx +56 -0
  304. package/src/components/CartTabContent.tsx +15 -0
  305. package/src/components/CartTabPanel.tsx +25 -0
  306. package/src/components/CartTableContainer.tsx +15 -0
  307. package/src/components/CartTitle.tsx +22 -0
  308. package/src/components/CartTotalsListGroup.tsx +58 -0
  309. package/src/components/Collapse.tsx +23 -0
  310. package/src/components/CustomCartProductForm.tsx +123 -0
  311. package/src/components/CustomerCheckoutMethodTabs.tsx +106 -0
  312. package/src/components/DiscountInputGroup.tsx +160 -0
  313. package/src/components/LoadingTemplate.tsx +22 -0
  314. package/src/components/NoCartItems.tsx +20 -0
  315. package/src/components/ShipmentGroupCard.tsx +170 -0
  316. package/src/components/Table.tsx +15 -0
  317. package/src/components/containers.tsx +40 -0
  318. package/src/components/index.ts +38 -0
  319. package/src/components/product-form-sdk-externals.ts +67 -0
  320. package/src/forms/FormNewCustomer.tsx +170 -0
  321. package/src/forms/FormReturningCustomer.tsx +117 -0
  322. package/src/forms/FormShipmentAddressAndNotes.tsx +165 -0
  323. package/src/forms/FormSquarePayment.tsx +19 -0
  324. package/src/forms/FormStripePayment.tsx +19 -0
  325. package/src/forms/FormWhatsappCustomer.tsx +179 -0
  326. package/src/forms/InputAcceptUserTermsAndConditions.tsx +43 -0
  327. package/src/forms/InputError.tsx +23 -0
  328. package/src/forms/InputSelect.tsx +58 -0
  329. package/src/forms/InputText.tsx +56 -0
  330. package/src/forms/InputsAddress.tsx +438 -0
  331. package/src/forms/index.ts +18 -0
  332. package/src/index.ts +31 -0
  333. package/src/modals.tsx +65 -0
  334. package/src/panels/PanelCartItems.tsx +56 -0
  335. package/src/panels/PanelCartShipment.tsx +86 -0
  336. package/src/panels/PanelClearCart.tsx +50 -0
  337. package/src/panels/PanelClientCheckout.tsx +102 -0
  338. package/src/panels/PanelEditCartItem.tsx +172 -0
  339. package/src/panels/PanelPaymentSuccess.tsx +66 -0
  340. package/src/panels/index.ts +15 -0
  341. package/src/square/SquareCard.tsx +84 -0
  342. package/src/stripe/LegacyStripeCardForm.tsx +91 -0
  343. package/src/stripe/StripeCardFields.tsx +173 -0
  344. package/src/stripe/StripeCardForm.tsx +18 -0
  345. package/src/stripe/StripePaymentButtons.tsx +117 -0
  346. package/src/stripe/actions.ts +94 -0
  347. package/src/stripe/utils.ts +22 -0
  348. package/src/styles/globals.scss +475 -0
  349. package/src/tabs/CartNav.tsx +18 -0
  350. package/src/tabs/NavTab.tsx +36 -0
  351. package/src/types/assets.d.ts +4 -0
  352. package/src/types/index.ts +15 -0
  353. package/src/types/merchi_product_form/index.d.ts +1 -0
  354. package/src/types/merchi_sdk_ts/index.d.ts +1 -0
  355. package/src/types/react-redux/index.d.ts +0 -0
  356. package/src/utilities/address.ts +463 -0
  357. package/src/utilities/area.ts +359 -0
  358. package/src/utilities/cart.ts +80 -0
  359. package/src/utilities/company.ts +8 -0
  360. package/src/utilities/cookie.ts +58 -0
  361. package/src/utilities/currency.ts +216 -0
  362. package/src/utilities/customForm.ts +71 -0
  363. package/src/utilities/helpers.ts +213 -0
  364. package/src/utilities/index.ts +14 -0
  365. package/src/utilities/invoice.ts +60 -0
  366. package/src/utilities/job.ts +13 -0
  367. package/src/utilities/local_storage.ts +130 -0
  368. package/src/utilities/product.ts +14 -0
  369. package/src/utilities/shipment.ts +11 -0
  370. package/src/utilities/tabs.ts +38 -0
  371. package/src/utilities/user.ts +33 -0
  372. package/src/utilities/variations.ts +80 -0
@@ -0,0 +1,170 @@
1
+ import * as React from 'react';
2
+ import { useForm } from 'react-hook-form';
3
+ import InputAcceptUserTermsAndConditions from './InputAcceptUserTermsAndConditions';
4
+ import { Button } from '../buttons';
5
+ import InputSelect from './InputSelect';
6
+ import InputText from './InputText';
7
+ import { useCartContext } from '../CartProvider';
8
+ import { cartEmbed, phoneOptions } from '../utilities/helpers';
9
+ import InputError from './InputError';
10
+ import { createNewCustomer, makeUser } from '../utilities/user';
11
+ import { makeCart } from '../utilities/cart';
12
+ import { getCartCookieToken } from '../utilities/cookie';
13
+ import {
14
+ getSavedCheckoutCustomer,
15
+ saveCheckoutCustomer,
16
+ } from '../utilities/local_storage';
17
+
18
+ export const emailValidation = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]/i;
19
+
20
+ export function FormCustomerNew() {
21
+ const {
22
+ cart,
23
+ classNameBtnPrimary,
24
+ classNameCartFormGroup,
25
+ classNameCartFormGroupButton,
26
+ domainId,
27
+ setCart,
28
+ setCartClient,
29
+ showUserTermsAndConditions,
30
+ } = useCartContext();
31
+ const [loading, setLoading] = React.useState(false);
32
+ const [error, setError] = React.useState(({} as any));
33
+ const [acceptConditions, setAcceptConditions] = React.useState(true);
34
+ const savedCustomer = getSavedCheckoutCustomer(domainId);
35
+
36
+ async function actionCreateNewCustomer(customerJson: any) {
37
+ setError({});
38
+ setLoading(true);
39
+ try {
40
+ const r = await createNewCustomer(
41
+ {...customerJson, registeredUnderDomains: [{id: domainId}]}
42
+ );
43
+ const { user } = r;
44
+ if (!user?.id) {
45
+ throw new Error('Unable to create customer.');
46
+ }
47
+
48
+ // patch cart with new user
49
+ const cartToken = await getCartCookieToken((domainId as number));
50
+ const clientEnt = makeUser({id: user.id}, true);
51
+ const cartEnt = makeCart({ ...cart }, false, cartToken);
52
+ cartEnt.sendWhatsapp = false;
53
+ cartEnt.client = clientEnt;
54
+ const _cart = await cartEnt.save({embed: cartEmbed});
55
+ const cartJson = _cart.toJson();
56
+ if (!cartJson?.client?.id) {
57
+ throw new Error('Unable to attach client to cart.');
58
+ }
59
+ saveCheckoutCustomer(domainId, {
60
+ id: user.id,
61
+ name: customerJson.name,
62
+ emailAddress: customerJson.emailAddresses?.[0]?.emailAddress,
63
+ phoneNumbers: customerJson.phoneNumbers,
64
+ });
65
+ setCartClient(cartJson.client);
66
+ setCart(cartJson);
67
+ } catch (e: any) {
68
+ setError({message: e.errorMessage || e.message || 'Unable to attach client to cart.'});
69
+ } finally {
70
+ setLoading(false);
71
+ }
72
+ }
73
+
74
+ const { control, handleSubmit, watch } = useForm({
75
+ defaultValues: {
76
+ emailAddresses: [{
77
+ emailAddress: savedCustomer?.emailAddress || '',
78
+ }],
79
+ name: savedCustomer?.name || '',
80
+ phoneNumbers: [{
81
+ code: savedCustomer?.phoneNumbers?.[0]?.code || 'AU',
82
+ number: savedCustomer?.phoneNumbers?.[0]?.number || '',
83
+ }],
84
+ registeredAsGuest: false,
85
+ },
86
+ });
87
+
88
+ async function onSubmit(values: any) {
89
+ await actionCreateNewCustomer({ ...values });
90
+ }
91
+
92
+ // Basic validation for phone. Checking that phone is a number. Can make more complex if we want.
93
+ function validatePhone() {
94
+ const phone = watch('phoneNumbers.0.number');
95
+ if (isNaN(phone as any)) return 'Phone number must be a number';
96
+ else return true;
97
+ }
98
+ return (
99
+ <form onSubmit={handleSubmit(onSubmit)}>
100
+ <InputText
101
+ control={control}
102
+ label='Full Name'
103
+ name='name'
104
+ placeholder='John Smith'
105
+ rules={{ required: 'Full name is required.' }}
106
+ />
107
+ <InputText
108
+ control={control}
109
+ label='Email'
110
+ name='emailAddresses[0].emailAddress'
111
+ placeholder='john@example.com'
112
+ rules={{
113
+ required: 'Email is required.',
114
+ validate: emailValidation,
115
+ }}
116
+ />
117
+ <div style={{ display: 'flex', gap: '1rem' }}>
118
+ <div style={{ flexGrow: 1 }}>
119
+ <InputSelect
120
+ control={control}
121
+ label='Country Code'
122
+ name='phoneNumbers[0].code'
123
+ options={phoneOptions}
124
+ />
125
+ </div>
126
+ <div style={{ flexGrow: 1 }}>
127
+ <InputText
128
+ control={control}
129
+ label='Phone Number'
130
+ name='phoneNumbers[0].number'
131
+ placeholder='0400 000 000'
132
+ rules={{
133
+ required: 'Phone number is required',
134
+ validate: validatePhone,
135
+ }}
136
+ type='phone'
137
+ />
138
+ </div>
139
+ </div>
140
+ {showUserTermsAndConditions && (
141
+ <div className={classNameCartFormGroup}>
142
+ <InputAcceptUserTermsAndConditions
143
+ isChecked={acceptConditions}
144
+ setIsChecked={setAcceptConditions}
145
+ />
146
+ {!acceptConditions && (
147
+ <InputError
148
+ error={{
149
+ message:
150
+ 'You must agree to the user profile terms and conditions to proceed.',
151
+ }}
152
+ />
153
+ )}
154
+ </div>
155
+ )}
156
+ <InputError error={error || {}} />
157
+ <div className={classNameCartFormGroupButton}>
158
+ <Button
159
+ className={classNameBtnPrimary}
160
+ disabled={loading}
161
+ type='submit'
162
+ >
163
+ {loading ? 'Loading...' : 'Submit'}
164
+ </Button>
165
+ </div>
166
+ </form>
167
+ );
168
+ }
169
+
170
+ export default FormCustomerNew;
@@ -0,0 +1,117 @@
1
+ import * as React from 'react';
2
+ import { useForm } from 'react-hook-form';
3
+ import { Button } from '../buttons';
4
+ import InputError from './InputError';
5
+ import { useCartContext } from '../CartProvider';
6
+ import {
7
+ makeUser,
8
+ tryReturningCustomerEmail,
9
+ } from '../utilities/user';
10
+ import { makeCart } from '../utilities/cart';
11
+ import { getCartCookieToken } from '../utilities/cookie';
12
+ import { cartEmbed } from '../utilities/helpers';
13
+ import {
14
+ getSavedCheckoutCustomer,
15
+ saveCheckoutCustomer,
16
+ } from '../utilities/local_storage';
17
+
18
+ const emailValidation = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]/i;
19
+
20
+ function FormReturningCustomer() {
21
+ const {
22
+ alertError,
23
+ cart,
24
+ classNameBtnPrimary,
25
+ classNameCartFormGroup,
26
+ classNameCartFormInput,
27
+ classNameCartFormGroupButton,
28
+ domainId,
29
+ setCart,
30
+ setCartClient,
31
+ } = useCartContext();
32
+ const [loading, setLoading] = React.useState(false);
33
+ const [error, setError] = React.useState(({} as any));
34
+ const savedCustomer = getSavedCheckoutCustomer(domainId);
35
+
36
+ const hookForm = useForm({
37
+ defaultValues: { emailAddress: savedCustomer?.emailAddress || '' },
38
+ });
39
+ const {
40
+ handleSubmit,
41
+ formState: { errors },
42
+ getValues,
43
+ register,
44
+ } = hookForm;
45
+ async function submit() {
46
+ setError({});
47
+ const { emailAddress } = getValues();
48
+ setLoading(true);
49
+ try {
50
+ const user: any = await tryReturningCustomerEmail(emailAddress);
51
+ // /user-check-email/ returns user_id (not id)
52
+ const userId = user.user_id ?? user.id;
53
+ if (!userId) {
54
+ throw new Error('Unable to find returning customer.');
55
+ }
56
+
57
+ // Attach by id only — extra user fields trigger a forbidden user PATCH.
58
+ const cartToken = await getCartCookieToken((domainId as number));
59
+ const clientEnt = makeUser({id: userId}, true);
60
+ const cartEnt = makeCart({ ...cart }, false, cartToken);
61
+ cartEnt.sendWhatsapp = false;
62
+ cartEnt.client = clientEnt;
63
+ const _cart = await cartEnt.save({embed: cartEmbed});
64
+ const cartJson = _cart.toJson();
65
+ if (!cartJson?.client?.id) {
66
+ throw new Error('Unable to attach client to cart.');
67
+ }
68
+ saveCheckoutCustomer(domainId, {
69
+ id: userId,
70
+ name: user.name || savedCustomer?.name,
71
+ emailAddress,
72
+ });
73
+ setCartClient(cartJson.client);
74
+ setCart(cartJson);
75
+ } catch(e: any) {
76
+ alertError(e.errorMessage || e.message);
77
+ setError({message: e.errorMessage || e.message || 'Server error.'});
78
+ } finally {
79
+ setLoading(false);
80
+ }
81
+ }
82
+ return (
83
+ <form onSubmit={handleSubmit(submit)}>
84
+ <div className={classNameCartFormGroup}>
85
+ <input
86
+ className={classNameCartFormInput}
87
+ placeholder='info@example.com'
88
+ type='email'
89
+ {...register('emailAddress', {
90
+ required: 'Email address required',
91
+ pattern: {
92
+ value: emailValidation,
93
+ message: 'Invalid email address'
94
+ }
95
+ })}
96
+ />
97
+ <small>
98
+ If you are a returning customer please use the same email
99
+ which you used previously.
100
+ </small>
101
+ <InputError error={errors.emailAddress} />
102
+ {error && <InputError error={error} />}
103
+ </div>
104
+ <div className={classNameCartFormGroupButton}>
105
+ <Button
106
+ className={classNameBtnPrimary}
107
+ disabled={loading}
108
+ type='submit'
109
+ >
110
+ {loading ? 'Loading...' : 'Submit'}
111
+ </Button>
112
+ </div>
113
+ </form>
114
+ );
115
+ }
116
+
117
+ export default FormReturningCustomer;
@@ -0,0 +1,165 @@
1
+ import { useForm } from "react-hook-form";
2
+ import InputsAddress from "./InputsAddress";
3
+ import { CheckoutContainer, InnerContainer } from "../components/containers";
4
+ import { Title } from "../components";
5
+ import { shipmentFormId } from "../utilities/shipment";
6
+ import { faMapMarkerAlt } from "@fortawesome/free-solid-svg-icons";
7
+ import { useCartContext } from "../CartProvider";
8
+ import { useState } from "react";
9
+ import { getCartCookieToken } from "../utilities/cookie";
10
+ import { makeAddress, sanitizeAddressFields } from "../utilities/address";
11
+ import { makeCart } from "../utilities/cart";
12
+ import { cartEmbed } from "../utilities/helpers";
13
+ import { tabIdCheckout } from "../utilities/tabs";
14
+ import {
15
+ addressHasContent,
16
+ getSavedCheckoutAddress,
17
+ saveCheckoutAddress,
18
+ } from "../utilities/local_storage";
19
+
20
+ interface PropsAddress {
21
+ defaultAddress?: any;
22
+ labelGeoSuggest?: string;
23
+ hookForm: any;
24
+ name?: string;
25
+ placeholder?: string;
26
+ updateAddress: (address: any) => void;
27
+ }
28
+
29
+ const AddressGeoSuggestInput = (props: PropsAddress) => (
30
+ <InputsAddress {...props} name="receiverAddress" />
31
+ );
32
+
33
+ interface Props {
34
+ address?: any;
35
+ addressFieldsOpen: boolean;
36
+ formId: string;
37
+ notes?: string;
38
+ showIcon?: boolean;
39
+ deliveryNomenclature?: boolean;
40
+ showHeadings?: boolean;
41
+ setCartShipmentAddress: (values: any) => void | Promise<void>;
42
+ toggleAddressFields: () => void;
43
+ }
44
+
45
+ function FormShipmentAddressAndNotes({
46
+ address = {},
47
+ formId,
48
+ notes = "",
49
+ showIcon = true,
50
+ deliveryNomenclature = false,
51
+ showHeadings = true,
52
+ setCartShipmentAddress,
53
+ }: Props) {
54
+ const { classNameCartFormGroup, updateCartShipmentAddress } =
55
+ useCartContext();
56
+ const hookForm = useForm({
57
+ defaultValues: {
58
+ receiverAddress: address,
59
+ receiverNotes: notes,
60
+ },
61
+ });
62
+ const { getValues, handleSubmit, register, reset } = hookForm;
63
+
64
+ async function onSubmit() {
65
+ await setCartShipmentAddress(getValues());
66
+ }
67
+ function updateAddress(addr: any) {
68
+ const oldAddresses: any = getValues();
69
+ const newAddress = addr ? { ...addr } : {};
70
+ oldAddresses["receiverAddress"] = newAddress;
71
+ reset(oldAddresses);
72
+ updateCartShipmentAddress(newAddress);
73
+ }
74
+ return (
75
+ <form id={formId} onSubmit={handleSubmit(onSubmit)}>
76
+ {showHeadings && (
77
+ <CheckoutContainer>
78
+ <InnerContainer paddingBottom="0px">
79
+ <Title
80
+ icon={showIcon ? faMapMarkerAlt : null}
81
+ title="Delivery / billing address"
82
+ />
83
+ </InnerContainer>
84
+ </CheckoutContainer>
85
+ )}
86
+ <AddressGeoSuggestInput
87
+ defaultAddress={address}
88
+ hookForm={hookForm}
89
+ labelGeoSuggest={`Enter your ${
90
+ deliveryNomenclature ? "delivery" : "shipping"
91
+ } address`}
92
+ name="receiverAddress"
93
+ updateAddress={updateAddress}
94
+ />
95
+ <div className={classNameCartFormGroup}>
96
+ <label>{deliveryNomenclature ? "Delivery" : "Shipment"} notes</label>
97
+ <textarea
98
+ className="form-control input"
99
+ defaultValue={notes}
100
+ placeholder="Example - Leave at top of stairs"
101
+ rows={4}
102
+ {...register("receiverNotes")}
103
+ ></textarea>
104
+ </div>
105
+ </form>
106
+ );
107
+ }
108
+
109
+ export function ActiveFormShipmentAddressAndNotes() {
110
+ const {
111
+ alertError,
112
+ domainId,
113
+ cart,
114
+ setCart,
115
+ setLoadingTotals,
116
+ setActiveTabAndEditDisabled,
117
+ } = useCartContext();
118
+ const saved = getSavedCheckoutAddress(domainId);
119
+ const cartAddress = cart?.receiverAddress;
120
+ const receiverAddress = addressHasContent(cartAddress)
121
+ ? cartAddress
122
+ : saved.address || {};
123
+ const receiverNotes = cart?.receiverNotes || saved.receiverNotes || "";
124
+ const [addressFieldsOpen, setAddressFieldsOpen] = useState(false);
125
+
126
+ async function saveCartShipmentAddressAndGoToNextTab(values: any) {
127
+ const { receiverAddress: address, receiverNotes } = values;
128
+ setLoadingTotals(true);
129
+ try {
130
+ const cartToken = await getCartCookieToken(domainId as number);
131
+ // Never PATCH an existing Address via cart token — create a fresh embed.
132
+ const addressFields = sanitizeAddressFields(address);
133
+ const receiverAddress = makeAddress(addressFields, true);
134
+ const cartEnt = makeCart(cart, false, cartToken);
135
+ cartEnt.receiverAddress = receiverAddress;
136
+ cartEnt.receiverNotes = receiverNotes;
137
+ await cartEnt.save({ embed: cartEmbed });
138
+ saveCheckoutAddress(domainId, addressFields, receiverNotes);
139
+ setCart(cartEnt.toJson());
140
+ setActiveTabAndEditDisabled({
141
+ tabId: tabIdCheckout,
142
+ tabIndexToSet: 2,
143
+ disabled: false,
144
+ });
145
+ } catch (e: any) {
146
+ alertError(
147
+ e.errorMessage || e.message || "Unable to set shipment address."
148
+ );
149
+ } finally {
150
+ setLoadingTotals(false);
151
+ }
152
+ }
153
+ return (
154
+ <FormShipmentAddressAndNotes
155
+ address={receiverAddress}
156
+ addressFieldsOpen={addressFieldsOpen}
157
+ formId={shipmentFormId}
158
+ notes={receiverNotes}
159
+ setCartShipmentAddress={saveCartShipmentAddressAndGoToNextTab}
160
+ toggleAddressFields={() => setAddressFieldsOpen(!addressFieldsOpen)}
161
+ />
162
+ );
163
+ }
164
+
165
+ export default FormShipmentAddressAndNotes;
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { Suspense, lazy } from 'react';
3
+ import { useCartContext } from '../CartProvider';
4
+ import { LoadingTemplateSm } from '../components/LoadingTemplate';
5
+
6
+ const SquareCard = lazy(() => import('../square/SquareCard'));
7
+
8
+ function FormSquarePayment() {
9
+ const { cart } = useCartContext();
10
+ const company = cart && cart.domain && cart.domain.company;
11
+ if (!company?.acceptSquare) return null;
12
+ return (
13
+ <Suspense fallback={<LoadingTemplateSm />}>
14
+ <SquareCard />
15
+ </Suspense>
16
+ );
17
+ }
18
+
19
+ export default FormSquarePayment;
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { Suspense, lazy } from 'react';
3
+ import { useCartContext } from '../CartProvider';
4
+ import { LoadingTemplateSm } from '../components/LoadingTemplate';
5
+
6
+ const StripeCardForm = lazy(() => import('../stripe/StripeCardForm'));
7
+
8
+ function FormStripePayment() {
9
+ const { cart } = useCartContext();
10
+ const company = cart && cart.domain && cart.domain.company;
11
+ if (!company) return null;
12
+ return (
13
+ <Suspense fallback={<LoadingTemplateSm />}>
14
+ <StripeCardForm />
15
+ </Suspense>
16
+ );
17
+ }
18
+
19
+ export default FormStripePayment;
@@ -0,0 +1,179 @@
1
+ import * as React from 'react';
2
+ import { useForm } from 'react-hook-form';
3
+ import InputAcceptUserTermsAndConditions from './InputAcceptUserTermsAndConditions';
4
+ import { Button } from '../buttons';
5
+ import InputSelect from './InputSelect';
6
+ import InputText from './InputText';
7
+ import { useCartContext } from '../CartProvider';
8
+ import { cartEmbed, phoneOptions } from '../utilities/helpers';
9
+ import InputError from './InputError';
10
+ import { createNewCustomer, makeUser } from '../utilities/user';
11
+ import { makeCart } from '../utilities/cart';
12
+ import { getCartCookieToken } from '../utilities/cookie';
13
+ import {
14
+ getSavedCheckoutCustomer,
15
+ saveCheckoutCustomer,
16
+ } from '../utilities/local_storage';
17
+ import { emailValidation } from './FormNewCustomer';
18
+
19
+ function FormWhatsappCustomer() {
20
+ const {
21
+ cart,
22
+ classNameBtnPrimary,
23
+ classNameCartFormGroup,
24
+ classNameCartFormGroupButton,
25
+ domainId,
26
+ setCart,
27
+ setCartClient,
28
+ showUserTermsAndConditions,
29
+ } = useCartContext();
30
+ const [loading, setLoading] = React.useState(false);
31
+ const [error, setError] = React.useState(({} as any));
32
+ const [acceptConditions, setAcceptConditions] = React.useState(true);
33
+ const savedCustomer = getSavedCheckoutCustomer(domainId);
34
+
35
+ async function actionWhatsappCheckout(customerJson: any) {
36
+ setError({});
37
+ setLoading(true);
38
+ try {
39
+ const r = await createNewCustomer({
40
+ ...customerJson,
41
+ registeredUnderDomains: [{ id: domainId }],
42
+ });
43
+ const { user } = r;
44
+ if (!user?.id) {
45
+ throw new Error('Unable to create customer.');
46
+ }
47
+
48
+ const cartToken = await getCartCookieToken((domainId as number));
49
+ const clientEnt = makeUser({ id: user.id }, true);
50
+ const cartEnt = makeCart({ ...cart }, false, cartToken);
51
+ cartEnt.sendWhatsapp = true;
52
+ cartEnt.client = clientEnt;
53
+ const _cart = await cartEnt.save({ embed: cartEmbed });
54
+ const cartJson = _cart.toJson();
55
+ if (!cartJson?.client?.id) {
56
+ throw new Error('Unable to attach client to cart.');
57
+ }
58
+ saveCheckoutCustomer(domainId, {
59
+ id: user.id,
60
+ name: customerJson.name,
61
+ emailAddress: customerJson.emailAddresses?.[0]?.emailAddress,
62
+ phoneNumbers: customerJson.phoneNumbers,
63
+ });
64
+ setCartClient(cartJson.client);
65
+ setCart(cartJson);
66
+ } catch (e: any) {
67
+ setError({
68
+ message:
69
+ e.errorMessage || e.message || 'Unable to attach client to cart.',
70
+ });
71
+ } finally {
72
+ setLoading(false);
73
+ }
74
+ }
75
+
76
+ const { control, handleSubmit, watch } = useForm({
77
+ defaultValues: {
78
+ emailAddresses: [{
79
+ emailAddress: savedCustomer?.emailAddress || '',
80
+ }],
81
+ name: savedCustomer?.name || '',
82
+ phoneNumbers: [{
83
+ code: savedCustomer?.phoneNumbers?.[0]?.code || 'AU',
84
+ number: savedCustomer?.phoneNumbers?.[0]?.number || '',
85
+ }],
86
+ },
87
+ });
88
+
89
+ async function onSubmit(values: any) {
90
+ if (showUserTermsAndConditions && !acceptConditions) {
91
+ return;
92
+ }
93
+ await actionWhatsappCheckout({ ...values });
94
+ }
95
+
96
+ function validatePhone() {
97
+ const phone = watch('phoneNumbers.0.number');
98
+ if (!phone) return 'Phone number is required for WhatsApp checkout';
99
+ if (isNaN(phone as any)) return 'Phone number must be a number';
100
+ return true;
101
+ }
102
+
103
+ return (
104
+ <form onSubmit={handleSubmit(onSubmit)}>
105
+ <InputText
106
+ control={control}
107
+ label='Full Name'
108
+ name='name'
109
+ placeholder='John Smith'
110
+ rules={{ required: 'Full name is required.' }}
111
+ />
112
+ <InputText
113
+ control={control}
114
+ label='Email'
115
+ name='emailAddresses[0].emailAddress'
116
+ placeholder='john@example.com'
117
+ rules={{
118
+ required: 'Email is required.',
119
+ validate: emailValidation,
120
+ }}
121
+ />
122
+ <div style={{ display: 'flex', gap: '1rem' }}>
123
+ <div style={{ flexGrow: 1 }}>
124
+ <InputSelect
125
+ control={control}
126
+ label='Country Code'
127
+ name='phoneNumbers[0].code'
128
+ options={phoneOptions}
129
+ />
130
+ </div>
131
+ <div style={{ flexGrow: 1 }}>
132
+ <InputText
133
+ control={control}
134
+ label='WhatsApp Number'
135
+ name='phoneNumbers[0].number'
136
+ placeholder='0400 000 000'
137
+ rules={{
138
+ required: 'WhatsApp number is required',
139
+ validate: validatePhone,
140
+ }}
141
+ type='phone'
142
+ />
143
+ </div>
144
+ </div>
145
+ <small className={classNameCartFormGroup}>
146
+ By continuing, you agree to receive order updates via WhatsApp at this
147
+ number.
148
+ </small>
149
+ {showUserTermsAndConditions && (
150
+ <div className={classNameCartFormGroup}>
151
+ <InputAcceptUserTermsAndConditions
152
+ isChecked={acceptConditions}
153
+ setIsChecked={setAcceptConditions}
154
+ />
155
+ {!acceptConditions && (
156
+ <InputError
157
+ error={{
158
+ message:
159
+ 'You must agree to the user profile terms and conditions to proceed.',
160
+ }}
161
+ />
162
+ )}
163
+ </div>
164
+ )}
165
+ <InputError error={error || {}} />
166
+ <div className={classNameCartFormGroupButton}>
167
+ <Button
168
+ className={classNameBtnPrimary}
169
+ disabled={loading}
170
+ type='submit'
171
+ >
172
+ {loading ? 'Loading...' : 'Continue with WhatsApp'}
173
+ </Button>
174
+ </div>
175
+ </form>
176
+ );
177
+ }
178
+
179
+ export default FormWhatsappCustomer;