@anker-in/campaign-ui 0.5.0-beta.8 → 0.5.0

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 (158) 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/useShippingCountries.d.ts +8 -0
  4. package/dist/cjs/components/credits/context/hooks/useShippingCountries.js +2 -0
  5. package/dist/cjs/components/credits/context/hooks/useShippingCountries.js.map +7 -0
  6. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
  7. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +3 -3
  8. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/index.js +1 -1
  9. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/index.js.map +3 -3
  10. package/dist/cjs/components/memberPopup/MemberPopup.d.ts +1 -1
  11. package/dist/cjs/components/memberPopup/MemberPopup.js +1 -1
  12. package/dist/cjs/components/memberPopup/MemberPopup.js.map +3 -3
  13. package/dist/cjs/components/memberPopup/context/provider.d.ts +3 -3
  14. package/dist/cjs/components/memberPopup/context/provider.js +1 -1
  15. package/dist/cjs/components/memberPopup/context/provider.js.map +3 -3
  16. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +1 -4
  17. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js +1 -1
  18. package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +3 -3
  19. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +8 -7
  20. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +1 -1
  21. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +3 -3
  22. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.d.ts +1 -2
  23. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js +1 -1
  24. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js.map +3 -3
  25. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +1 -2
  26. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js +1 -1
  27. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +3 -3
  28. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +1 -3
  29. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +1 -1
  30. package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +3 -3
  31. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +1 -2
  32. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +1 -1
  33. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +3 -3
  34. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.d.ts +1 -8
  35. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js +1 -1
  36. package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js.map +3 -3
  37. package/dist/cjs/components/memberPopup/panels/Referral/index.js +1 -1
  38. package/dist/cjs/components/memberPopup/panels/Referral/index.js.map +3 -3
  39. package/dist/cjs/components/memberPopup/type.d.ts +19 -2
  40. package/dist/cjs/components/memberPopup/type.js +1 -1
  41. package/dist/cjs/components/memberPopup/type.js.map +1 -1
  42. package/dist/cjs/templates/Credits.js +1 -1
  43. package/dist/cjs/templates/Credits.js.map +3 -3
  44. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
  45. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
  46. package/dist/esm/components/credits/context/hooks/useShippingCountries.d.ts +8 -0
  47. package/dist/esm/components/credits/context/hooks/useShippingCountries.js +2 -0
  48. package/dist/esm/components/credits/context/hooks/useShippingCountries.js.map +7 -0
  49. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
  50. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +3 -3
  51. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/index.js +1 -1
  52. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/index.js.map +3 -3
  53. package/dist/esm/components/memberPopup/MemberPopup.d.ts +1 -1
  54. package/dist/esm/components/memberPopup/MemberPopup.js +1 -1
  55. package/dist/esm/components/memberPopup/MemberPopup.js.map +3 -3
  56. package/dist/esm/components/memberPopup/context/provider.d.ts +3 -3
  57. package/dist/esm/components/memberPopup/context/provider.js +1 -1
  58. package/dist/esm/components/memberPopup/context/provider.js.map +3 -3
  59. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +1 -4
  60. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js +1 -1
  61. package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +3 -3
  62. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +8 -7
  63. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +1 -1
  64. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +3 -3
  65. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.d.ts +1 -2
  66. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js +1 -1
  67. package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js.map +3 -3
  68. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +1 -2
  69. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js +1 -1
  70. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +3 -3
  71. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +1 -3
  72. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +1 -1
  73. package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +3 -3
  74. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +1 -2
  75. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +1 -1
  76. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +3 -3
  77. package/dist/esm/components/memberPopup/panels/EarnCredits/index.d.ts +1 -8
  78. package/dist/esm/components/memberPopup/panels/EarnCredits/index.js +1 -1
  79. package/dist/esm/components/memberPopup/panels/EarnCredits/index.js.map +3 -3
  80. package/dist/esm/components/memberPopup/panels/Referral/index.js +1 -1
  81. package/dist/esm/components/memberPopup/panels/Referral/index.js.map +3 -3
  82. package/dist/esm/components/memberPopup/type.d.ts +19 -2
  83. package/dist/esm/components/memberPopup/type.js +1 -1
  84. package/dist/esm/components/memberPopup/type.js.map +1 -1
  85. package/dist/esm/templates/Credits.js +1 -1
  86. package/dist/esm/templates/Credits.js.map +3 -3
  87. package/package.json +2 -1
  88. package/src/components/LiveChatWidget/components/MessageContent/TextBlock.tsx +7 -5
  89. package/src/components/credits/context/hooks/useShippingCountries.ts +60 -0
  90. package/src/components/credits/creditsRedeemList/RedeemProductModal/Address.tsx +2 -2
  91. package/src/components/credits/creditsRedeemList/RedeemProductModal/index.tsx +2 -2
  92. package/src/components/memberPopup/MemberPopup.tsx +166 -178
  93. package/src/components/memberPopup/context/provider.tsx +24 -4
  94. package/src/components/memberPopup/panels/ActivitiesSubscribePanel.tsx +66 -73
  95. package/src/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.tsx +38 -55
  96. package/src/components/memberPopup/panels/ConsumeCredits/index.tsx +210 -105
  97. package/src/components/memberPopup/panels/EarnCredits/ActivatePanel.tsx +32 -16
  98. package/src/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.tsx +60 -35
  99. package/src/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.tsx +32 -22
  100. package/src/components/memberPopup/panels/EarnCredits/index.tsx +56 -49
  101. package/src/components/memberPopup/panels/Referral/index.tsx +40 -22
  102. package/src/components/memberPopup/type.ts +20 -3
  103. package/src/templates/Credits.tsx +25 -0
  104. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.d.ts +0 -10
  105. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js +0 -2
  106. package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js.map +0 -7
  107. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +0 -7
  108. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +0 -2
  109. package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +0 -7
  110. package/dist/cjs/components/memberPopup/panels/Activity/index.d.ts +0 -7
  111. package/dist/cjs/components/memberPopup/panels/Activity/index.js +0 -2
  112. package/dist/cjs/components/memberPopup/panels/Activity/index.js.map +0 -7
  113. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +0 -19
  114. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +0 -2
  115. package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +0 -7
  116. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.d.ts +0 -11
  117. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js +0 -2
  118. package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js.map +0 -7
  119. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +0 -10
  120. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js +0 -2
  121. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +0 -7
  122. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +0 -9
  123. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js +0 -2
  124. package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +0 -7
  125. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +0 -13
  126. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +0 -2
  127. package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +0 -7
  128. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.d.ts +0 -10
  129. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js +0 -2
  130. package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js.map +0 -7
  131. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +0 -7
  132. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +0 -2
  133. package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +0 -7
  134. package/dist/esm/components/memberPopup/panels/Activity/index.d.ts +0 -7
  135. package/dist/esm/components/memberPopup/panels/Activity/index.js +0 -2
  136. package/dist/esm/components/memberPopup/panels/Activity/index.js.map +0 -7
  137. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +0 -19
  138. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +0 -2
  139. package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +0 -7
  140. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.d.ts +0 -11
  141. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js +0 -2
  142. package/dist/esm/components/memberPopup/panels/EarnCredits/ActivitiesSubscribePanel.js.map +0 -7
  143. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +0 -10
  144. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js +0 -2
  145. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +0 -7
  146. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +0 -9
  147. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js +0 -2
  148. package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +0 -7
  149. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +0 -13
  150. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +0 -2
  151. package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +0 -7
  152. package/dist/index.d.mts +0 -1775
  153. package/dist/index.d.ts +0 -1775
  154. package/dist/index.js +0 -18542
  155. package/dist/index.js.map +0 -1
  156. package/dist/index.mjs +0 -18514
  157. package/dist/index.mjs.map +0 -1
  158. package/src/components/memberPopup/panels/EarnCredits/CompleteProfileModal.tsx +0 -191
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useEffect, useState } from 'react'
2
2
  import { Button, Text } from '@anker-in/headless-ui'
3
- import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
3
+ import { gaTrack, classNames as cn, useHeadlessContext } from '@anker-in/lib'
4
4
  import type { CompleteProfileCopy } from '../../type'
5
5
  import { useUpdateProfile } from './hooks/useUpdateProfile'
6
6
  import useCountries from '../../../credits/context/hooks/useCountries'
@@ -9,15 +9,13 @@ import { ROUNDED_BRANDS } from '../../../../constants'
9
9
 
10
10
  type Props = {
11
11
  copy: CompleteProfileCopy
12
- shopifyStoreDomain?: string
13
12
  onClose: () => void
14
- onSuccess?: () => void
15
13
  }
16
14
 
17
- export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', onClose, onSuccess }: Props) {
18
- const { profile, fetchCreditInfo, alpcConfig } = useMemberPopupContext()
15
+ export default function CompleteProfilePanel({ copy, onClose }: Props) {
16
+ const { profile, fetchCreditInfo, alpcConfig, setIsProfileCompleteSuccess } = useMemberPopupContext()
19
17
  const { locale } = alpcConfig
20
- const { brand } = useHeadlessContext()
18
+ const { brand, storeDomain } = useHeadlessContext()
21
19
  const rounded = ROUNDED_BRANDS.includes(brand)
22
20
 
23
21
  const [firstName, setFirstName] = useState('')
@@ -29,7 +27,7 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
29
27
  const [lastNameError, setLastNameError] = useState('')
30
28
 
31
29
  const { updateProfile, isLoading } = useUpdateProfile({ locale, appName: alpcConfig.appName })
32
- const { countries } = useCountries({ shopifyStoreDomain })
30
+ const { countries } = useCountries({ shopifyStoreDomain: storeDomain })
33
31
 
34
32
  useEffect(() => {
35
33
  if (profile) {
@@ -74,22 +72,44 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
74
72
  dob: birthDay,
75
73
  })
76
74
  if (success) {
77
- fetchCreditInfo(profile?.user_id)
78
- onSuccess?.()
75
+ setTimeout(() => fetchCreditInfo(profile?.user_id), 3000)
76
+ setIsProfileCompleteSuccess(true)
77
+ gaTrack({
78
+ event: 'ga4Event',
79
+ event_name: 'lp_button',
80
+ event_parameters: {
81
+ position: 'earn_credits',
82
+ button_name: 'complete_profile_success',
83
+ info: 'Member Floating Window',
84
+ },
85
+ })
79
86
  onClose()
80
87
  }
81
- }, [validate, updateProfile, firstName, lastName, phone, country, birthDay, fetchCreditInfo, profile, onSuccess, onClose])
88
+ }, [
89
+ validate,
90
+ updateProfile,
91
+ firstName,
92
+ lastName,
93
+ phone,
94
+ country,
95
+ birthDay,
96
+ fetchCreditInfo,
97
+ profile,
98
+ setIsProfileCompleteSuccess,
99
+ onClose,
100
+ ])
82
101
 
83
102
  return (
84
- <div className="flex flex-col gap-[20px]">
85
- {copy.subtitle && (
86
- <Text className="text-[14px] text-[#1d1d1f]" html={copy.subtitle} />
87
- )}
103
+ <div className="flex flex-col gap-[16px]">
104
+ {copy.subtitle && <Text className="text-[14px] text-[#1d1d1f]" html={copy.subtitle} />}
88
105
 
89
106
  <div>
90
107
  <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.email}</label>
91
108
  <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')}
109
+ className={cn(
110
+ 'mt-[8px] h-[46px] w-full border border-[#d8d8d8] bg-[#f5f5f5] px-[12px] text-[14px] text-[#999]',
111
+ rounded ? 'rounded-[4px]' : 'rounded-none'
112
+ )}
93
113
  value={profile?.email ?? ''}
94
114
  disabled
95
115
  />
@@ -106,7 +126,10 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
106
126
  rounded ? 'rounded-[4px]' : 'rounded-none'
107
127
  )}
108
128
  value={firstName}
109
- onChange={e => { setFirstName(e.target.value); setFirstNameError('') }}
129
+ onChange={e => {
130
+ setFirstName(e.target.value)
131
+ setFirstNameError('')
132
+ }}
110
133
  />
111
134
  {firstNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={firstNameError} />}
112
135
  </div>
@@ -122,7 +145,10 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
122
145
  rounded ? 'rounded-[4px]' : 'rounded-none'
123
146
  )}
124
147
  value={lastName}
125
- onChange={e => { setLastName(e.target.value); setLastNameError('') }}
148
+ onChange={e => {
149
+ setLastName(e.target.value)
150
+ setLastNameError('')
151
+ }}
126
152
  />
127
153
  {lastNameError && <Text className="mt-[4px] text-[12px] text-[#f84d4f]" html={lastNameError} />}
128
154
  </div>
@@ -130,7 +156,10 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
130
156
  <div>
131
157
  <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.birthday}</label>
132
158
  <input
133
- className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
159
+ className={cn(
160
+ 'mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none',
161
+ rounded ? 'rounded-[4px]' : 'rounded-none'
162
+ )}
134
163
  type="date"
135
164
  value={birthDay}
136
165
  onChange={e => setBirthDay(e.target.value)}
@@ -140,7 +169,10 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
140
169
  <div>
141
170
  <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.phone}</label>
142
171
  <input
143
- className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
172
+ className={cn(
173
+ 'mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none',
174
+ rounded ? 'rounded-[4px]' : 'rounded-none'
175
+ )}
144
176
  value={phone}
145
177
  onChange={e => setPhone(e.target.value)}
146
178
  />
@@ -149,33 +181,26 @@ export default function CompleteProfilePanel({ copy, shopifyStoreDomain = '', on
149
181
  <div>
150
182
  <label className="block text-[14px] font-[700] text-[#1d1d1f]">{copy.country}</label>
151
183
  <select
152
- className={cn('mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none', rounded ? 'rounded-[4px]' : 'rounded-none')}
184
+ className={cn(
185
+ 'mt-[8px] h-[46px] w-full border border-[#d8d8d8] px-[12px] text-[14px] outline-none',
186
+ rounded ? 'rounded-[4px]' : 'rounded-none'
187
+ )}
153
188
  value={country}
154
189
  onChange={e => setCountry(e.target.value)}
155
190
  >
156
191
  {countries.map((c: { id: string; name: string }) => (
157
- <option key={c.id} value={c.id}>{c.name}</option>
192
+ <option key={c.id} value={c.id}>
193
+ {c.name}
194
+ </option>
158
195
  ))}
159
196
  </select>
160
197
  </div>
161
198
 
162
199
  <div className="flex gap-[12px]">
163
- <Button
164
- variant="secondary"
165
- size="lg"
166
- className="flex-1"
167
- onClick={onClose}
168
- disabled={isLoading}
169
- >
200
+ <Button variant="secondary" size="base" className="flex-1" onClick={onClose} disabled={isLoading}>
170
201
  {copy.cancel}
171
202
  </Button>
172
- <Button
173
- variant="primary"
174
- size="lg"
175
- className="flex-1"
176
- loading={isLoading}
177
- onClick={handleSubmit}
178
- >
203
+ <Button variant="primary" size="base" className="flex-1" loading={isLoading} onClick={handleSubmit}>
179
204
  {copy.save}
180
205
  </Button>
181
206
  </div>
@@ -1,6 +1,6 @@
1
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'
2
+ import { Button, Checkbox, Text } from '@anker-in/headless-ui'
3
+ import { gaTrack, classNames as cn, useHeadlessContext } from '@anker-in/lib'
4
4
  import Cookies from 'js-cookie'
5
5
  import { parse } from 'query-string'
6
6
  import { emailValidate } from '../../../credits/context/utils'
@@ -12,7 +12,6 @@ type Props = {
12
12
  copy: SubscribeModalCopy
13
13
  email?: string
14
14
  onClose: () => void
15
- onSuccess?: () => void
16
15
  }
17
16
 
18
17
  function getAdCookie() {
@@ -27,12 +26,12 @@ function getAdCookie() {
27
26
  }
28
27
  }
29
28
 
30
- export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose, onSuccess }: Props) {
31
- const { alpcConfig } = useMemberPopupContext()
29
+ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose }: Props) {
30
+ const { alpcConfig, setIsSubscribeSuccess, fetchCreditInfo, profile } = useMemberPopupContext()
32
31
  const { brand, locale } = alpcConfig
33
32
  const { brand: headlessBrand } = useHeadlessContext()
34
33
  const rounded = ROUNDED_BRANDS.includes(headlessBrand)
35
- const [policy, setPolicy] = useState(false)
34
+ const [policy, setPolicy] = useState(copy.policyDefaultChecked ?? false)
36
35
  const [email, setEmail] = useState(initialEmail ?? '')
37
36
  const [errorMessage, setErrorMessage] = useState('')
38
37
  const [successMessage, setSuccessMessage] = useState('')
@@ -64,7 +63,17 @@ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose
64
63
  const result = await response.json()
65
64
  if (!result.errors) {
66
65
  setSuccessMessage(copy.successTips ?? 'Subscribed successfully!')
67
- onSuccess?.()
66
+ setIsSubscribeSuccess(true)
67
+ if (profile?.user_id) setTimeout(() => fetchCreditInfo(profile.user_id), 3000)
68
+ gaTrack({
69
+ event: 'ga4Event',
70
+ event_name: 'subscribe',
71
+ event_parameters: {
72
+ page_group: copy.dealsType ?? '',
73
+ position: 'sticky',
74
+ info: '',
75
+ },
76
+ })
68
77
  setTimeout(() => {
69
78
  setSuccessMessage('')
70
79
  onClose()
@@ -77,17 +86,13 @@ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose
77
86
  } finally {
78
87
  setLoading(false)
79
88
  }
80
- }, [email, policy, locale, brand, copy, onClose, onSuccess])
89
+ }, [email, policy, locale, brand, copy, onClose, setIsSubscribeSuccess])
81
90
 
82
91
  return (
83
92
  <div className="flex flex-col gap-[12px]">
84
93
  <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
- )}
94
+ {copy.title && <h2 className="text-[24px] font-[700] leading-[1.2] text-[#080a0f]">{copy.title}</h2>}
95
+ {copy.desc && <Text className="text-[16px] text-[#1e2024]" html={copy.desc} />}
91
96
  </div>
92
97
 
93
98
  <div className="flex flex-col gap-[16px]">
@@ -99,7 +104,10 @@ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose
99
104
  )}
100
105
  placeholder={copy.placeholder}
101
106
  value={email}
102
- onChange={e => { setErrorMessage(''); setEmail(e.target.value.trim()) }}
107
+ onChange={e => {
108
+ setErrorMessage('')
109
+ setEmail(e.target.value.trim())
110
+ }}
103
111
  />
104
112
 
105
113
  <div className="flex w-full items-start gap-[8px]">
@@ -112,18 +120,20 @@ export default function SubscribeEmailPanel({ copy, email: initialEmail, onClose
112
120
  </div>
113
121
 
114
122
  {(errorMessage || successMessage) && (
115
- <div className={cn('text-[14px] font-[700]', errorMessage && 'text-[#f84d4f]', successMessage && 'text-[#52c41a]')}>
123
+ <div
124
+ className={cn(
125
+ 'text-[14px] font-[700]',
126
+ errorMessage && 'text-[#f84d4f]',
127
+ successMessage && 'text-[#52c41a]'
128
+ )}
129
+ >
116
130
  <Text html={successMessage || errorMessage} />
117
131
  </div>
118
132
  )}
119
133
 
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
- >
134
+ <Button className="w-full" loading={loading} onClick={handleSubmit}>
125
135
  {copy.buttonLabel ?? 'Subscribe'}
126
- </button>
136
+ </Button>
127
137
  </div>
128
138
  </div>
129
139
  )
@@ -1,5 +1,5 @@
1
- import { useMemo } from 'react'
2
- import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
1
+ import { useEffect, useMemo } from 'react'
2
+ import { gaTrack, classNames as cn, useHeadlessContext } from '@anker-in/lib'
3
3
  import { useMemberPopupContext } from '../../context/provider'
4
4
  import { useViewStack } from '../../context/viewStack'
5
5
  import { useSubscribed } from './hooks/useSubscribed'
@@ -7,6 +7,7 @@ import { EarnCreditsTaskType, MemberPopupPanelType, type EarnCreditsCopy } from
7
7
  import { IconBag, IconLock, IconSubscription, IconOrders } from '../../icons'
8
8
  import { numberFormat } from '../../../credits/context/utils'
9
9
  import { ROUNDED_BRANDS } from '../../../../constants'
10
+ import { Button } from '@anker-in/headless-ui'
10
11
 
11
12
  function TaskIcon({ id, className }: { id: EarnCreditsTaskType; className?: string }) {
12
13
  switch (id) {
@@ -23,32 +24,27 @@ function TaskIcon({ id, className }: { id: EarnCreditsTaskType; className?: stri
23
24
 
24
25
  type Props = {
25
26
  copy: EarnCreditsCopy
26
- onClose: () => void
27
- isSubscribeSuccess?: boolean
28
- isActivateSuccess?: boolean
29
- isProfileCompleteSuccess?: boolean
30
- onSubscribeSuccess?: () => void
31
- onActivateSuccess?: () => void
32
- onProfileCompleteSuccess?: () => void
33
27
  }
34
28
 
35
- function EarnCredits({
36
- copy,
37
- onClose,
38
- isSubscribeSuccess = false,
39
- isActivateSuccess = false,
40
- isProfileCompleteSuccess = false,
41
- onSubscribeSuccess,
42
- onActivateSuccess,
43
- onProfileCompleteSuccess,
44
- }: Props) {
45
- const { profile, openSignUpPopup, alpcConfig, creditInfo } = useMemberPopupContext()
29
+ function EarnCredits({ copy }: Props) {
30
+ const {
31
+ profile,
32
+ openSignUpPopup,
33
+ alpcConfig,
34
+ creditInfo,
35
+ fetchCreditInfo,
36
+ isSubscribeSuccess,
37
+ isActivateSuccess,
38
+ isProfileCompleteSuccess,
39
+ } = useMemberPopupContext()
46
40
  const { pushView } = useViewStack()
47
41
  const { locale } = alpcConfig
48
42
  const { brand } = useHeadlessContext()
49
43
  const rounded = ROUNDED_BRANDS.includes(brand)
50
44
 
51
- console.log('creditInfo', creditInfo)
45
+ useEffect(() => {
46
+ if (profile?.user_id) fetchCreditInfo(profile.user_id)
47
+ }, [])
52
48
 
53
49
  const isLogin = !!profile
54
50
 
@@ -67,42 +63,63 @@ function EarnCredits({
67
63
  )
68
64
  }, [profile, isProfileCompleteSuccess])
69
65
 
66
+ function trackTaskButton(taskId: EarnCreditsTaskType) {
67
+ const taskButtonNameMap: Record<EarnCreditsTaskType, string> = {
68
+ [EarnCreditsTaskType.Activate]: 'activate',
69
+ [EarnCreditsTaskType.CompleteProfile]: 'complete_profile',
70
+ [EarnCreditsTaskType.Subscribe]: 'subscribe',
71
+ [EarnCreditsTaskType.Shop]: 'shop',
72
+ }
73
+ gaTrack({
74
+ event: 'ga4Event',
75
+ event_name: 'lp_button',
76
+ event_parameters: {
77
+ position: 'earn_credits',
78
+ button_name: taskButtonNameMap[taskId],
79
+ info: 'Member Floating Window',
80
+ },
81
+ })
82
+ }
83
+
70
84
  const taskStates: Record<EarnCreditsTaskType, { finished: boolean; onClick?: () => void; link?: string }> = useMemo(
71
85
  () => ({
72
86
  [EarnCreditsTaskType.Activate]: {
73
87
  finished: !!profile?.activated || isActivateSuccess,
74
88
  onClick: isLogin
75
- ? () =>
89
+ ? () => {
90
+ trackTaskButton(EarnCreditsTaskType.Activate)
76
91
  pushView({
77
92
  type: MemberPopupPanelType.Activate,
78
- props: { onSuccess: onActivateSuccess },
79
93
  })
94
+ }
80
95
  : openSignUpPopup,
81
96
  },
82
97
  [EarnCreditsTaskType.CompleteProfile]: {
83
98
  finished: profileCompleted,
84
99
  onClick: isLogin
85
- ? () =>
100
+ ? () => {
101
+ trackTaskButton(EarnCreditsTaskType.CompleteProfile)
86
102
  pushView({
87
103
  type: MemberPopupPanelType.CompleteProfile,
88
- props: { onSuccess: onProfileCompleteSuccess },
89
104
  })
105
+ }
90
106
  : openSignUpPopup,
91
107
  },
92
108
  [EarnCreditsTaskType.Subscribe]: {
93
109
  finished: isSubscribed || isSubscribeSuccess,
94
110
  onClick: isLogin
95
- ? () =>
111
+ ? () => {
112
+ trackTaskButton(EarnCreditsTaskType.Subscribe)
96
113
  pushView({
97
114
  type: MemberPopupPanelType.SubscribeEmail,
98
- props: { onSuccess: onSubscribeSuccess },
99
115
  })
116
+ }
100
117
  : openSignUpPopup,
101
118
  },
102
119
  [EarnCreditsTaskType.Shop]: {
103
120
  finished: false,
104
121
  link: copy.goShopLink,
105
- onClick: isLogin ? undefined : openSignUpPopup,
122
+ onClick: isLogin ? () => trackTaskButton(EarnCreditsTaskType.Shop) : openSignUpPopup,
106
123
  },
107
124
  }),
108
125
  [
@@ -187,38 +204,28 @@ function EarnCredits({
187
204
  {list.map((item, idx) => (
188
205
  <div key={idx} className="relative py-[16px]">
189
206
  {idx > 0 && <div className="absolute left-0 right-0 top-0 h-px bg-[#dadce0]" />}
190
- <div className={cn('flex items-center gap-[12px]', item.finished && 'opacity-60')}>
207
+ <div className={cn('flex items-center gap-[12px]')}>
191
208
  <TaskIcon id={item.id} className="size-[24px] shrink-0" />
192
209
  <div className="flex-1">
193
210
  <div className="text-[16px] font-[700] text-[#1e2024]">{item.title}</div>
194
- {item.description && (
195
- <div className="mt-[4px] text-[14px] font-[700] text-[#4a4c56]">{item.description}</div>
196
- )}
211
+ {item.credits && <div className="mt-[4px] text-[14px] font-bold text-[#4A4C56]">{item.credits}</div>}
197
212
  </div>
198
- {!item.finished && item.link ? (
199
- <a
213
+ {!item.finished && item.link && isLogin ? (
214
+ <Button
215
+ as="a"
216
+ size="base"
200
217
  href={item.link}
201
218
  target="_blank"
202
219
  rel="noopener noreferrer"
203
- className={cn(
204
- 'cursor-pointer bg-[#080a0f] min-w-[118px] px-[20px] pb-[10px] pt-[11px] text-[14px] font-[700] leading-[1.2] text-white',
205
- rounded ? 'rounded-[4px]' : 'rounded-none'
206
- )}
220
+ className="min-w-[116px]"
221
+ onClick={() => trackTaskButton(item.id)}
207
222
  >
208
223
  {item.buttonLabel}
209
- </a>
224
+ </Button>
210
225
  ) : (
211
- <button
212
- className={cn(
213
- 'cursor-pointer min-w-[118px] px-[20px] pb-[10px] pt-[11px] text-[14px] font-[700] leading-[1.2] text-white',
214
- item.finished ? 'bg-[#767880]' : 'bg-[#080a0f]',
215
- rounded ? 'rounded-[4px]' : 'rounded-none'
216
- )}
217
- disabled={item.finished}
218
- onClick={!item.finished ? item.onClick : undefined}
219
- >
226
+ <Button size="base" disabled={item.finished} className="min-w-[116px]" onClick={item.onClick}>
220
227
  {item.buttonLabel}
221
- </button>
228
+ </Button>
222
229
  )}
223
230
  </div>
224
231
  </div>
@@ -1,5 +1,5 @@
1
- import { Picture } from '@anker-in/headless-ui'
2
- import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
1
+ import { Button, Picture } from '@anker-in/headless-ui'
2
+ import { gaTrack, classNames as cn, useHeadlessContext } from '@anker-in/lib'
3
3
  import { useMemberPopupContext } from '../../context/provider'
4
4
  import { useReferralOverview } from './hooks/useReferralOverview'
5
5
  import { formatPrice } from '../../../credits/context/utils'
@@ -13,7 +13,7 @@ type Props = {
13
13
  }
14
14
 
15
15
  function Referral({ copy, onClose }: Props) {
16
- const { profile, alpcConfig } = useMemberPopupContext()
16
+ const { profile, alpcConfig, pageHandle } = useMemberPopupContext()
17
17
  const isLogin = !!profile
18
18
  const { brand, currencyCode = 'USD' as string } = useHeadlessContext()
19
19
  const rounded = ROUNDED_BRANDS.includes(brand)
@@ -23,19 +23,37 @@ function Referral({ copy, onClose }: Props) {
23
23
  const cashAvailable = data?.data?.data?.available ?? 0
24
24
  const cashPending = data?.data?.data?.pending ?? 0
25
25
 
26
- console.log('cashAvailable', cashAvailable)
27
- console.log('cashPending', cashPending)
28
- console.log('data', data)
29
- console.log('data.data', data?.data)
26
+ function buildRefUrl(url: string) {
27
+ try {
28
+ if (!pageHandle) return url
29
+ const target = new URL(url, window.location.href)
30
+ target.searchParams.set('ref', `${pageHandle}_referral`)
31
+ return target.toString()
32
+ } catch {
33
+ return url
34
+ }
35
+ }
36
+
37
+ function trackReferralCta() {
38
+ gaTrack({
39
+ event: 'ga4Event',
40
+ event_name: 'lp_button',
41
+ event_parameters: {
42
+ position: 'referral',
43
+ button_name: 'referral_cta',
44
+ info: 'Member Floating Window',
45
+ },
46
+ })
47
+ }
30
48
 
31
49
  return (
32
- <div className="flex flex-col gap-[12px]">
50
+ <div className="flex flex-col">
33
51
  {copy.title && <h2 className="text-[24px] font-[700] leading-[1.2] text-[#080a0f]">{copy.title}</h2>}
34
52
 
35
53
  {isLogin && (
36
54
  <div
37
55
  className={cn(
38
- 'flex items-center gap-[12px] bg-[#f5f6f7] p-[16px]',
56
+ 'flex items-center mt-[16px] gap-[12px] bg-[#f5f6f7] p-[16px]',
39
57
  rounded ? 'rounded-[8px]' : 'rounded-none'
40
58
  )}
41
59
  >
@@ -56,14 +74,14 @@ function Referral({ copy, onClose }: Props) {
56
74
  )}
57
75
 
58
76
  {(copy.howToTitle || copy.howToDescription) && (
59
- <div className="flex flex-col gap-[8px]">
60
- {copy.howToTitle && (
61
- <h3 className="text-[20px] font-[700] leading-[1.2] text-[#080a0f]">{copy.howToTitle}</h3>
77
+ <div className="flex mt-[32px] flex-col gap-[8px]">
78
+ {copy.howToTitle && <h3 className="text-[20px] font-bold leading-[1.2] text-[#080a0f]">{copy.howToTitle}</h3>}
79
+ {copy.howToDescription && (
80
+ <p className="text-[14px] font-bold leading-[1.4] text-[#080A0F]">{copy.howToDescription}</p>
62
81
  )}
63
- {copy.howToDescription && <p className="text-[14px] leading-[1.5] text-[#1e2024]">{copy.howToDescription}</p>}
64
82
  {copy.learnMoreLabel && copy.learnMoreUrl && (
65
83
  <a
66
- href={copy.learnMoreUrl}
84
+ href={buildRefUrl(copy.learnMoreUrl)}
67
85
  target="_blank"
68
86
  rel="noopener noreferrer"
69
87
  className="flex items-center gap-[4px] text-[14px] font-[700] text-[#080a0f] underline"
@@ -84,22 +102,22 @@ function Referral({ copy, onClose }: Props) {
84
102
  <Picture
85
103
  source={copy.image.url}
86
104
  alt={copy.image.alt ?? ''}
87
- className={cn('mt-[8px] h-[100px] w-full object-cover', rounded ? 'rounded-[8px]' : 'rounded-none')}
105
+ className={cn('mt-[8px] w-full', rounded ? 'rounded-[8px]' : 'rounded-none')}
88
106
  />
89
107
  )}
90
108
 
91
109
  {copy.ctaButton && (
92
- <a
93
- href={copy.ctaUrl ?? '#'}
110
+ <Button
111
+ size="base"
112
+ as="a"
113
+ className="mt-[16px]"
114
+ href={copy.ctaUrl ? buildRefUrl(copy.ctaUrl) : '#'}
94
115
  target="_blank"
95
116
  rel="noopener noreferrer"
96
- className={cn(
97
- 'block w-full cursor-pointer bg-[#080a0f] py-[14px] text-center text-[14px] font-[700] text-white',
98
- rounded ? 'rounded-[4px]' : 'rounded-none'
99
- )}
117
+ onClick={trackReferralCta}
100
118
  >
101
119
  {copy.ctaButton}
102
- </a>
120
+ </Button>
103
121
  )}
104
122
  </div>
105
123
  )
@@ -108,7 +108,6 @@ export type EarnCreditsCopy = {
108
108
  list: {
109
109
  id: EarnCreditsTaskType
110
110
  title: string
111
- description: string
112
111
  credits?: string
113
112
  }[]
114
113
  // 子弹窗文案
@@ -137,7 +136,9 @@ export type SubscribeModalCopy = {
137
136
  desc?: string
138
137
  placeholder: string
139
138
  policy?: string
139
+ policyDefaultChecked?: boolean
140
140
  successTips?: string
141
+ subscribedLabel?: string
141
142
  dealsType?: string
142
143
  buttonLabel?: string
143
144
  single_brand_subscribe?: boolean
@@ -160,14 +161,17 @@ export type ConsumeCreditsopy = {
160
161
  unlockRewards: string
161
162
  btnRedeem: string
162
163
  insufficientCredits?: string
163
- pointUnit?: string
164
+ balanceLabel?: string
165
+ comingSoonLabel?: string
166
+ creditUnit?: string
164
167
  off?: string
168
+ giftCard?: string
165
169
  imageMapping?: {
166
170
  [key in ConsumeCreditsItemType]?: { url: string }
167
171
  }
168
172
  list: ConsumeCreditsItem[]
169
173
  redeemModal: RedeemCouponModalCopy
170
- creditsPage?: { label: string; url: string }
174
+ creditsPage?: { label: string; url: string; redeemListSectionId?: string }
171
175
  }
172
176
 
173
177
  export type ConsumeCreditsItem = {
@@ -185,6 +189,7 @@ export type ConsumeCreditsItem = {
185
189
  export type RedeemCouponModalCopy = {
186
190
  confirmTitle: string
187
191
  confirmButton: string
192
+ off?: string
188
193
  commonError: string
189
194
  redeemLimitError: string
190
195
  inventoryNotEnough: string
@@ -194,6 +199,8 @@ export type RedeemCouponModalCopy = {
194
199
  successDesc: string
195
200
  successButton: string
196
201
  successButtonUrl?: string
202
+ copyLabel?: string
203
+ copiedLabel?: string
197
204
  }
198
205
 
199
206
  // ─── Referral Copy ───────────────────────────────────
@@ -236,4 +243,14 @@ export type MemberPopupContextValue = {
236
243
  openSignInPopup: () => void
237
244
  taskIdToTypeMapping?: Record<string, DTC_TASK_TYPE>
238
245
  alpcConfig: AlpcConfig
246
+ pageHandle?: string
247
+ }
248
+
249
+ export type MemberPopupInternalContextValue = MemberPopupContextValue & {
250
+ isSubscribeSuccess: boolean
251
+ setIsSubscribeSuccess: (v: boolean) => void
252
+ isActivateSuccess: boolean
253
+ setIsActivateSuccess: (v: boolean) => void
254
+ isProfileCompleteSuccess: boolean
255
+ setIsProfileCompleteSuccess: (v: boolean) => void
239
256
  }