@anker-in/campaign-ui 0.5.0-beta.2 → 0.5.0-beta.21
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/cjs/templates/Credits.js +1 -1
- package/dist/cjs/templates/Credits.js.map +3 -3
- 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/dist/esm/templates/Credits.js +1 -1
- package/dist/esm/templates/Credits.js.map +3 -3
- 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 +200 -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/src/templates/Credits.tsx +25 -0
- 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,28 @@ 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
|
+
targetUrl.hash = sectionId
|
|
122
|
+
if (pageHandle) {
|
|
123
|
+
targetUrl.searchParams.set('ref', `${pageHandle}_consume_credits`)
|
|
124
|
+
}
|
|
125
|
+
trackRedeemButton(item.title)
|
|
126
|
+
window.open(targetUrl.toString(), '_blank', 'noopener,noreferrer')
|
|
127
|
+
}
|
|
128
|
+
return
|
|
129
|
+
}
|
|
85
130
|
if (item.type === ConsumeCreditsItemType.Coupon) {
|
|
131
|
+
trackRedeemButton(item.title)
|
|
86
132
|
pushView({
|
|
87
133
|
type: MemberPopupPanelType.RedeemCoupon,
|
|
88
134
|
props: {
|
|
@@ -92,7 +138,7 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
92
138
|
? { url: copy.imageMapping[item.type]!.url, alt: item.image?.alt }
|
|
93
139
|
: item.image,
|
|
94
140
|
itemValue: item.value,
|
|
95
|
-
|
|
141
|
+
itemRules: item.rules,
|
|
96
142
|
redeemId: Number(item.redeemId),
|
|
97
143
|
userId: profile?.user_id,
|
|
98
144
|
alpcConfig,
|
|
@@ -101,12 +147,22 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
101
147
|
} else {
|
|
102
148
|
setRedeemAndBuyError('')
|
|
103
149
|
setLoadingId(item.redeemId)
|
|
150
|
+
trackRedeemButton(item.title)
|
|
104
151
|
try {
|
|
105
152
|
await redeemAndBuy({
|
|
106
153
|
productVariant: item.variant,
|
|
107
154
|
redeemId: Number(item.redeemId),
|
|
108
155
|
userId: profile?.user_id,
|
|
109
156
|
})
|
|
157
|
+
gaTrack({
|
|
158
|
+
event: 'ga4Event',
|
|
159
|
+
event_name: 'lp_button',
|
|
160
|
+
event_parameters: {
|
|
161
|
+
position: 'consume_credits',
|
|
162
|
+
button_name: 'redeem_success',
|
|
163
|
+
info: 'Member Floating Window',
|
|
164
|
+
},
|
|
165
|
+
})
|
|
110
166
|
} catch (e: any) {
|
|
111
167
|
setRedeemAndBuyError(e?.message ?? copy.redeemModal.commonError)
|
|
112
168
|
} finally {
|
|
@@ -117,97 +173,154 @@ function ConsumeCredits({ copy, onClose }: Props) {
|
|
|
117
173
|
|
|
118
174
|
return (
|
|
119
175
|
<>
|
|
120
|
-
<div className="flex flex-1 flex-col
|
|
176
|
+
<div className="flex flex-1 flex-col">
|
|
121
177
|
<div className="flex flex-col gap-[8px]">
|
|
122
178
|
{copy.title && <h2 className="text-[24px] font-[700] leading-[1.2] text-[#080a0f]">{copy.title}</h2>}
|
|
123
|
-
{copy.subtitle &&
|
|
179
|
+
{copy.subtitle && (
|
|
180
|
+
<p className="text-[16px] mt-[8px] font-[700] leading-snug text-[#4a4c56]">{copy.subtitle}</p>
|
|
181
|
+
)}
|
|
124
182
|
</div>
|
|
125
183
|
|
|
126
|
-
{
|
|
127
|
-
<div
|
|
128
|
-
{
|
|
184
|
+
{isLogin && (
|
|
185
|
+
<div
|
|
186
|
+
className={cn(
|
|
187
|
+
'flex items-center mt-[16px] gap-[12px] bg-[#f5f6f7] p-[16px]',
|
|
188
|
+
rounded ? 'rounded-[8px]' : 'rounded-none'
|
|
189
|
+
)}
|
|
190
|
+
>
|
|
191
|
+
<div className="flex flex-1 flex-col gap-[4px]">
|
|
192
|
+
<div className="text-[14px] font-[700] text-[#1e2024]">{copy.balanceLabel ?? 'AnkerCredits Balance'}</div>
|
|
193
|
+
<div className="flex items-end gap-[4px]">
|
|
194
|
+
<span className="text-[24px] font-[700] leading-[1.2] text-[#1e2024]">
|
|
195
|
+
{numberFormat(creditInfo?.available_credit || 0)}
|
|
196
|
+
</span>
|
|
197
|
+
<span className="text-[14px] font-[700] leading-[1.4] text-[#1e2024]">
|
|
198
|
+
{copy.creditUnit ?? 'ankercredits'}
|
|
199
|
+
</span>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
<div className="h-full w-px bg-[#dadce0]" />
|
|
203
|
+
<div className="flex flex-1 flex-col gap-[4px]">
|
|
204
|
+
<div className="text-[14px] font-[700] text-[#1e2024]">{copy.comingSoonLabel ?? 'Coming Soon'}</div>
|
|
205
|
+
<div className="flex items-end gap-[4px]">
|
|
206
|
+
<span className="text-[24px] font-[700] leading-[1.2] text-[#1e2024]">
|
|
207
|
+
{numberFormat(creditInfo?.pending_credit || 0)}
|
|
208
|
+
</span>
|
|
209
|
+
<span className="text-[14px] font-[700] leading-[1.4] text-[#1e2024]">
|
|
210
|
+
{copy.creditUnit ?? 'ankercredits'}
|
|
211
|
+
</span>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
129
214
|
</div>
|
|
130
215
|
)}
|
|
131
|
-
{redeemAndBuyError && <div className="text-[14px] font-[700] text-[#f84d4f]">{redeemAndBuyError}</div>}
|
|
216
|
+
{redeemAndBuyError && <div className="text-[14px] mt-[8px] font-[700] text-[#f84d4f]">{redeemAndBuyError}</div>}
|
|
132
217
|
|
|
133
218
|
{listLoading ? (
|
|
134
219
|
<div className="flex flex-1 items-center justify-center py-[32px]">
|
|
135
220
|
<div className="size-[32px] animate-spin rounded-full border-[3px] border-[#080a0f] border-t-transparent" />
|
|
136
221
|
</div>
|
|
137
222
|
) : (
|
|
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
|
-
|
|
223
|
+
<div className="flex mt-[16px] flex-col">
|
|
224
|
+
{list.map((item, idx) => {
|
|
225
|
+
const hasProduct = !!item.product
|
|
226
|
+
return (
|
|
227
|
+
<div key={idx} className="relative py-[16px]">
|
|
228
|
+
{idx > 0 && <div className="absolute inset-x-0 top-0 h-px bg-[#dadce0]" />}
|
|
229
|
+
<div className="flex items-center gap-[12px]">
|
|
230
|
+
{(() => {
|
|
231
|
+
const mappedImgUrl = copy.imageMapping?.[item.type]?.url
|
|
232
|
+
const imgUrl = hasProduct
|
|
233
|
+
? (item.variant?.image?.url ?? item.product?.images?.[0]?.url ?? item.image?.url)
|
|
234
|
+
: (mappedImgUrl ?? item.image?.url)
|
|
235
|
+
const imgAlt = hasProduct
|
|
236
|
+
? (item.variant?.image?.altText ?? item.product?.images?.[0]?.alt ?? item.image?.alt ?? '')
|
|
237
|
+
: (item.image?.alt ?? '')
|
|
238
|
+
if (!imgUrl) return null
|
|
239
|
+
return (
|
|
240
|
+
<div
|
|
241
|
+
className={cn(
|
|
242
|
+
'relative size-[64px] shrink-0 overflow-hidden',
|
|
243
|
+
rounded ? 'rounded-[4px]' : 'rounded-none'
|
|
244
|
+
)}
|
|
245
|
+
>
|
|
246
|
+
<Picture
|
|
247
|
+
source={imgUrl}
|
|
248
|
+
alt={imgAlt}
|
|
249
|
+
className="flex size-full items-center justify-center"
|
|
250
|
+
imgClassName={hasProduct ? 'object-cover' : 'h-full w-auto object-contain'}
|
|
251
|
+
/>
|
|
252
|
+
{!hasProduct && item.value && (
|
|
253
|
+
<div className="absolute bottom-[16px] left-[4px] text-[12px] font-[800] leading-none text-white">
|
|
254
|
+
{item.value} {copy.off}
|
|
255
|
+
</div>
|
|
256
|
+
)}
|
|
257
|
+
</div>
|
|
258
|
+
)
|
|
259
|
+
})()}
|
|
260
|
+
<div className="min-w-0 flex-1">
|
|
261
|
+
<div className="text-[16px] font-[700] text-[#1e2024] line-clamp-2">
|
|
262
|
+
{hasProduct && item.product?.title ? item.product.title : item.title}
|
|
263
|
+
</div>
|
|
264
|
+
<div className="mt-[4px] text-[14px] text-[#666]">
|
|
265
|
+
{hasProduct && item.price != null
|
|
266
|
+
? `${numberFormat(item.alpcData.consume_credits)} ${copy.creditUnit ?? ''} + $${Number(item.price).toFixed(2)}`
|
|
267
|
+
: `${numberFormat(item.alpcData.consume_credits)} ${copy.creditUnit ?? ''}`}
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
<div className="relative group">
|
|
271
|
+
<Button
|
|
272
|
+
className={cn(
|
|
273
|
+
'bg-[#080a0f] px-[20px] pb-[10px] pt-[11px] text-[14px] font-[700] leading-[1.2] text-white',
|
|
274
|
+
rounded ? 'rounded-[4px]' : 'rounded-none'
|
|
275
|
+
)}
|
|
276
|
+
disabled={isDisabled(item)}
|
|
277
|
+
loading={loadingId === item.redeemId}
|
|
278
|
+
onClick={() => handleRedeem(item)}
|
|
279
|
+
>
|
|
280
|
+
{getButtonLabel(item)}
|
|
281
|
+
</Button>
|
|
282
|
+
{item.insufficient && isLogin && isActivate && (
|
|
283
|
+
<div className="pointer-events-none absolute right-0 top-full z-[100] mt-[10px] hidden w-[200px] group-hover:block">
|
|
284
|
+
<div className="relative bg-[#6D6D6F] p-[16px] text-[14px] font-[700] text-white shadow">
|
|
285
|
+
<p className="text-pretty tracking-[-0.02em] text-[14px]">{copy.insufficientCredits}</p>
|
|
286
|
+
<div className="absolute -top-[8px] right-[20px] size-[16px] origin-top-left rotate-45 rounded-[2px] bg-[#6D6D6F]" />
|
|
287
|
+
</div>
|
|
164
288
|
</div>
|
|
165
289
|
)}
|
|
166
290
|
</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
291
|
</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
292
|
</div>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
</div>
|
|
293
|
+
)
|
|
294
|
+
})}
|
|
295
|
+
</div>
|
|
203
296
|
)}
|
|
204
297
|
|
|
205
298
|
{copy.creditsPage?.url && (
|
|
206
299
|
<a
|
|
207
|
-
href={
|
|
300
|
+
href={(() => {
|
|
301
|
+
if (!pageHandle) return copy.creditsPage!.url
|
|
302
|
+
try {
|
|
303
|
+
const url = new URL(copy.creditsPage!.url, window.location.href)
|
|
304
|
+
url.searchParams.set('ref', `${pageHandle}_consume_credits`)
|
|
305
|
+
return url.toString()
|
|
306
|
+
} catch {
|
|
307
|
+
return copy.creditsPage!.url
|
|
308
|
+
}
|
|
309
|
+
})()}
|
|
208
310
|
target="_blank"
|
|
209
311
|
rel="noopener noreferrer"
|
|
210
312
|
className="mt-auto self-start text-[14px] font-[700] text-[#080a0f] underline"
|
|
313
|
+
onClick={() =>
|
|
314
|
+
gaTrack({
|
|
315
|
+
event: 'ga4Event',
|
|
316
|
+
event_name: 'lp_button',
|
|
317
|
+
event_parameters: {
|
|
318
|
+
position: 'consume_credits',
|
|
319
|
+
button_name: 'credits_page_link',
|
|
320
|
+
info: 'Member Floating Window',
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
}
|
|
211
324
|
>
|
|
212
325
|
{copy.creditsPage.label ?? 'Go to Credits Page'}
|
|
213
326
|
</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
|
))}
|