@anker-in/campaign-ui 0.4.8 → 0.5.0-beta.10

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 (233) hide show
  1. package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
  2. package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
  3. package/dist/cjs/components/credits/context/hooks/useCountries.js +1 -1
  4. package/dist/cjs/components/credits/context/hooks/useCountries.js.map +3 -3
  5. package/dist/cjs/components/index.d.ts +1 -0
  6. package/dist/cjs/components/index.js +1 -1
  7. package/dist/cjs/components/index.js.map +2 -2
  8. package/dist/cjs/components/memberPopup/MemberPopup.d.ts +9 -0
  9. package/dist/cjs/components/memberPopup/MemberPopup.js +2 -0
  10. package/dist/cjs/components/memberPopup/MemberPopup.js.map +7 -0
  11. package/dist/cjs/components/memberPopup/context/provider.d.ts +11 -0
  12. package/dist/cjs/components/memberPopup/context/provider.js +2 -0
  13. package/dist/cjs/components/memberPopup/context/provider.js.map +7 -0
  14. package/dist/cjs/components/memberPopup/context/viewStack.d.ts +12 -0
  15. package/dist/cjs/components/memberPopup/context/viewStack.js +2 -0
  16. package/dist/cjs/components/memberPopup/context/viewStack.js.map +7 -0
  17. package/dist/cjs/components/memberPopup/icons.d.ts +27 -0
  18. package/dist/cjs/components/memberPopup/icons.js +2 -0
  19. package/dist/cjs/components/memberPopup/icons.js.map +7 -0
  20. package/dist/cjs/components/memberPopup/index.d.ts +4 -0
  21. package/dist/cjs/components/memberPopup/index.js +2 -0
  22. package/dist/cjs/components/memberPopup/index.js.map +7 -0
  23. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +10 -0
  24. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js +2 -0
  25. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +7 -0
  26. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.d.ts +10 -0
  27. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js +2 -0
  28. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js.map +7 -0
  29. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +7 -0
  30. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +2 -0
  31. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +7 -0
  32. package/dist/cjs/components/memberPopup/panels/Activity/index.d.ts +7 -0
  33. package/dist/cjs/components/memberPopup/panels/Activity/index.js +2 -0
  34. package/dist/cjs/components/memberPopup/panels/Activity/index.js.map +7 -0
  35. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +19 -0
  36. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +2 -0
  37. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +7 -0
  38. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +21 -0
  39. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +2 -0
  40. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +7 -0
  41. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.d.ts +12 -0
  42. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.js +2 -0
  43. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.js.map +7 -0
  44. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.d.ts +17 -0
  45. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.js +2 -0
  46. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.js.map +7 -0
  47. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.d.ts +8 -0
  48. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.js +2 -0
  49. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.js.map +7 -0
  50. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.d.ts +7 -0
  51. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js +2 -0
  52. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js.map +7 -0
  53. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +8 -0
  54. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js +2 -0
  55. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +7 -0
  56. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.d.ts +11 -0
  57. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js +2 -0
  58. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js.map +7 -0
  59. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfileModal.d.ts +10 -0
  60. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js +2 -0
  61. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js.map +7 -0
  62. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +9 -0
  63. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +2 -0
  64. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +7 -0
  65. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +9 -0
  66. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +2 -0
  67. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +7 -0
  68. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +10 -0
  69. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js +2 -0
  70. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +7 -0
  71. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +9 -0
  72. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js +2 -0
  73. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +7 -0
  74. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useActivities.d.ts +18 -0
  75. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useActivities.js +2 -0
  76. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useActivities.js.map +7 -0
  77. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.d.ts +9 -0
  78. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.js +2 -0
  79. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.js.map +7 -0
  80. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.d.ts +17 -0
  81. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.js +2 -0
  82. package/dist/cjs/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.js.map +7 -0
  83. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.d.ts +13 -0
  84. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js +2 -0
  85. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js.map +7 -0
  86. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +13 -0
  87. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +2 -0
  88. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +7 -0
  89. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralOverview.d.ts +12 -0
  90. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralOverview.js +2 -0
  91. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralOverview.js.map +7 -0
  92. package/dist/cjs/components/memberPopup/panels/Referral/index.d.ts +7 -0
  93. package/dist/cjs/components/memberPopup/panels/Referral/index.js +2 -0
  94. package/dist/cjs/components/memberPopup/panels/Referral/index.js.map +7 -0
  95. package/dist/cjs/components/memberPopup/type.d.ts +231 -0
  96. package/dist/cjs/components/memberPopup/type.js +2 -0
  97. package/dist/cjs/components/memberPopup/type.js.map +7 -0
  98. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
  99. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
  100. package/dist/esm/components/credits/context/hooks/useCountries.js +1 -1
  101. package/dist/esm/components/credits/context/hooks/useCountries.js.map +3 -3
  102. package/dist/esm/components/index.d.ts +1 -0
  103. package/dist/esm/components/index.js +1 -1
  104. package/dist/esm/components/index.js.map +2 -2
  105. package/dist/esm/components/memberPopup/MemberPopup.d.ts +9 -0
  106. package/dist/esm/components/memberPopup/MemberPopup.js +2 -0
  107. package/dist/esm/components/memberPopup/MemberPopup.js.map +7 -0
  108. package/dist/esm/components/memberPopup/context/provider.d.ts +11 -0
  109. package/dist/esm/components/memberPopup/context/provider.js +2 -0
  110. package/dist/esm/components/memberPopup/context/provider.js.map +7 -0
  111. package/dist/esm/components/memberPopup/context/viewStack.d.ts +12 -0
  112. package/dist/esm/components/memberPopup/context/viewStack.js +2 -0
  113. package/dist/esm/components/memberPopup/context/viewStack.js.map +7 -0
  114. package/dist/esm/components/memberPopup/icons.d.ts +27 -0
  115. package/dist/esm/components/memberPopup/icons.js +2 -0
  116. package/dist/esm/components/memberPopup/icons.js.map +7 -0
  117. package/dist/esm/components/memberPopup/index.d.ts +4 -0
  118. package/dist/esm/components/memberPopup/index.js +2 -0
  119. package/dist/esm/components/memberPopup/index.js.map +7 -0
  120. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +10 -0
  121. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js +2 -0
  122. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +7 -0
  123. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.d.ts +10 -0
  124. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js +2 -0
  125. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js.map +7 -0
  126. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +7 -0
  127. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +2 -0
  128. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +7 -0
  129. package/dist/esm/components/memberPopup/panels/Activity/index.d.ts +7 -0
  130. package/dist/esm/components/memberPopup/panels/Activity/index.js +2 -0
  131. package/dist/esm/components/memberPopup/panels/Activity/index.js.map +7 -0
  132. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +19 -0
  133. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +2 -0
  134. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +7 -0
  135. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +21 -0
  136. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +2 -0
  137. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +7 -0
  138. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.d.ts +12 -0
  139. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.js +2 -0
  140. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.js.map +7 -0
  141. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.d.ts +17 -0
  142. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.js +2 -0
  143. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.js.map +7 -0
  144. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.d.ts +8 -0
  145. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.js +2 -0
  146. package/dist/esm/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.js.map +7 -0
  147. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.d.ts +7 -0
  148. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js +2 -0
  149. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js.map +7 -0
  150. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +8 -0
  151. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js +2 -0
  152. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +7 -0
  153. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.d.ts +11 -0
  154. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js +2 -0
  155. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js.map +7 -0
  156. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfileModal.d.ts +10 -0
  157. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js +2 -0
  158. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js.map +7 -0
  159. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +9 -0
  160. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +2 -0
  161. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +7 -0
  162. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +9 -0
  163. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +2 -0
  164. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +7 -0
  165. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +10 -0
  166. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js +2 -0
  167. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +7 -0
  168. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +9 -0
  169. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js +2 -0
  170. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +7 -0
  171. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useActivities.d.ts +18 -0
  172. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useActivities.js +2 -0
  173. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useActivities.js.map +7 -0
  174. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.d.ts +9 -0
  175. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.js +2 -0
  176. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.js.map +7 -0
  177. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.d.ts +17 -0
  178. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.js +2 -0
  179. package/dist/esm/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.js.map +7 -0
  180. package/dist/esm/components/memberPopup/panels/EarnCredits/index.d.ts +13 -0
  181. package/dist/esm/components/memberPopup/panels/EarnCredits/index.js +2 -0
  182. package/dist/esm/components/memberPopup/panels/EarnCredits/index.js.map +7 -0
  183. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +13 -0
  184. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +2 -0
  185. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +7 -0
  186. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralOverview.d.ts +12 -0
  187. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralOverview.js +2 -0
  188. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralOverview.js.map +7 -0
  189. package/dist/esm/components/memberPopup/panels/Referral/index.d.ts +7 -0
  190. package/dist/esm/components/memberPopup/panels/Referral/index.js +2 -0
  191. package/dist/esm/components/memberPopup/panels/Referral/index.js.map +7 -0
  192. package/dist/esm/components/memberPopup/type.d.ts +231 -0
  193. package/dist/esm/components/memberPopup/type.js +2 -0
  194. package/dist/esm/components/memberPopup/type.js.map +7 -0
  195. package/dist/index.d.mts +1775 -0
  196. package/dist/index.d.ts +1775 -0
  197. package/dist/index.js +18542 -0
  198. package/dist/index.js.map +1 -0
  199. package/dist/index.mjs +18514 -0
  200. package/dist/index.mjs.map +1 -0
  201. package/package.json +1 -1
  202. package/src/components/LiveChatWidget/components/MessageContent/TextBlock.tsx +5 -7
  203. package/src/components/credits/context/hooks/useCountries.ts +4 -15
  204. package/src/components/index.ts +2 -0
  205. package/src/components/memberPopup/MemberPopup.tsx +330 -0
  206. package/src/components/memberPopup/context/provider.tsx +52 -0
  207. package/src/components/memberPopup/context/viewStack.tsx +23 -0
  208. package/src/components/memberPopup/icons.tsx +147 -0
  209. package/src/components/memberPopup/index.ts +24 -0
  210. package/src/components/memberPopup/panels/ActivitiesSubscribePanel.tsx +194 -0
  211. package/src/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.tsx +175 -0
  212. package/src/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemAndBuy.ts +33 -0
  213. package/src/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemCoupon.ts +38 -0
  214. package/src/components/memberPopup/panels/ConsumeCredits/hooks/useRedeemableList.ts +55 -0
  215. package/src/components/memberPopup/panels/ConsumeCredits/index.tsx +291 -0
  216. package/src/components/memberPopup/panels/EarnCredits/ActivatePanel.tsx +323 -0
  217. package/src/components/memberPopup/panels/EarnCredits/CompleteProfileModal.tsx +191 -0
  218. package/src/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.tsx +184 -0
  219. package/src/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.tsx +130 -0
  220. package/src/components/memberPopup/panels/EarnCredits/hooks/useActivities.ts +64 -0
  221. package/src/components/memberPopup/panels/EarnCredits/hooks/useSubscribed.ts +32 -0
  222. package/src/components/memberPopup/panels/EarnCredits/hooks/useUpdateProfile.ts +50 -0
  223. package/src/components/memberPopup/panels/EarnCredits/index.tsx +245 -0
  224. package/src/components/memberPopup/panels/Referral/hooks/useReferralOverview.ts +41 -0
  225. package/src/components/memberPopup/panels/Referral/index.tsx +108 -0
  226. package/src/components/memberPopup/type.ts +242 -0
  227. package/tailwind.config.ts +4 -0
  228. package/dist/cjs/stories/CartCard.stories.d.ts +0 -33
  229. package/dist/cjs/stories/CartCard.stories.js +0 -21
  230. package/dist/cjs/stories/CartCard.stories.js.map +0 -7
  231. package/dist/esm/stories/CartCard.stories.d.ts +0 -33
  232. package/dist/esm/stories/CartCard.stories.js +0 -21
  233. package/dist/esm/stories/CartCard.stories.js.map +0 -7
@@ -0,0 +1,191 @@
1
+ import { useCallback, useEffect, useState } from 'react'
2
+ import { Button, Text } from '@anker-in/headless-ui'
3
+ import { classNames as cn } from '@anker-in/lib'
4
+ import { CreditsModalContainer } from '../../../credits/modal/ModalContainer'
5
+ import type { CompleteProfileCopy } from '../../type'
6
+ import { useUpdateProfile } from './hooks/useUpdateProfile'
7
+ import useCountries from '../../../credits/context/hooks/useCountries'
8
+ import { useMemberPopupContext } from '../../context/provider'
9
+
10
+ type Props = {
11
+ isOpen: boolean
12
+ onClose: () => void
13
+ onSuccess?: () => void
14
+ copy: CompleteProfileCopy
15
+ shopifyStoreDomain?: string
16
+ }
17
+
18
+ export function CompleteProfileModal({ isOpen, onClose, onSuccess, copy, shopifyStoreDomain = '' }: Props) {
19
+ const { profile, fetchCreditInfo, alpcConfig } = useMemberPopupContext()
20
+ const { locale } = alpcConfig
21
+
22
+ const [firstName, setFirstName] = useState('')
23
+ const [lastName, setLastName] = useState('')
24
+ const [phone, setPhone] = useState('')
25
+ const [birthDay, setBirthDay] = useState('')
26
+ const [country, setCountry] = useState('')
27
+ const [firstNameError, setFirstNameError] = useState('')
28
+ const [lastNameError, setLastNameError] = useState('')
29
+
30
+ const { updateProfile, isLoading } = useUpdateProfile({ locale, appName: alpcConfig.appName })
31
+ const { countries } = useCountries({ shopifyStoreDomain })
32
+
33
+ useEffect(() => {
34
+ if (profile) {
35
+ setFirstName(profile.first_name ?? '')
36
+ setLastName(profile.last_name ?? '')
37
+ setPhone(profile.phone_number ?? '')
38
+ setBirthDay(profile.dob ?? '')
39
+ setCountry(profile.country?.id ?? '')
40
+ }
41
+ }, [profile])
42
+
43
+ useEffect(() => {
44
+ if (countries.length > 0 && !country) {
45
+ setCountry(countries[0].id)
46
+ }
47
+ }, [countries])
48
+
49
+ const validate = useCallback(() => {
50
+ let hasError = false
51
+ if (!firstName.trim()) {
52
+ setFirstNameError(copy.required)
53
+ hasError = true
54
+ } else {
55
+ setFirstNameError('')
56
+ }
57
+ if (!lastName.trim()) {
58
+ setLastNameError(copy.required)
59
+ hasError = true
60
+ } else {
61
+ setLastNameError('')
62
+ }
63
+ return hasError
64
+ }, [firstName, lastName, copy.required])
65
+
66
+ const handleSubmit = useCallback(async () => {
67
+ if (validate()) return
68
+ const success = await updateProfile({
69
+ first_name: firstName.trim(),
70
+ last_name: lastName.trim(),
71
+ phone_number: phone,
72
+ country,
73
+ dob: birthDay,
74
+ })
75
+ if (success) {
76
+ fetchCreditInfo(profile?.user_id)
77
+ onSuccess?.()
78
+ onClose()
79
+ }
80
+ }, [validate, updateProfile, firstName, lastName, phone, country, birthDay, fetchCreditInfo, profile, onSuccess, onClose])
81
+
82
+ return (
83
+ <CreditsModalContainer
84
+ isOpen={isOpen}
85
+ onClose={onClose}
86
+ title={copy.title}
87
+ titleClassName="!h-auto !border-b-0 !pb-0"
88
+ className="w-[540px] md:h-auto"
89
+ useAnimation
90
+ animationClassName="md:translate-y-[100vh]"
91
+ >
92
+ <div className="flex flex-col gap-[20px]">
93
+ {copy.subtitle && (
94
+ <Text className="text-[14px] text-[#1d1d1f]" html={copy.subtitle} />
95
+ )}
96
+
97
+ <div>
98
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">{copy.email}</label>
99
+ <input
100
+ className="mt-[8px] h-[46px] w-full rounded-[4px] border border-[#d8d8d8] bg-[#f5f5f5] px-[12px] text-[14px] text-[#999]"
101
+ value={profile?.email ?? ''}
102
+ disabled
103
+ />
104
+ </div>
105
+
106
+ <div>
107
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">
108
+ {copy.firstName} <span className="text-[#f84d4f]">*</span>
109
+ </label>
110
+ <input
111
+ className={cn(
112
+ 'mt-[8px] h-[46px] w-full rounded-[4px] border px-[12px] text-[14px] outline-none',
113
+ firstNameError ? 'border-[#f84d4f]' : 'border-[#d8d8d8]'
114
+ )}
115
+ value={firstName}
116
+ onChange={e => { setFirstName(e.target.value); setFirstNameError('') }}
117
+ />
118
+ {firstNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={firstNameError} />}
119
+ </div>
120
+
121
+ <div>
122
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">
123
+ {copy.lastName} <span className="text-[#f84d4f]">*</span>
124
+ </label>
125
+ <input
126
+ className={cn(
127
+ 'mt-[8px] h-[46px] w-full rounded-[4px] border px-[12px] text-[14px] outline-none',
128
+ lastNameError ? 'border-[#f84d4f]' : 'border-[#d8d8d8]'
129
+ )}
130
+ value={lastName}
131
+ onChange={e => { setLastName(e.target.value); setLastNameError('') }}
132
+ />
133
+ {lastNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={lastNameError} />}
134
+ </div>
135
+
136
+ <div>
137
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">{copy.birthday}</label>
138
+ <input
139
+ className="mt-[8px] h-[46px] w-full rounded-[4px] border border-[#d8d8d8] px-[12px] text-[14px] outline-none"
140
+ type="date"
141
+ value={birthDay}
142
+ onChange={e => setBirthDay(e.target.value)}
143
+ />
144
+ </div>
145
+
146
+ <div>
147
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">{copy.phone}</label>
148
+ <input
149
+ className="mt-[8px] h-[46px] w-full rounded-[4px] border border-[#d8d8d8] px-[12px] text-[14px] outline-none"
150
+ value={phone}
151
+ onChange={e => setPhone(e.target.value)}
152
+ />
153
+ </div>
154
+
155
+ <div>
156
+ <label className="block text-[14px] font-semibold text-[#1d1d1f]">{copy.country}</label>
157
+ <select
158
+ className="mt-[8px] h-[46px] w-full rounded-[4px] border border-[#d8d8d8] px-[12px] text-[14px] outline-none"
159
+ value={country}
160
+ onChange={e => setCountry(e.target.value)}
161
+ >
162
+ {countries.map((c: { id: string; name: string }) => (
163
+ <option key={c.id} value={c.id}>{c.name}</option>
164
+ ))}
165
+ </select>
166
+ </div>
167
+
168
+ <div className="flex gap-[12px]">
169
+ <Button
170
+ variant="secondary"
171
+ size="lg"
172
+ className="flex-1"
173
+ onClick={onClose}
174
+ disabled={isLoading}
175
+ >
176
+ {copy.cancel}
177
+ </Button>
178
+ <Button
179
+ variant="primary"
180
+ size="lg"
181
+ className="flex-1"
182
+ loading={isLoading}
183
+ onClick={handleSubmit}
184
+ >
185
+ {copy.save}
186
+ </Button>
187
+ </div>
188
+ </div>
189
+ </CreditsModalContainer>
190
+ )
191
+ }
@@ -0,0 +1,184 @@
1
+ import { useCallback, useEffect, useState } from 'react'
2
+ import { Button, Text } from '@anker-in/headless-ui'
3
+ import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
4
+ import type { CompleteProfileCopy } from '../../type'
5
+ import { useUpdateProfile } from './hooks/useUpdateProfile'
6
+ import useCountries from '../../../credits/context/hooks/useCountries'
7
+ import { useMemberPopupContext } from '../../context/provider'
8
+ import { ROUNDED_BRANDS } from '../../../../constants'
9
+
10
+ type Props = {
11
+ copy: CompleteProfileCopy
12
+ shopifyStoreDomain?: string
13
+ onClose: () => void
14
+ onSuccess?: () => void
15
+ }
16
+
17
+ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', onClose, onSuccess }: Props) {
18
+ const { profile, fetchCreditInfo, alpcConfig } = useMemberPopupContext()
19
+ const { locale } = alpcConfig
20
+ const { brand } = useHeadlessContext()
21
+ const rounded = ROUNDED_BRANDS.includes(brand)
22
+
23
+ const [firstName, setFirstName] = useState('')
24
+ const [lastName, setLastName] = useState('')
25
+ const [phone, setPhone] = useState('')
26
+ const [birthDay, setBirthDay] = useState('')
27
+ const [country, setCountry] = useState('')
28
+ const [firstNameError, setFirstNameError] = useState('')
29
+ const [lastNameError, setLastNameError] = useState('')
30
+
31
+ const { updateProfile, isLoading } = useUpdateProfile({ locale, appName: alpcConfig.appName })
32
+ const { countries } = useCountries({ shopifyStoreDomain })
33
+
34
+ useEffect(() => {
35
+ if (profile) {
36
+ setFirstName(profile.first_name ?? '')
37
+ setLastName(profile.last_name ?? '')
38
+ setPhone(profile.phone_number ?? '')
39
+ setBirthDay(profile.dob ?? '')
40
+ setCountry(profile.country?.id ?? '')
41
+ }
42
+ }, [profile])
43
+
44
+ useEffect(() => {
45
+ if (countries.length > 0 && !country) {
46
+ setCountry(countries[0].id)
47
+ }
48
+ }, [countries])
49
+
50
+ const validate = useCallback(() => {
51
+ let hasError = false
52
+ if (!firstName.trim()) {
53
+ setFirstNameError(copy.required)
54
+ hasError = true
55
+ } else {
56
+ setFirstNameError('')
57
+ }
58
+ if (!lastName.trim()) {
59
+ setLastNameError(copy.required)
60
+ hasError = true
61
+ } else {
62
+ setLastNameError('')
63
+ }
64
+ return hasError
65
+ }, [firstName, lastName, copy.required])
66
+
67
+ const handleSubmit = useCallback(async () => {
68
+ if (validate()) return
69
+ const success = await updateProfile({
70
+ first_name: firstName.trim(),
71
+ last_name: lastName.trim(),
72
+ phone_number: phone,
73
+ country,
74
+ dob: birthDay,
75
+ })
76
+ if (success) {
77
+ fetchCreditInfo(profile?.user_id)
78
+ onSuccess?.()
79
+ onClose()
80
+ }
81
+ }, [validate, updateProfile, firstName, lastName, phone, country, birthDay, fetchCreditInfo, profile, onSuccess, onClose])
82
+
83
+ return (
84
+ <div className="flex flex-col gap-[20px]">
85
+ {copy.subtitle && (
86
+ <Text className="text-[14px] text-[#1d1d1f]" html={copy.subtitle} />
87
+ )}
88
+
89
+ <div>
90
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.email}</label>
91
+ <input
92
+ className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] bg-[#f5f5f5] px-[12px] text-[14px] text-[#999]', rounded ? 'rounded-[4px]' : 'rounded-none')}
93
+ value={profile?.email ?? ''}
94
+ disabled
95
+ />
96
+ </div>
97
+
98
+ <div>
99
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">
100
+ {copy.firstName} <span className="text-[#f84d4f]">*</span>
101
+ </label>
102
+ <input
103
+ className={cn(
104
+ 'mt-[8px] h-[46px] w-full border px-[12px] text-[14px] outline-none',
105
+ firstNameError ? 'border-[#f84d4f]' : 'border-[#d8d8d8]',
106
+ rounded ? 'rounded-[4px]' : 'rounded-none'
107
+ )}
108
+ value={firstName}
109
+ onChange={e => { setFirstName(e.target.value); setFirstNameError('') }}
110
+ />
111
+ {firstNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={firstNameError} />}
112
+ </div>
113
+
114
+ <div>
115
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">
116
+ {copy.lastName} <span className="text-[#f84d4f]">*</span>
117
+ </label>
118
+ <input
119
+ className={cn(
120
+ 'mt-[8px] h-[46px] w-full border px-[12px] text-[14px] outline-none',
121
+ lastNameError ? 'border-[#f84d4f]' : 'border-[#d8d8d8]',
122
+ rounded ? 'rounded-[4px]' : 'rounded-none'
123
+ )}
124
+ value={lastName}
125
+ onChange={e => { setLastName(e.target.value); setLastNameError('') }}
126
+ />
127
+ {lastNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={lastNameError} />}
128
+ </div>
129
+
130
+ <div>
131
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.birthday}</label>
132
+ <input
133
+ className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
134
+ type="date"
135
+ value={birthDay}
136
+ onChange={e => setBirthDay(e.target.value)}
137
+ />
138
+ </div>
139
+
140
+ <div>
141
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.phone}</label>
142
+ <input
143
+ className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
144
+ value={phone}
145
+ onChange={e => setPhone(e.target.value)}
146
+ />
147
+ </div>
148
+
149
+ <div>
150
+ <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.country}</label>
151
+ <select
152
+ className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
153
+ value={country}
154
+ onChange={e => setCountry(e.target.value)}
155
+ >
156
+ {countries.map((c: { id: string; name: string }) => (
157
+ <option key={c.id} value={c.id}>{c.name}</option>
158
+ ))}
159
+ </select>
160
+ </div>
161
+
162
+ <div className="flex gap-[12px]">
163
+ <Button
164
+ variant="secondary"
165
+ size="lg"
166
+ className="flex-1"
167
+ onClick={onClose}
168
+ disabled={isLoading}
169
+ >
170
+ {copy.cancel}
171
+ </Button>
172
+ <Button
173
+ variant="primary"
174
+ size="lg"
175
+ className="flex-1"
176
+ loading={isLoading}
177
+ onClick={handleSubmit}
178
+ >
179
+ {copy.save}
180
+ </Button>
181
+ </div>
182
+ </div>
183
+ )
184
+ }
@@ -0,0 +1,130 @@
1
+ import { useCallback, useEffect, useState } from 'react'
2
+ import { Checkbox, Text } from '@anker-in/headless-ui'
3
+ import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
4
+ import Cookies from 'js-cookie'
5
+ import { parse } from 'query-string'
6
+ import { emailValidate } from '../../../credits/context/utils'
7
+ import { useMemberPopupContext } from '../../context/provider'
8
+ import type { SubscribeModalCopy } from '../../type'
9
+ import { ROUNDED_BRANDS } from '../../../../constants'
10
+
11
+ type Props = {
12
+ copy: SubscribeModalCopy
13
+ email?: string
14
+ onClose: () => void
15
+ onSuccess?: () => void
16
+ }
17
+
18
+ function getAdCookie() {
19
+ if (typeof window === 'undefined') return { register_source: '' }
20
+ const { search, href } = window.location
21
+ const query = parse(search)
22
+ return {
23
+ fbuy_ref_code: Cookies.get('fbuy_ref_code'),
24
+ ref: Cookies.get('ref_ads'),
25
+ inviter_code: query.ic ?? query.inviter_code ?? Cookies.get('inviter_code'),
26
+ register_source: query.redirect ?? Cookies.get('reg_source') ?? href,
27
+ }
28
+ }
29
+
30
+ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose, onSuccess }: Props) {
31
+ const { alpcConfig } = useMemberPopupContext()
32
+ const { brand, locale } = alpcConfig
33
+ const { brand: headlessBrand } = useHeadlessContext()
34
+ const rounded = ROUNDED_BRANDS.includes(headlessBrand)
35
+ const [policy, setPolicy] = useState(false)
36
+ const [email, setEmail] = useState(initialEmail ?? '')
37
+ const [errorMessage, setErrorMessage] = useState('')
38
+ const [successMessage, setSuccessMessage] = useState('')
39
+ const [loading, setLoading] = useState(false)
40
+
41
+ useEffect(() => {
42
+ if (initialEmail) setEmail(initialEmail)
43
+ }, [initialEmail])
44
+
45
+ const handleSubmit = useCallback(async () => {
46
+ setErrorMessage('')
47
+ if (!email) return setErrorMessage('Please fill in your email')
48
+ if (!emailValidate(email)) return setErrorMessage('Invalid email address')
49
+ if (!policy) return setErrorMessage('Please agree to the policy')
50
+
51
+ setLoading(true)
52
+ const { register_source } = getAdCookie()
53
+ try {
54
+ const response = await fetch('/api/multipass/subscribe/subscribe_emails', {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json', 'current-language': locale },
57
+ body: JSON.stringify({
58
+ email,
59
+ register_source,
60
+ brand,
61
+ deals_type: copy.dealsType ?? 'vip_subscribe',
62
+ }),
63
+ })
64
+ const result = await response.json()
65
+ if (!result.errors) {
66
+ setSuccessMessage(copy.successTips ?? 'Subscribed successfully!')
67
+ onSuccess?.()
68
+ setTimeout(() => {
69
+ setSuccessMessage('')
70
+ onClose()
71
+ }, 3000)
72
+ } else {
73
+ setErrorMessage(result.errors ?? 'Error occurred')
74
+ }
75
+ } catch {
76
+ setErrorMessage('Network error')
77
+ } finally {
78
+ setLoading(false)
79
+ }
80
+ }, [email, policy, locale, brand, copy, onClose, onSuccess])
81
+
82
+ return (
83
+ <div className="flex flex-col gap-[12px]">
84
+ <div className="flex flex-col gap-[8px]">
85
+ {copy.title && (
86
+ <h2 className="text-[24px] font-[700] leading-[1.2] text-[#080a0f]">{copy.title}</h2>
87
+ )}
88
+ {copy.desc && (
89
+ <Text className="text-[16px] text-[#1e2024]" html={copy.desc} />
90
+ )}
91
+ </div>
92
+
93
+ <div className="flex flex-col gap-[16px]">
94
+ <input
95
+ className={cn(
96
+ 'h-[46px] w-full border px-[14px] text-[16px] outline-none placeholder:text-[#999]',
97
+ errorMessage ? 'border-[#f84d4f]' : 'border-[#d8d8d8]',
98
+ rounded ? 'rounded-[4px]' : 'rounded-none'
99
+ )}
100
+ placeholder={copy.placeholder}
101
+ value={email}
102
+ onChange={e => { setErrorMessage(''); setEmail(e.target.value.trim()) }}
103
+ />
104
+
105
+ <div className="flex w-full items-start gap-[8px]">
106
+ <Checkbox checked={policy} onCheckedChange={() => setPolicy(v => !v)} className="mt-[2px] border-[#1d1d1f]" />
107
+ <label
108
+ className="cursor-pointer text-left text-[14px] text-[#1e2024] [&_a]:underline"
109
+ onClick={() => setPolicy(v => !v)}
110
+ dangerouslySetInnerHTML={{ __html: copy.policy ?? '' }}
111
+ />
112
+ </div>
113
+
114
+ {(errorMessage || successMessage) && (
115
+ <div className={cn('text-[14px] font-[700]', errorMessage && 'text-[#f84d4f]', successMessage && 'text-[#52c41a]')}>
116
+ <Text html={successMessage || errorMessage} />
117
+ </div>
118
+ )}
119
+
120
+ <button
121
+ className={cn('w-full cursor-pointer bg-[#080a0f] py-[14px] text-[14px] font-[700] text-white disabled:opacity-60', rounded ? 'rounded-[4px]' : 'rounded-none')}
122
+ disabled={loading}
123
+ onClick={handleSubmit}
124
+ >
125
+ {copy.buttonLabel ?? 'Subscribe'}
126
+ </button>
127
+ </div>
128
+ </div>
129
+ )
130
+ }
@@ -0,0 +1,64 @@
1
+ import { useCallback, useEffect, useState } from 'react'
2
+ import useSWRMutation from 'swr/mutation'
3
+ import { getAlpcPath } from '../../../../credits/context/utils'
4
+ import type { CreditLogResponse } from '../../../../credits/context/response'
5
+
6
+ type UseActivitiesConfig = {
7
+ userId: string | undefined
8
+ brand: string
9
+ apiBaseUrl?: string
10
+ locale?: string
11
+ }
12
+
13
+ type Params = {
14
+ page: number
15
+ pageSize: number
16
+ }
17
+
18
+ function useActivities(
19
+ { userId, brand, apiBaseUrl, locale = '' }: UseActivitiesConfig,
20
+ { page, pageSize }: Params
21
+ ) {
22
+ const [activities, setActivities] = useState<CreditLogResponse[]>([])
23
+ const [total, setTotal] = useState(0)
24
+ const [currentPage, setCurrentPage] = useState(0)
25
+
26
+ const { isMutating: isLoading, trigger } = useSWRMutation(
27
+ `/v1/credit/log`,
28
+ async (url: string, { arg }: { arg: Record<string, any> }) => {
29
+ const response = await fetch(getAlpcPath(locale, apiBaseUrl) + url, {
30
+ method: 'POST',
31
+ headers: { 'Content-Type': 'application/json', 'current-language': locale },
32
+ body: JSON.stringify(arg),
33
+ })
34
+ return response.json()
35
+ }
36
+ )
37
+
38
+ const fetchActivities = useCallback(async () => {
39
+ await trigger(
40
+ { page, page_size: pageSize, user_id: userId, brand },
41
+ {
42
+ onSuccess(data) {
43
+ setCurrentPage(page)
44
+ setTotal(data?.data?.total ?? 0)
45
+ setActivities(prev => prev.concat(data?.data?.creditLogs ?? []))
46
+ },
47
+ }
48
+ )
49
+ }, [page, pageSize, userId, brand, trigger])
50
+
51
+ useEffect(() => {
52
+ if (!userId || !brand || isLoading || page === currentPage) return
53
+ fetchActivities()
54
+ }, [fetchActivities, userId, brand, page, currentPage, isLoading])
55
+
56
+ return {
57
+ activities,
58
+ isLoading,
59
+ total,
60
+ canNext: total > activities.length && !isLoading,
61
+ }
62
+ }
63
+
64
+ export default useActivities
@@ -0,0 +1,32 @@
1
+ import { useMemo } from 'react'
2
+ import { useSubscriptions } from '@anker-in/lib'
3
+ import { TaskSubType } from '../../../../credits/context/const'
4
+ import useActivities from './useActivities'
5
+
6
+ type UseSubscribedConfig = {
7
+ userId: string | undefined
8
+ brand: string
9
+ email: string | undefined
10
+ locale?: string
11
+ apiBaseUrl?: string
12
+ }
13
+
14
+ export function useSubscribed({ userId, brand, email, locale = '', apiBaseUrl }: UseSubscribedConfig) {
15
+ const { activities } = useActivities(
16
+ { userId, brand, apiBaseUrl, locale },
17
+ { page: 1, pageSize: 50 }
18
+ )
19
+ const { data: subscription } = useSubscriptions({ email })
20
+ const subscriptionData = subscription?.data || subscription
21
+
22
+ return useMemo(() => {
23
+ if (!subscriptionData?.preference) {
24
+ return false
25
+ }
26
+ const subscribedByPreference = subscriptionData.preference.some(
27
+ (item: any) => item.brand === brand && item.subscribe
28
+ )
29
+ if (subscribedByPreference) return true
30
+ return activities?.some(item => item.task_sub_type === TaskSubType.Subscription)
31
+ }, [subscriptionData?.preference, activities, brand])
32
+ }
@@ -0,0 +1,50 @@
1
+ import { useCallback, useState } from 'react'
2
+
3
+ type UseUpdateProfileConfig = {
4
+ locale?: string
5
+ appName?: string
6
+ }
7
+
8
+ type ProfileData = {
9
+ first_name?: string
10
+ last_name?: string
11
+ phone_number?: string
12
+ country?: string
13
+ dob?: string
14
+ }
15
+
16
+ export function useUpdateProfile({ locale = '', appName = '' }: UseUpdateProfileConfig = {}) {
17
+ const [isLoading, setIsLoading] = useState(false)
18
+ const [error, setError] = useState<string | null>(null)
19
+
20
+ const updateProfile = useCallback(
21
+ async (data: ProfileData): Promise<boolean> => {
22
+ setIsLoading(true)
23
+ setError(null)
24
+ try {
25
+ const response = await fetch('/api/multipass/account/users/update_profile', {
26
+ method: 'PUT',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ 'current-language': locale,
30
+ },
31
+ body: JSON.stringify({ app: appName, ...data }),
32
+ })
33
+ const result = await response.json()
34
+ if (response.ok && !result.error) {
35
+ return true
36
+ }
37
+ setError(result?.error?.message || result?.error || 'Update failed')
38
+ return false
39
+ } catch (e: any) {
40
+ setError(e?.message ?? 'Unknown error')
41
+ return false
42
+ } finally {
43
+ setIsLoading(false)
44
+ }
45
+ },
46
+ [locale, appName]
47
+ )
48
+
49
+ return { updateProfile, isLoading, error }
50
+ }