@anker-in/campaign-ui 0.5.0-beta.2 → 0.5.0-beta.20
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.
- package/dist/cjs/components/credits/context/hooks/useCountries.js +1 -1
- package/dist/cjs/components/credits/context/hooks/useCountries.js.map +3 -3
- package/dist/cjs/components/memberPopup/MemberPopup.d.ts +1 -1
- package/dist/cjs/components/memberPopup/MemberPopup.js +1 -1
- package/dist/cjs/components/memberPopup/MemberPopup.js.map +3 -3
- package/dist/cjs/components/memberPopup/context/provider.d.ts +3 -3
- package/dist/cjs/components/memberPopup/context/provider.js +1 -1
- package/dist/cjs/components/memberPopup/context/provider.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +7 -0
- package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js +2 -0
- package/dist/cjs/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +7 -0
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +9 -7
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +1 -1
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.d.ts +1 -2
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js +1 -1
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/index.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +1 -2
- package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js +1 -1
- package/dist/cjs/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js +1 -1
- package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js.map +2 -2
- package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +1 -3
- package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +1 -1
- package/dist/cjs/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +1 -2
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +1 -1
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/EarnCredits/index.d.ts +1 -8
- package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js +1 -1
- package/dist/cjs/components/memberPopup/panels/EarnCredits/index.js.map +3 -3
- package/dist/cjs/components/memberPopup/panels/Referral/index.js +1 -1
- package/dist/cjs/components/memberPopup/panels/Referral/index.js.map +3 -3
- package/dist/cjs/components/memberPopup/type.d.ts +29 -3
- package/dist/cjs/components/memberPopup/type.js +1 -1
- package/dist/cjs/components/memberPopup/type.js.map +2 -2
- package/dist/esm/components/credits/context/hooks/useCountries.js +1 -1
- package/dist/esm/components/credits/context/hooks/useCountries.js.map +3 -3
- package/dist/esm/components/memberPopup/MemberPopup.d.ts +1 -1
- package/dist/esm/components/memberPopup/MemberPopup.js +1 -1
- package/dist/esm/components/memberPopup/MemberPopup.js.map +3 -3
- package/dist/esm/components/memberPopup/context/provider.d.ts +3 -3
- package/dist/esm/components/memberPopup/context/provider.js +1 -1
- package/dist/esm/components/memberPopup/context/provider.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.d.ts +7 -0
- package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js +2 -0
- package/dist/esm/components/memberPopup/panels/ActivitiesSubscribePanel.js.map +7 -0
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.d.ts +9 -7
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js +1 -1
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.d.ts +1 -2
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js +1 -1
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/index.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.d.ts +1 -2
- package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js +1 -1
- package/dist/esm/components/memberPopup/panels/EarnCredits/ActivatePanel.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js +1 -1
- package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfileModal.js.map +2 -2
- package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.d.ts +1 -3
- package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js +1 -1
- package/dist/esm/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.d.ts +1 -2
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js +1 -1
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/EarnCredits/index.d.ts +1 -8
- package/dist/esm/components/memberPopup/panels/EarnCredits/index.js +1 -1
- package/dist/esm/components/memberPopup/panels/EarnCredits/index.js.map +3 -3
- package/dist/esm/components/memberPopup/panels/Referral/index.js +1 -1
- package/dist/esm/components/memberPopup/panels/Referral/index.js.map +3 -3
- package/dist/esm/components/memberPopup/type.d.ts +29 -3
- package/dist/esm/components/memberPopup/type.js +1 -1
- package/dist/esm/components/memberPopup/type.js.map +2 -2
- package/package.json +1 -1
- package/src/components/credits/context/hooks/useCountries.ts +4 -15
- package/src/components/memberPopup/MemberPopup.tsx +170 -177
- package/src/components/memberPopup/context/provider.tsx +24 -4
- package/src/components/memberPopup/panels/ActivitiesSubscribePanel.tsx +194 -0
- package/src/components/memberPopup/panels/ConsumeCredits/RedeemCouponPanel.tsx +93 -60
- package/src/components/memberPopup/panels/ConsumeCredits/index.tsx +199 -87
- package/src/components/memberPopup/panels/EarnCredits/ActivatePanel.tsx +30 -15
- package/src/components/memberPopup/panels/EarnCredits/CompleteProfileModal.tsx +6 -1
- package/src/components/memberPopup/panels/EarnCredits/CompleteProfilePanel.tsx +65 -35
- package/src/components/memberPopup/panels/EarnCredits/SubscribeEmailPanel.tsx +15 -6
- package/src/components/memberPopup/panels/EarnCredits/index.tsx +131 -86
- package/src/components/memberPopup/panels/Referral/index.tsx +35 -16
- package/src/components/memberPopup/type.ts +26 -3
- package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.d.ts +0 -10
- package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js +0 -2
- package/dist/cjs/components/memberPopup/panels/Activity/SubscribeModal.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +0 -7
- package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +0 -2
- package/dist/cjs/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/Activity/index.d.ts +0 -7
- package/dist/cjs/components/memberPopup/panels/Activity/index.js +0 -2
- package/dist/cjs/components/memberPopup/panels/Activity/index.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +0 -19
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +0 -2
- package/dist/cjs/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +0 -10
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js +0 -2
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +0 -9
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js +0 -2
- package/dist/cjs/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +0 -7
- package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +0 -13
- package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +0 -2
- package/dist/cjs/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.d.ts +0 -10
- package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js +0 -2
- package/dist/esm/components/memberPopup/panels/Activity/SubscribeModal.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.d.ts +0 -7
- package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js +0 -2
- package/dist/esm/components/memberPopup/panels/Activity/hooks/useActivitySubscribe.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/Activity/index.d.ts +0 -7
- package/dist/esm/components/memberPopup/panels/Activity/index.js +0 -2
- package/dist/esm/components/memberPopup/panels/Activity/index.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.d.ts +0 -19
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js +0 -2
- package/dist/esm/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.d.ts +0 -10
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js +0 -2
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribeModal.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.d.ts +0 -9
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js +0 -2
- package/dist/esm/components/memberPopup/panels/EarnCredits/SubscribePanel.js.map +0 -7
- package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.d.ts +0 -13
- package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js +0 -2
- package/dist/esm/components/memberPopup/panels/Referral/hooks/useReferralDashboard.js.map +0 -7
- package/dist/index.d.mts +0 -1775
- package/dist/index.d.ts +0 -1775
- package/dist/index.js +0 -18542
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -18514
- package/dist/index.mjs.map +0 -1
- package/src/components/memberPopup/panels/ConsumeCredits/RedeemCouponModal.tsx +0 -150
- package/src/components/memberPopup/panels/EarnCredits/SubscribeModal.tsx +0 -144
- package/src/components/memberPopup/panels/EarnCredits/SubscribePanel.tsx +0 -147
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useMemo, useState } from 'react'
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react'
|
|
2
2
|
import { Picture, Button } from '@anker-in/headless-ui'
|
|
3
|
-
import { classNames as cn, useProductsByHandles, useHeadlessContext } from '@anker-in/lib'
|
|
3
|
+
import { gaTrack, classNames as cn, useProductsByHandles, useHeadlessContext } from '@anker-in/lib'
|
|
4
4
|
import { useMemberPopupContext } from '../../context/provider'
|
|
5
5
|
import { useViewStack } from '../../context/viewStack'
|
|
6
6
|
import { useRedeemableList } from './hooks/useRedeemableList'
|
|
@@ -19,17 +19,18 @@ type EnrichedItem = ConsumeCreditsItem & {
|
|
|
19
19
|
alpcData: ConsumeCreditRuleResponse
|
|
20
20
|
insufficient: boolean
|
|
21
21
|
soldOut: boolean
|
|
22
|
+
disabled: boolean
|
|
22
23
|
product?: any
|
|
23
24
|
variant?: any
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
type Props = {
|
|
27
28
|
copy: ConsumeCreditsopy
|
|
28
|
-
onClose: () => void
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function ConsumeCredits({ copy
|
|
32
|
-
const { profile, creditInfo, openSignUpPopup, alpcConfig } =
|
|
31
|
+
function ConsumeCredits({ copy }: Props) {
|
|
32
|
+
const { profile, creditInfo, openSignUpPopup, alpcConfig, isActivateSuccess, fetchCreditInfo, pageHandle } =
|
|
33
|
+
useMemberPopupContext()
|
|
33
34
|
const { pushView } = useViewStack()
|
|
34
35
|
const { brand } = useHeadlessContext()
|
|
35
36
|
const rounded = ROUNDED_BRANDS.includes(brand)
|
|
@@ -37,6 +38,10 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
37
38
|
const [redeemAndBuyError, setRedeemAndBuyError] = useState('')
|
|
38
39
|
const [loadingId, setLoadingId] = useState<string | number | null>(null)
|
|
39
40
|
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (profile?.user_id) fetchCreditInfo(profile.user_id)
|
|
43
|
+
}, [])
|
|
44
|
+
|
|
40
45
|
const isLogin = !!profile
|
|
41
46
|
const { redeemableList, listLoading } = useRedeemableList(alpcConfig)
|
|
42
47
|
const { trigger: redeemAndBuy } = useRedeemAndBuy(alpcConfig)
|
|
@@ -51,30 +56,50 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
51
56
|
if (!alpcData) return null
|
|
52
57
|
|
|
53
58
|
const availableCredit = Number(creditInfo?.available_credit ?? 0)
|
|
54
|
-
const insufficient =
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
let product
|
|
58
|
-
let variant
|
|
59
|
-
if (item.type === ConsumeCreditsItemType.RedeemAndBuy && item.product) {
|
|
60
|
-
product = products?.find((p: any) => p.handle === item.product!.handle)
|
|
61
|
-
variant = product?.variants?.find((v: any) => v.sku === item.product!.sku) ?? product?.variants?.[0]
|
|
62
|
-
if (!product || !variant) return null
|
|
63
|
-
}
|
|
59
|
+
const insufficient = alpcData.consume_credits > availableCredit
|
|
60
|
+
const alpcSoldOut = alpcData.is_limited && (!alpcData.remaining_inventory || alpcData.remaining_inventory <= 0)
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
const isPhysicalProduct =
|
|
63
|
+
item.type === ConsumeCreditsItemType.RedeemAndBuy || item.type === ConsumeCreditsItemType.Product
|
|
64
|
+
const product = products?.find((p: any) => p.handle === item.product?.handle)
|
|
65
|
+
const variant = product?.variants?.find((v: any) => v.sku === item.product?.sku) ?? product?.variants?.[0]
|
|
66
|
+
if (isPhysicalProduct && (!product || !variant || !variant?.availableForSale || alpcSoldOut)) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
return { ...item, alpcData, insufficient, product, variant }
|
|
66
70
|
})
|
|
67
71
|
.filter(Boolean) as EnrichedItem[]
|
|
68
72
|
}, [copy.list, redeemableList, creditInfo, profile, isLogin, products])
|
|
69
73
|
|
|
74
|
+
const isActivate = profile?.activated || isActivateSuccess
|
|
75
|
+
|
|
70
76
|
function getButtonLabel(item: (typeof list)[number]) {
|
|
71
|
-
if (!isLogin)
|
|
72
|
-
|
|
77
|
+
if (!isLogin || !isActivate) {
|
|
78
|
+
return copy.unlockRewards
|
|
79
|
+
}
|
|
80
|
+
if (item.soldOut) {
|
|
81
|
+
return copy.soldOut
|
|
82
|
+
}
|
|
73
83
|
return copy.btnRedeem
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
function isDisabled(item: (typeof list)[number]) {
|
|
77
|
-
|
|
87
|
+
if (!isLogin || !isActivate) {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
return item.insufficient
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function trackRedeemButton(itemTitle: string) {
|
|
94
|
+
gaTrack({
|
|
95
|
+
event: 'ga4Event',
|
|
96
|
+
event_name: 'lp_button',
|
|
97
|
+
event_parameters: {
|
|
98
|
+
position: 'consume_credits',
|
|
99
|
+
button_name: 'redeem',
|
|
100
|
+
info: 'Member Floating Window',
|
|
101
|
+
},
|
|
102
|
+
})
|
|
78
103
|
}
|
|
79
104
|
|
|
80
105
|
async function handleRedeem(item: (typeof list)[number]) {
|
|
@@ -82,7 +107,27 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
82
107
|
openSignUpPopup()
|
|
83
108
|
return
|
|
84
109
|
}
|
|
110
|
+
if (!isActivate) {
|
|
111
|
+
pushView({
|
|
112
|
+
type: MemberPopupPanelType.Activate,
|
|
113
|
+
})
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
if (item.type === ConsumeCreditsItemType.GiftCard || item.type === ConsumeCreditsItemType.Product) {
|
|
117
|
+
if (copy.creditsPage?.url) {
|
|
118
|
+
const sectionId = copy.creditsPage.redeemListSectionId ?? 'creditsRedeemList'
|
|
119
|
+
const targetUrl = new URL(copy.creditsPage.url, window.location.href)
|
|
120
|
+
targetUrl.searchParams.set('section', sectionId)
|
|
121
|
+
if (pageHandle) {
|
|
122
|
+
targetUrl.searchParams.set('ref', `${pageHandle}_consume_credits`)
|
|
123
|
+
}
|
|
124
|
+
trackRedeemButton(item.title)
|
|
125
|
+
window.open(targetUrl.toString(), '_blank', 'noopener,noreferrer')
|
|
126
|
+
}
|
|
127
|
+
return
|
|
128
|
+
}
|
|
85
129
|
if (item.type === ConsumeCreditsItemType.Coupon) {
|
|
130
|
+
trackRedeemButton(item.title)
|
|
86
131
|
pushView({
|
|
87
132
|
type: MemberPopupPanelType.RedeemCoupon,
|
|
88
133
|
props: {
|
|
@@ -92,7 +137,7 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
92
137
|
? { url: copy.imageMapping[item.type]!.url, alt: item.image?.alt }
|
|
93
138
|
: item.image,
|
|
94
139
|
itemValue: item.value,
|
|
95
|
-
|
|
140
|
+
itemRules: item.rules,
|
|
96
141
|
redeemId: Number(item.redeemId),
|
|
97
142
|
userId: profile?.user_id,
|
|
98
143
|
alpcConfig,
|
|
@@ -101,12 +146,22 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
101
146
|
} else {
|
|
102
147
|
setRedeemAndBuyError('')
|
|
103
148
|
setLoadingId(item.redeemId)
|
|
149
|
+
trackRedeemButton(item.title)
|
|
104
150
|
try {
|
|
105
151
|
await redeemAndBuy({
|
|
106
152
|
productVariant: item.variant,
|
|
107
153
|
redeemId: Number(item.redeemId),
|
|
108
154
|
userId: profile?.user_id,
|
|
109
155
|
})
|
|
156
|
+
gaTrack({
|
|
157
|
+
event: 'ga4Event',
|
|
158
|
+
event_name: 'lp_button',
|
|
159
|
+
event_parameters: {
|
|
160
|
+
position: 'consume_credits',
|
|
161
|
+
button_name: 'redeem_success',
|
|
162
|
+
info: 'Member Floating Window',
|
|
163
|
+
},
|
|
164
|
+
})
|
|
110
165
|
} catch (e: any) {
|
|
111
166
|
setRedeemAndBuyError(e?.message ?? copy.redeemModal.commonError)
|
|
112
167
|
} finally {
|
|
@@ -117,97 +172,154 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
117
172
|
|
|
118
173
|
return (
|
|
119
174
|
<>
|
|
120
|
-
<div className="flex flex-1 flex-col
|
|
175
|
+
<div className="flex flex-1 flex-col">
|
|
121
176
|
<div className="flex flex-col gap-[8px]">
|
|
122
177
|
{copy.title && <h2 className="text-[24px] font-[700] leading-[1.2] text-[#080a0f]">{copy.title}</h2>}
|
|
123
|
-
{copy.subtitle &&
|
|
178
|
+
{copy.subtitle && (
|
|
179
|
+
<p className="text-[16px] mt-[8px] font-[700] leading-snug text-[#4a4c56]">{copy.subtitle}</p>
|
|
180
|
+
)}
|
|
124
181
|
</div>
|
|
125
182
|
|
|
126
|
-
{
|
|
127
|
-
<div
|
|
128
|
-
{
|
|
183
|
+
{isLogin && (
|
|
184
|
+
<div
|
|
185
|
+
className={cn(
|
|
186
|
+
'flex items-center mt-[16px] gap-[12px] bg-[#f5f6f7] p-[16px]',
|
|
187
|
+
rounded ? 'rounded-[8px]' : 'rounded-none'
|
|
188
|
+
)}
|
|
189
|
+
>
|
|
190
|
+
<div className="flex flex-1 flex-col gap-[4px]">
|
|
191
|
+
<div className="text-[14px] font-[700] text-[#1e2024]">{copy.balanceLabel ?? 'AnkerCredits Balance'}</div>
|
|
192
|
+
<div className="flex items-end gap-[4px]">
|
|
193
|
+
<span className="text-[24px] font-[700] leading-[1.2] text-[#1e2024]">
|
|
194
|
+
{numberFormat(creditInfo?.available_credit || 0)}
|
|
195
|
+
</span>
|
|
196
|
+
<span className="text-[14px] font-[700] leading-[1.4] text-[#1e2024]">
|
|
197
|
+
{copy.creditUnit ?? 'ankercredits'}
|
|
198
|
+
</span>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div className="h-full w-px bg-[#dadce0]" />
|
|
202
|
+
<div className="flex flex-1 flex-col gap-[4px]">
|
|
203
|
+
<div className="text-[14px] font-[700] text-[#1e2024]">{copy.comingSoonLabel ?? 'Coming Soon'}</div>
|
|
204
|
+
<div className="flex items-end gap-[4px]">
|
|
205
|
+
<span className="text-[24px] font-[700] leading-[1.2] text-[#1e2024]">
|
|
206
|
+
{numberFormat(creditInfo?.pending_credit || 0)}
|
|
207
|
+
</span>
|
|
208
|
+
<span className="text-[14px] font-[700] leading-[1.4] text-[#1e2024]">
|
|
209
|
+
{copy.creditUnit ?? 'ankercredits'}
|
|
210
|
+
</span>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
129
213
|
</div>
|
|
130
214
|
)}
|
|
131
|
-
{redeemAndBuyError && <div className="text-[14px] font-[700] text-[#f84d4f]">{redeemAndBuyError}</div>}
|
|
215
|
+
{redeemAndBuyError && <div className="text-[14px] mt-[8px] font-[700] text-[#f84d4f]">{redeemAndBuyError}</div>}
|
|
132
216
|
|
|
133
217
|
{listLoading ? (
|
|
134
218
|
<div className="flex flex-1 items-center justify-center py-[32px]">
|
|
135
219
|
<div className="size-[32px] animate-spin rounded-full border-[3px] border-[#080a0f] border-t-transparent" />
|
|
136
220
|
</div>
|
|
137
221
|
) : (
|
|
138
|
-
<div className="flex flex-col">
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
222
|
+
<div className="flex mt-[16px] flex-col">
|
|
223
|
+
{list.map((item, idx) => {
|
|
224
|
+
const hasProduct = !!item.product
|
|
225
|
+
return (
|
|
226
|
+
<div key={idx} className="relative py-[16px]">
|
|
227
|
+
{idx > 0 && <div className="absolute inset-x-0 top-0 h-px bg-[#dadce0]" />}
|
|
228
|
+
<div className="flex items-center gap-[12px]">
|
|
229
|
+
{(() => {
|
|
230
|
+
const mappedImgUrl = copy.imageMapping?.[item.type]?.url
|
|
231
|
+
const imgUrl = hasProduct
|
|
232
|
+
? (item.variant?.image?.url ?? item.product?.images?.[0]?.url ?? item.image?.url)
|
|
233
|
+
: (mappedImgUrl ?? item.image?.url)
|
|
234
|
+
const imgAlt = hasProduct
|
|
235
|
+
? (item.variant?.image?.altText ?? item.product?.images?.[0]?.alt ?? item.image?.alt ?? '')
|
|
236
|
+
: (item.image?.alt ?? '')
|
|
237
|
+
if (!imgUrl) return null
|
|
238
|
+
return (
|
|
239
|
+
<div
|
|
240
|
+
className={cn(
|
|
241
|
+
'relative size-[64px] shrink-0 overflow-hidden',
|
|
242
|
+
rounded ? 'rounded-[4px]' : 'rounded-none'
|
|
243
|
+
)}
|
|
244
|
+
>
|
|
245
|
+
<Picture
|
|
246
|
+
source={imgUrl}
|
|
247
|
+
alt={imgAlt}
|
|
248
|
+
className="flex size-full items-center justify-center"
|
|
249
|
+
imgClassName={hasProduct ? 'object-cover' : 'h-full w-auto object-contain'}
|
|
250
|
+
/>
|
|
251
|
+
{!hasProduct && item.value && (
|
|
252
|
+
<div className="absolute bottom-[16px] left-[4px] text-[12px] font-[800] leading-none text-white">
|
|
253
|
+
{item.value} {copy.off}
|
|
254
|
+
</div>
|
|
255
|
+
)}
|
|
256
|
+
</div>
|
|
257
|
+
)
|
|
258
|
+
})()}
|
|
259
|
+
<div className="min-w-0 flex-1">
|
|
260
|
+
<div className="text-[16px] font-[700] text-[#1e2024] line-clamp-2">
|
|
261
|
+
{hasProduct && item.product?.title ? item.product.title : item.title}
|
|
262
|
+
</div>
|
|
263
|
+
<div className="mt-[4px] text-[14px] text-[#666]">
|
|
264
|
+
{hasProduct && item.price != null
|
|
265
|
+
? `${numberFormat(item.alpcData.consume_credits)} ${copy.creditUnit ?? ''} + $${Number(item.price).toFixed(2)}`
|
|
266
|
+
: `${numberFormat(item.alpcData.consume_credits)} ${copy.creditUnit ?? ''}`}
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
<div className="relative group">
|
|
270
|
+
<Button
|
|
271
|
+
className={cn(
|
|
272
|
+
'bg-[#080a0f] px-[20px] pb-[10px] pt-[11px] text-[14px] font-[700] leading-[1.2] text-white',
|
|
273
|
+
rounded ? 'rounded-[4px]' : 'rounded-none'
|
|
274
|
+
)}
|
|
275
|
+
disabled={isDisabled(item)}
|
|
276
|
+
loading={loadingId === item.redeemId}
|
|
277
|
+
onClick={() => handleRedeem(item)}
|
|
278
|
+
>
|
|
279
|
+
{getButtonLabel(item)}
|
|
280
|
+
</Button>
|
|
281
|
+
{item.insufficient && isLogin && isActivate && (
|
|
282
|
+
<div className="pointer-events-none absolute right-0 top-full z-[100] mt-[10px] hidden w-[200px] group-hover:block">
|
|
283
|
+
<div className="relative bg-[#6D6D6F] p-[16px] text-[14px] font-[700] text-white shadow">
|
|
284
|
+
<p className="text-pretty tracking-[-0.02em] text-[14px]">{copy.insufficientCredits}</p>
|
|
285
|
+
<div className="absolute -top-[8px] right-[20px] size-[16px] origin-top-left rotate-45 rounded-[2px] bg-[#6D6D6F]" />
|
|
286
|
+
</div>
|
|
164
287
|
</div>
|
|
165
288
|
)}
|
|
166
289
|
</div>
|
|
167
|
-
)
|
|
168
|
-
})()}
|
|
169
|
-
<div className="min-w-0 flex-1">
|
|
170
|
-
<div className="text-[16px] font-[700] text-[#1e2024] line-clamp-2">
|
|
171
|
-
{item.type === ConsumeCreditsItemType.RedeemAndBuy && item.product?.title
|
|
172
|
-
? item.product.title
|
|
173
|
-
: item.title}
|
|
174
290
|
</div>
|
|
175
|
-
<div className="mt-[4px] text-[14px] text-[#666]">
|
|
176
|
-
{item.type === ConsumeCreditsItemType.RedeemAndBuy && item.price != null
|
|
177
|
-
? `${numberFormat(item.alpcData.consume_credits)} ${copy.pointUnit ?? ''} + $${Number(item.price).toFixed(2)}`
|
|
178
|
-
: `${numberFormat(item.alpcData.consume_credits)} ${copy.pointUnit ?? ''}`}
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
<div className="relative group">
|
|
182
|
-
<Button
|
|
183
|
-
className={cn('bg-[#080a0f] px-[20px] pb-[10px] pt-[11px] text-[14px] font-[700] leading-[1.2] text-white', rounded ? 'rounded-[4px]' : 'rounded-none')}
|
|
184
|
-
disabled={isDisabled(item)}
|
|
185
|
-
loading={loadingId === item.redeemId}
|
|
186
|
-
onClick={() => handleRedeem(item)}
|
|
187
|
-
>
|
|
188
|
-
{getButtonLabel(item)}
|
|
189
|
-
</Button>
|
|
190
|
-
{item.insufficient && (
|
|
191
|
-
<div className="pointer-events-none absolute left-[48px] top-full mt-[10px] hidden -translate-x-1/2 group-hover:block">
|
|
192
|
-
<div className="relative bg-[#6D6D6F] p-[16px] text-[14px] font-[700] text-white shadow md:px-[10px] md:py-[8px]">
|
|
193
|
-
<p className="text-pretty tracking-[-0.02em] text-[14px]">{copy.insufficientCredits}</p>
|
|
194
|
-
<div className="absolute -top-[8px] left-[48px] size-[16px] origin-top-left rotate-45 rounded-[2px] bg-[#6D6D6F]" />
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
)}
|
|
198
291
|
</div>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
</div>
|
|
292
|
+
)
|
|
293
|
+
})}
|
|
294
|
+
</div>
|
|
203
295
|
)}
|
|
204
296
|
|
|
205
297
|
{copy.creditsPage?.url && (
|
|
206
298
|
<a
|
|
207
|
-
href={
|
|
299
|
+
href={(() => {
|
|
300
|
+
if (!pageHandle) return copy.creditsPage!.url
|
|
301
|
+
try {
|
|
302
|
+
const url = new URL(copy.creditsPage!.url, window.location.href)
|
|
303
|
+
url.searchParams.set('ref', `${pageHandle}_consume_credits`)
|
|
304
|
+
return url.toString()
|
|
305
|
+
} catch {
|
|
306
|
+
return copy.creditsPage!.url
|
|
307
|
+
}
|
|
308
|
+
})()}
|
|
208
309
|
target="_blank"
|
|
209
310
|
rel="noopener noreferrer"
|
|
210
311
|
className="mt-auto self-start text-[14px] font-[700] text-[#080a0f] underline"
|
|
312
|
+
onClick={() =>
|
|
313
|
+
gaTrack({
|
|
314
|
+
event: 'ga4Event',
|
|
315
|
+
event_name: 'lp_button',
|
|
316
|
+
event_parameters: {
|
|
317
|
+
position: 'consume_credits',
|
|
318
|
+
button_name: 'credits_page_link',
|
|
319
|
+
info: 'Member Floating Window',
|
|
320
|
+
},
|
|
321
|
+
})
|
|
322
|
+
}
|
|
211
323
|
>
|
|
212
324
|
{copy.creditsPage.label ?? 'Go to Credits Page'}
|
|
213
325
|
</a>
|
|
@@ -11,15 +11,16 @@ import {
|
|
|
11
11
|
import { Message } from '../../../registration/authCodeActivate/Message'
|
|
12
12
|
import type { AuthCodeActivateCopy } from '../../type'
|
|
13
13
|
import { useRegistration } from '../../../registration'
|
|
14
|
+
import { useMemberPopupContext } from '../../context/provider'
|
|
14
15
|
import { ROUNDED_BRANDS } from '../../../../constants'
|
|
15
16
|
|
|
16
17
|
type Props = {
|
|
17
18
|
copy: AuthCodeActivateCopy
|
|
18
19
|
onClose: () => void
|
|
19
|
-
onSuccess?: () => void
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export default function ActivatePanel({ copy, onClose
|
|
22
|
+
export default function ActivatePanel({ copy, onClose }: Props) {
|
|
23
|
+
const { setIsActivateSuccess, fetchCreditInfo, profile } = useMemberPopupContext()
|
|
23
24
|
const { locale, brand } = useHeadlessContext()
|
|
24
25
|
const { email } = useRegistration()
|
|
25
26
|
const rounded = ROUNDED_BRANDS.includes(brand)
|
|
@@ -165,14 +166,36 @@ export default function ActivatePanel({ copy, onClose, onSuccess }: Props) {
|
|
|
165
166
|
if (data.status >= 200 && data.status < 300) {
|
|
166
167
|
setMessageStatus('success')
|
|
167
168
|
setMessageText(copy?.authSuccessMessage || '')
|
|
168
|
-
|
|
169
|
+
setIsActivateSuccess(true)
|
|
170
|
+
if (profile?.user_id) fetchCreditInfo(profile.user_id)
|
|
171
|
+
gaTrack({
|
|
172
|
+
event: 'ga4Event',
|
|
173
|
+
event_name: 'lp_button',
|
|
174
|
+
event_parameters: {
|
|
175
|
+
page_group: 'reg_sub_pop',
|
|
176
|
+
position: 'auth_code',
|
|
177
|
+
button_name: 'check_and_active',
|
|
178
|
+
info: 'Member Floating Window',
|
|
179
|
+
},
|
|
180
|
+
})
|
|
169
181
|
setTimeout(() => {
|
|
170
182
|
onClose()
|
|
171
183
|
}, 3000)
|
|
172
184
|
} else {
|
|
173
185
|
const errorCode = data?.data?.error_code ?? data?.error_code
|
|
174
186
|
if (errorCode === '104') {
|
|
175
|
-
|
|
187
|
+
setIsActivateSuccess(true)
|
|
188
|
+
if (profile?.user_id) fetchCreditInfo(profile.user_id)
|
|
189
|
+
gaTrack({
|
|
190
|
+
event: 'ga4Event',
|
|
191
|
+
event_name: 'lp_button',
|
|
192
|
+
event_parameters: {
|
|
193
|
+
page_group: 'reg_sub_pop',
|
|
194
|
+
position: 'auth_code',
|
|
195
|
+
button_name: 'check_and_active',
|
|
196
|
+
info: 'Member Floating Window',
|
|
197
|
+
},
|
|
198
|
+
})
|
|
176
199
|
setTimeout(() => {
|
|
177
200
|
onClose()
|
|
178
201
|
}, 3000)
|
|
@@ -194,16 +217,6 @@ export default function ActivatePanel({ copy, onClose, onSuccess }: Props) {
|
|
|
194
217
|
setMessageText('')
|
|
195
218
|
clearTimeout(timer)
|
|
196
219
|
}, 5000)
|
|
197
|
-
|
|
198
|
-
gaTrack({
|
|
199
|
-
event: 'ga4Event',
|
|
200
|
-
event_name: 'lp_button',
|
|
201
|
-
event_parameters: {
|
|
202
|
-
page_group: 'reg_sub_pop',
|
|
203
|
-
position: 'auth_code',
|
|
204
|
-
button_name: 'check_and_active',
|
|
205
|
-
},
|
|
206
|
-
})
|
|
207
220
|
}, [
|
|
208
221
|
code,
|
|
209
222
|
copy?.codeEmptyError,
|
|
@@ -215,7 +228,9 @@ export default function ActivatePanel({ copy, onClose, onSuccess }: Props) {
|
|
|
215
228
|
sendEmailData,
|
|
216
229
|
triggerEmailValidation,
|
|
217
230
|
onClose,
|
|
218
|
-
|
|
231
|
+
setIsActivateSuccess,
|
|
232
|
+
fetchCreditInfo,
|
|
233
|
+
profile,
|
|
219
234
|
])
|
|
220
235
|
|
|
221
236
|
return (
|
|
@@ -40,6 +40,12 @@ export function CompleteProfileModal({ isOpen, onClose, onSuccess, copy, shopify
|
|
|
40
40
|
}
|
|
41
41
|
}, [profile])
|
|
42
42
|
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (countries.length > 0 && !country) {
|
|
45
|
+
setCountry(countries[0].id)
|
|
46
|
+
}
|
|
47
|
+
}, [countries])
|
|
48
|
+
|
|
43
49
|
const validate = useCallback(() => {
|
|
44
50
|
let hasError = false
|
|
45
51
|
if (!firstName.trim()) {
|
|
@@ -153,7 +159,6 @@ export function CompleteProfileModal({ isOpen, onClose, onSuccess, copy, shopify
|
|
|
153
159
|
value={country}
|
|
154
160
|
onChange={e => setCountry(e.target.value)}
|
|
155
161
|
>
|
|
156
|
-
<option value="" />
|
|
157
162
|
{countries.map((c: { id: string; name: string }) => (
|
|
158
163
|
<option key={c.id} value={c.id}>{c.name}</option>
|
|
159
164
|
))}
|