@anker-in/campaign-ui 0.3.4 → 0.4.0-beta.1
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/LiveChatWidget/LiveChatWidget.js +1 -1
- package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js +3 -3
- package/dist/cjs/components/LiveChatWidget/components/MessageList.js.map +3 -3
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.d.ts +2 -1
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js +1 -1
- package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js.map +2 -2
- package/dist/cjs/components/LiveChatWidget/types.d.ts +2 -1
- package/dist/cjs/components/LiveChatWidget/types.js.map +1 -1
- package/dist/cjs/components/credits/context/const.d.ts +10 -2
- package/dist/cjs/components/credits/context/const.js +1 -1
- package/dist/cjs/components/credits/context/const.js.map +2 -2
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.d.ts +7 -0
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js +2 -0
- package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js.map +7 -0
- package/dist/cjs/components/credits/context/hooks/useMyRewards.js +1 -1
- package/dist/cjs/components/credits/context/hooks/useMyRewards.js.map +3 -3
- package/dist/cjs/components/credits/context/hooks/useRedeemGoGift.d.ts +17 -0
- package/dist/cjs/components/credits/context/hooks/useRedeemGoGift.js +2 -0
- package/dist/cjs/components/credits/context/hooks/useRedeemGoGift.js.map +7 -0
- package/dist/cjs/components/credits/context/hooks/useRedeemableList.d.ts +7 -2
- package/dist/cjs/components/credits/context/hooks/useRedeemableList.js +1 -1
- package/dist/cjs/components/credits/context/hooks/useRedeemableList.js.map +3 -3
- package/dist/cjs/components/credits/context/provider.d.ts +5 -1
- package/dist/cjs/components/credits/context/provider.js +1 -1
- package/dist/cjs/components/credits/context/provider.js.map +3 -3
- package/dist/cjs/components/credits/context/response.d.ts +1 -0
- package/dist/cjs/components/credits/context/response.js.map +1 -1
- package/dist/cjs/components/credits/context/utils/atobID.d.ts +1 -0
- package/dist/cjs/components/credits/context/utils/atobID.js +2 -0
- package/dist/cjs/components/credits/context/utils/atobID.js.map +7 -0
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.d.ts +5 -0
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js +2 -0
- package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js.map +7 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.d.ts +8 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js +2 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js.map +7 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +9 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +2 -0
- package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +7 -0
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.d.ts +6 -0
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.js +2 -0
- package/dist/cjs/components/credits/context/utils/variantGetCoupon.js.map +7 -0
- package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
- package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +2 -2
- package/dist/cjs/components/credits/creditsBanner/index.js +2 -2
- package/dist/cjs/components/credits/creditsBanner/index.js.map +2 -2
- package/dist/cjs/components/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/cjs/components/credits/creditsCash/CreditsCash.js.map +2 -2
- package/dist/cjs/components/credits/creditsGoGift/CreditsGoGift.d.ts +5 -0
- package/dist/cjs/components/credits/creditsGoGift/CreditsGoGift.js +2 -0
- package/dist/cjs/components/credits/creditsGoGift/CreditsGoGift.js.map +7 -0
- package/dist/cjs/components/credits/creditsGoGift/index.d.ts +2 -0
- package/dist/cjs/components/credits/creditsGoGift/index.js +2 -0
- package/dist/cjs/components/credits/creditsGoGift/index.js.map +7 -0
- package/dist/cjs/components/credits/creditsGoGift/type.d.ts +22 -0
- package/dist/cjs/components/credits/creditsGoGift/type.js +2 -0
- package/dist/cjs/components/credits/creditsGoGift/type.js.map +7 -0
- package/dist/cjs/components/credits/creditsGofit/CreditsGofit.d.ts +5 -0
- package/dist/cjs/components/credits/creditsGofit/CreditsGofit.js +2 -0
- package/dist/cjs/components/credits/creditsGofit/CreditsGofit.js.map +7 -0
- package/dist/cjs/components/credits/creditsGofit/index.d.ts +2 -0
- package/dist/cjs/components/credits/creditsGofit/index.js +2 -0
- package/dist/cjs/components/credits/creditsGofit/index.js.map +7 -0
- package/dist/cjs/components/credits/creditsGofit/type.d.ts +22 -0
- package/dist/cjs/components/credits/creditsGofit/type.js +2 -0
- package/dist/cjs/components/credits/creditsGofit/type.js.map +7 -0
- package/dist/cjs/components/credits/creditsInfoCard/index.js +1 -1
- package/dist/cjs/components/credits/creditsInfoCard/index.js.map +3 -3
- package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
- package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.d.ts +10 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.js +2 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.js.map +7 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.d.ts +10 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.js +2 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.js.map +7 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal.d.ts +4 -5
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemCouponModal.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.d.ts +2 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Init.d.ts +2 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Init.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Init.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.d.ts +1 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.d.ts +3 -4
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Success.d.ts +2 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Success.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Success.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/index.d.ts +4 -5
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/index.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/index.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.d.ts +10 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.js +2 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.js.map +7 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.d.ts +9 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.js +2 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.js.map +7 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal.d.ts +8 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal.js +2 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemVirtualProductModal.js.map +7 -0
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/type.d.ts +11 -0
- package/dist/cjs/components/credits/creditsRedeemList/type.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/type.js.map +1 -1
- package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
- package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +2 -2
- package/dist/cjs/components/credits/creditsWaysToGetCredits/type.d.ts +2 -2
- package/dist/cjs/components/credits/creditsWaysToGetCredits/type.js.map +1 -1
- package/dist/cjs/components/credits/index.d.ts +2 -1
- package/dist/cjs/components/credits/index.js +1 -1
- package/dist/cjs/components/credits/index.js.map +3 -3
- package/dist/cjs/components/credits/modal/MyRewardsModal.d.ts +16 -0
- package/dist/cjs/components/credits/modal/MyRewardsModal.js +1 -1
- package/dist/cjs/components/credits/modal/MyRewardsModal.js.map +3 -3
- package/dist/cjs/components/credits/modal/RewardsModal.d.ts +64 -0
- package/dist/cjs/components/credits/modal/RewardsModal.js +2 -0
- package/dist/cjs/components/credits/modal/RewardsModal.js.map +7 -0
- package/dist/cjs/components/credits/modal/activitiesModal.d.ts +1 -1
- package/dist/cjs/components/credits/modal/activitiesModal.js +2 -2
- package/dist/cjs/components/credits/modal/activitiesModal.js.map +3 -3
- package/dist/cjs/components/credits/modal/creditsUploadReceiptModal.js +2 -2
- package/dist/cjs/components/credits/modal/creditsUploadReceiptModal.js.map +3 -3
- package/dist/cjs/components/credits/modal/loadingDots.js +1 -1
- package/dist/cjs/components/credits/modal/loadingDots.js.map +2 -2
- package/dist/cjs/components/credits/modal/modalContainer.js +2 -2
- package/dist/cjs/components/credits/modal/modalContainer.js.map +4 -4
- package/dist/cjs/components/credits/modal/rulesModal.d.ts +1 -1
- package/dist/cjs/components/credits/modal/rulesModal.js +2 -2
- package/dist/cjs/components/credits/modal/rulesModal.js.map +3 -3
- package/dist/cjs/components/credits/modal/subscribeModal.d.ts +1 -1
- package/dist/cjs/components/credits/modal/subscribeModal.js +2 -2
- package/dist/cjs/components/credits/modal/subscribeModal.js.map +3 -3
- package/dist/cjs/components/credits/modal/tip.js +1 -1
- package/dist/cjs/components/credits/modal/tip.js.map +2 -2
- package/dist/cjs/components/credits/type.d.ts +67 -5
- package/dist/cjs/components/credits/type.js +1 -1
- package/dist/cjs/components/credits/type.js.map +1 -1
- package/dist/cjs/stories/LiveChatWidget.stories.js +2 -9
- package/dist/cjs/stories/LiveChatWidget.stories.js.map +2 -2
- package/dist/cjs/templates/Credits.d.ts +1 -87
- package/dist/cjs/templates/Credits.js +1 -1
- package/dist/cjs/templates/Credits.js.map +3 -3
- package/dist/cjs/templates/Credits.types.d.ts +96 -0
- package/dist/cjs/templates/Credits.types.js +2 -0
- package/dist/cjs/templates/Credits.types.js.map +7 -0
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js +1 -1
- package/dist/esm/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/components/MessageList.js +3 -3
- package/dist/esm/components/LiveChatWidget/components/MessageList.js.map +3 -3
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.d.ts +2 -1
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js +1 -1
- package/dist/esm/components/LiveChatWidget/hooks/useChatState.js.map +2 -2
- package/dist/esm/components/LiveChatWidget/types.d.ts +2 -1
- package/dist/esm/components/credits/context/const.d.ts +10 -2
- package/dist/esm/components/credits/context/const.js +1 -1
- package/dist/esm/components/credits/context/const.js.map +2 -2
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.d.ts +7 -0
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js +2 -0
- package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js.map +7 -0
- package/dist/esm/components/credits/context/hooks/useMyRewards.js +1 -1
- package/dist/esm/components/credits/context/hooks/useMyRewards.js.map +3 -3
- package/dist/esm/components/credits/context/hooks/useRedeemGoGift.d.ts +17 -0
- package/dist/esm/components/credits/context/hooks/useRedeemGoGift.js +2 -0
- package/dist/esm/components/credits/context/hooks/useRedeemGoGift.js.map +7 -0
- package/dist/esm/components/credits/context/hooks/useRedeemableList.d.ts +7 -2
- package/dist/esm/components/credits/context/hooks/useRedeemableList.js +1 -1
- package/dist/esm/components/credits/context/hooks/useRedeemableList.js.map +3 -3
- package/dist/esm/components/credits/context/provider.d.ts +5 -1
- package/dist/esm/components/credits/context/provider.js +1 -1
- package/dist/esm/components/credits/context/provider.js.map +3 -3
- package/dist/esm/components/credits/context/response.d.ts +1 -0
- package/dist/esm/components/credits/context/utils/atobID.d.ts +1 -0
- package/dist/esm/components/credits/context/utils/atobID.js +2 -0
- package/dist/esm/components/credits/context/utils/atobID.js.map +7 -0
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.d.ts +5 -0
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js +2 -0
- package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js.map +7 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.d.ts +8 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js +2 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js.map +7 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +9 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +2 -0
- package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +7 -0
- package/dist/esm/components/credits/context/utils/variantGetCoupon.d.ts +6 -0
- package/dist/esm/components/credits/context/utils/variantGetCoupon.js +2 -0
- package/dist/esm/components/credits/context/utils/variantGetCoupon.js.map +7 -0
- package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
- package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +1 -1
- package/dist/esm/components/credits/creditsBanner/index.js +2 -2
- package/dist/esm/components/credits/creditsBanner/index.js.map +2 -2
- package/dist/esm/components/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/esm/components/credits/creditsCash/CreditsCash.js.map +1 -1
- package/dist/esm/components/credits/creditsGoGift/CreditsGoGift.d.ts +5 -0
- package/dist/esm/components/credits/creditsGoGift/CreditsGoGift.js +2 -0
- package/dist/esm/components/credits/creditsGoGift/CreditsGoGift.js.map +7 -0
- package/dist/esm/components/credits/creditsGoGift/index.d.ts +2 -0
- package/dist/esm/components/credits/creditsGoGift/index.js +2 -0
- package/dist/esm/components/credits/creditsGoGift/index.js.map +7 -0
- package/dist/esm/components/credits/creditsGoGift/type.d.ts +22 -0
- package/dist/esm/components/credits/creditsGoGift/type.js +1 -0
- package/dist/esm/components/credits/creditsGoGift/type.js.map +7 -0
- package/dist/esm/components/credits/creditsGofit/CreditsGofit.d.ts +5 -0
- package/dist/esm/components/credits/creditsGofit/CreditsGofit.js +2 -0
- package/dist/esm/components/credits/creditsGofit/CreditsGofit.js.map +7 -0
- package/dist/esm/components/credits/creditsGofit/index.d.ts +2 -0
- package/dist/esm/components/credits/creditsGofit/index.js +2 -0
- package/dist/esm/components/credits/creditsGofit/index.js.map +7 -0
- package/dist/esm/components/credits/creditsGofit/type.d.ts +22 -0
- package/dist/esm/components/credits/creditsGofit/type.js +1 -0
- package/dist/esm/components/credits/creditsGofit/type.js.map +7 -0
- package/dist/esm/components/credits/creditsInfoCard/index.js +1 -1
- package/dist/esm/components/credits/creditsInfoCard/index.js.map +3 -3
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +1 -1
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.d.ts +10 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.js +2 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.js.map +7 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.d.ts +10 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.js +2 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.js.map +7 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal.d.ts +4 -5
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemCouponModal.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.d.ts +2 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Init.d.ts +2 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Init.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Init.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.d.ts +1 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.d.ts +3 -4
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Success.d.ts +2 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Success.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Success.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/index.d.ts +4 -5
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/index.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/index.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.d.ts +10 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.js +2 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.js.map +7 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.d.ts +9 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.js +2 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.js.map +7 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal.d.ts +8 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal.js +2 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemVirtualProductModal.js.map +7 -0
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/type.d.ts +11 -0
- package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
- package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +1 -1
- package/dist/esm/components/credits/creditsWaysToGetCredits/type.d.ts +2 -2
- package/dist/esm/components/credits/creditsWaysToGetCredits/type.js.map +1 -1
- package/dist/esm/components/credits/index.d.ts +2 -1
- package/dist/esm/components/credits/index.js +1 -1
- package/dist/esm/components/credits/index.js.map +3 -3
- package/dist/esm/components/credits/modal/MyRewardsModal.d.ts +16 -0
- package/dist/esm/components/credits/modal/MyRewardsModal.js +1 -1
- package/dist/esm/components/credits/modal/MyRewardsModal.js.map +3 -3
- package/dist/esm/components/credits/modal/RewardsModal.d.ts +64 -0
- package/dist/esm/components/credits/modal/RewardsModal.js +2 -0
- package/dist/esm/components/credits/modal/RewardsModal.js.map +7 -0
- package/dist/esm/components/credits/modal/activitiesModal.d.ts +1 -1
- package/dist/esm/components/credits/modal/activitiesModal.js +2 -2
- package/dist/esm/components/credits/modal/activitiesModal.js.map +3 -3
- package/dist/esm/components/credits/modal/creditsUploadReceiptModal.js +2 -2
- package/dist/esm/components/credits/modal/creditsUploadReceiptModal.js.map +2 -2
- package/dist/esm/components/credits/modal/loadingDots.js +1 -1
- package/dist/esm/components/credits/modal/loadingDots.js.map +2 -2
- package/dist/esm/components/credits/modal/modalContainer.js +2 -2
- package/dist/esm/components/credits/modal/modalContainer.js.map +3 -3
- package/dist/esm/components/credits/modal/rulesModal.d.ts +1 -1
- package/dist/esm/components/credits/modal/rulesModal.js +2 -2
- package/dist/esm/components/credits/modal/rulesModal.js.map +3 -3
- package/dist/esm/components/credits/modal/subscribeModal.d.ts +1 -1
- package/dist/esm/components/credits/modal/subscribeModal.js +2 -2
- package/dist/esm/components/credits/modal/subscribeModal.js.map +2 -2
- package/dist/esm/components/credits/modal/tip.js +1 -1
- package/dist/esm/components/credits/modal/tip.js.map +2 -2
- package/dist/esm/components/credits/type.d.ts +67 -5
- package/dist/esm/stories/LiveChatWidget.stories.js +1 -8
- package/dist/esm/stories/LiveChatWidget.stories.js.map +2 -2
- package/dist/esm/templates/Credits.d.ts +1 -87
- package/dist/esm/templates/Credits.js +1 -1
- package/dist/esm/templates/Credits.js.map +3 -3
- package/dist/esm/templates/Credits.types.d.ts +96 -0
- package/dist/esm/templates/Credits.types.js +2 -0
- package/dist/esm/templates/Credits.types.js.map +7 -0
- package/package.json +2 -2
- package/src/components/LiveChatWidget/LiveChatWidget.tsx +20 -0
- package/src/components/LiveChatWidget/components/MessageContent/PromotionList.tsx +1 -1
- package/src/components/LiveChatWidget/components/MessageList.tsx +39 -44
- package/src/components/LiveChatWidget/hooks/useChatState.ts +4 -3
- package/src/components/LiveChatWidget/types.ts +2 -1
- package/src/components/credits/context/const.ts +8 -0
- package/src/components/credits/context/hooks/useMyRewards.ts +7 -31
- package/src/components/credits/context/hooks/useRedeemGoGift.ts +36 -0
- package/src/components/credits/context/hooks/useRedeemableList.ts +13 -19
- package/src/components/credits/context/provider.tsx +17 -2
- package/src/components/credits/context/response.ts +1 -0
- package/src/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.tsx +2 -2
- package/src/components/credits/creditsBanner/index.tsx +5 -5
- package/src/components/credits/creditsCash/CreditsCash.tsx +1 -1
- package/src/components/credits/creditsGoGift/CreditsGoGift.tsx +210 -0
- package/src/components/credits/creditsGoGift/index.ts +2 -0
- package/src/components/credits/creditsGoGift/type.ts +23 -0
- package/src/components/credits/creditsInfoCard/index.tsx +5 -28
- package/src/components/credits/creditsMemberPrice/CreditsMemberPrice.tsx +1 -1
- package/src/components/credits/creditsRedeemList/CreditsRedeemList.tsx +39 -17
- package/src/components/credits/creditsRedeemList/RedeemCouponModal/CouponInit.tsx +77 -0
- package/src/components/credits/creditsRedeemList/RedeemCouponModal/CouponSuccess.tsx +86 -0
- package/src/components/credits/creditsRedeemList/RedeemCouponModal.tsx +29 -138
- package/src/components/credits/creditsRedeemList/RedeemProductModal/Address.tsx +5 -6
- package/src/components/credits/creditsRedeemList/RedeemProductModal/Init.tsx +11 -12
- package/src/components/credits/creditsRedeemList/RedeemProductModal/NonProductValue.tsx +23 -14
- package/src/components/credits/creditsRedeemList/RedeemProductModal/ProductInfo.tsx +11 -9
- package/src/components/credits/creditsRedeemList/RedeemProductModal/Success.tsx +4 -5
- package/src/components/credits/creditsRedeemList/RedeemProductModal/index.tsx +29 -28
- package/src/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductInit.tsx +101 -0
- package/src/components/credits/creditsRedeemList/RedeemVirtualProductModal/VirtualProductSuccess.tsx +65 -0
- package/src/components/credits/creditsRedeemList/RedeemVirtualProductModal.tsx +156 -0
- package/src/components/credits/creditsRedeemList/RedeemableItem.tsx +1 -1
- package/src/components/credits/creditsRedeemList/type.ts +11 -0
- package/src/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.tsx +2 -2
- package/src/components/credits/creditsWaysToGetCredits/type.ts +2 -2
- package/src/components/credits/index.ts +2 -1
- package/src/components/credits/modal/{activitiesModal.tsx → ActivitiesModal.tsx} +2 -2
- package/src/components/credits/modal/{creditsUploadReceiptModal.tsx → CreditsUploadReceiptModal.tsx} +1 -1
- package/src/components/credits/modal/{modalContainer.tsx → ModalContainer.tsx} +1 -1
- package/src/components/credits/modal/{MyRewardsModal.tsx → RewardsModal.tsx} +145 -103
- package/src/components/credits/modal/{rulesModal.tsx → RulesModal.tsx} +1 -1
- package/src/components/credits/modal/{subscribeModal.tsx → SubscribeModal.tsx} +1 -1
- package/src/components/credits/type.ts +68 -5
- package/src/stories/LiveChatWidget.stories.tsx +7 -12
- package/src/styles/livechat.css +29 -0
- package/src/templates/Credits.tsx +110 -142
- package/src/templates/Credits.types.ts +110 -0
- package/dist/index.d.mts +0 -1305
- package/dist/index.d.ts +0 -1305
- package/dist/index.js +0 -26656
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -26641
- package/dist/index.mjs.map +0 -1
- /package/src/components/credits/modal/{loadingDots.tsx → LoadingDots.tsx} +0 -0
- /package/src/components/credits/modal/{tip.tsx → Tip.tsx} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var N=Object.create;var m=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var S=(r,i)=>{for(var d in i)m(r,d,{get:i[d],enumerable:!0})},P=(r,i,d,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let a of q(i))!x.call(r,a)&&a!==d&&m(r,a,{get:()=>i[a],enumerable:!(s=F(i,a))||s.enumerable});return r};var y=(r,i,d)=>(d=r!=null?N(w(r)):{},P(i||!r||!r.__esModule?m(d,"default",{value:r,enumerable:!0}):d,r)),O=r=>P(m({},"__esModule",{value:!0}),r);var U={};S(U,{CreditsTemplate:()=>H});module.exports=O(U);var e=require("react/jsx-runtime"),l=require("@anker-in/lib"),g=require("../components/registration/context/provider"),c=require("../components/credits/context/provider"),v=require("../components/credits/creditsBanner"),M=require("../components/credits/creditsInfoCard"),T=require("../components/credits/creditsBenefits"),u=require("../components/credits/creditsWaysToGetCredits"),b=require("../components/credits/creditsAnkersolixTask"),h=require("../components/credits/creditsRedeemList"),G=require("../components/credits/creditsGoGift"),I=require("../components/credits/creditsCash"),B=require("../components/credits/creditsMemberPrice"),A=require("../components/credits/creditsFaq"),L=require("../components/credits/creditsNavigation"),R=y(require("../components/credits/modal/ActivitiesModal")),D=y(require("../components/credits/modal/RewardsModal")),t=require("./Credits.types");const W=({headlessConfig:r,pageConfig:i,userContext:d})=>{const{openMyRewardsModal:s,setOpenMyRewardsModal:a,openActivitiesModal:C,setOpenActivitiesModal:f,pageCommon:n}=(0,c.useCreditsContext)();return(0,e.jsxs)(e.Fragment,{children:[i.components[t.ComponentKey.Navigation]&&(0,e.jsx)(L.CreditsNavigation,{copy:i.components[t.ComponentKey.Navigation]}),(0,e.jsx)("div",{className:(0,l.classNames)("bg-[#f5f5f7] leading-[1.2]"),children:i.order.map(o=>{if(o===t.ComponentKey.Navigation)return null;const p=i.components?.[o];return p?(0,e.jsxs)(e.Fragment,{children:[o===t.ComponentKey.Banner&&(0,e.jsx)(v.CreditsBanner,{copy:p,id:o}),o===t.ComponentKey.InfoCard&&d?.profile&&(0,e.jsx)(M.CreditsInfoCard,{copy:p,id:o}),o===t.ComponentKey.Benefits&&(0,e.jsx)(T.CreditsBenefits,{copy:p,id:o}),o===t.ComponentKey.WaysToGetCredits&&(0,e.jsx)(u.CreditsWaysToGetCredits,{copy:p,id:o,classNames:r.brand==="anker"?{subtitle:"text-white",equalCreditsText:"bg-gradient-to-r from-[#3AD1FF] to-[#008CD6] bg-clip-text text-transparent"}:{subtitle:"text-[#D1D1D1]",equalCreditsText:"text-[#F6EAD0]"}}),o===t.ComponentKey.AnkersolixTask&&(0,e.jsx)(b.CreditsAnkersolixTask,{copy:p,id:o}),o===t.ComponentKey.RedeemList&&(0,e.jsx)(h.CreditsRedeemList,{copy:p,id:o}),o===t.ComponentKey.GoGift&&(0,e.jsx)(G.CreditsGoGift,{copy:p,id:o}),o===t.ComponentKey.SpendCreditsLikeCash&&(0,e.jsx)(I.CreditsCash,{copy:p,id:o}),o===t.ComponentKey.MemberPrice&&(0,e.jsx)(B.CreditsMemberPrice,{copy:p,id:o}),o===t.ComponentKey.Faqs&&(0,e.jsx)(A.CreditsFaq,{copy:p,id:o}),o!==t.ComponentKey.Banner&&(0,e.jsx)("div",{className:"laptop:h-16 desktop:h-[96px] lg-desktop:h-[128px] tablet:h-16 h-16"})]}):null})}),n?.activitiesModal&&(0,e.jsx)(R.default,{isOpen:C,data:n.activitiesModal,onClose:()=>f(!1)}),n?.rewardsModal&&(0,e.jsx)(D.default,{isOpen:s,data:n.rewardsModal,onClose:()=>a(!1)})]})},H=({headlessConfig:r,siteConfig:i,creditsConfig:d,userContext:s,pageConfig:a,registrationContext:C,gtm:f,cartConfig:n})=>(0,e.jsx)(l.HeadlessProvider,{headlessConfig:r,children:(0,e.jsx)(g.RegistrationProvider,{copy:i.registrationsSettings,email:s?.profile?.email,children:(0,e.jsx)(c.CreditsProvider,{profile:s?.profile,removeProfile:s?.removeProfile,isLoadingProfile:s?.isLoadingProfile,openSignInPopup:C.openSignInPopup,openSignUpPopup:C.openSignUpPopup,creditInfo:s?.creditInfo,taskIdToTypeMapping:i.taskIdToTypeMapping,customer:s?.customer,fetchCreditInfo:s?.fetchCreditInfo,customerLoading:s?.customerLoading,gtm:f,pageCommon:a.common,memberPriceDiscount:i.memberPriceDiscount,alpcBrand:d?.alpcBrand,cartConfig:n,children:(0,e.jsx)(W,{headlessConfig:r,pageConfig:a,userContext:s})})})});
|
|
2
2
|
//# sourceMappingURL=Credits.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/templates/Credits.tsx"],
|
|
4
|
-
"sourcesContent": ["import { classNames,
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["Credits_exports", "__export", "
|
|
4
|
+
"sourcesContent": ["import { classNames, HeadlessProvider } from '@anker-in/lib'\nimport { RegistrationProvider } from '../components/registration/context/provider'\nimport { CreditsProvider, useCreditsContext } from '../components/credits/context/provider'\nimport { CreditsBanner } from '../components/credits/creditsBanner'\nimport { CreditsInfoCard } from '../components/credits/creditsInfoCard'\nimport { CreditsBenefits } from '../components/credits/creditsBenefits'\nimport { CreditsWaysToGetCredits } from '../components/credits/creditsWaysToGetCredits'\nimport { CreditsAnkersolixTask } from '../components/credits/creditsAnkersolixTask'\nimport { CreditsRedeemList } from '../components/credits/creditsRedeemList'\nimport { CreditsGoGift } from '../components/credits/creditsGoGift'\nimport { CreditsCash } from '../components/credits/creditsCash'\nimport { CreditsMemberPrice } from '../components/credits/creditsMemberPrice'\nimport { CreditsFaq } from '../components/credits/creditsFaq'\nimport { CreditsNavigation } from '../components/credits/creditsNavigation'\nimport ActivitiesModal from '../components/credits/modal/ActivitiesModal'\nimport RewardsModal from '../components/credits/modal/RewardsModal'\nimport { ComponentKey } from './Credits.types'\nimport type {\n CreditsTemplateProps,\n CreditsContentProps,\n CreditsBannerCopy,\n CreditsInfoCardCopy,\n CreditsBenefitsCopy,\n CreditsWaysToGetCreditsCopy,\n CreditsAnkersolixTaskCopy,\n CreditsRedeemListCopy,\n CreditsGoGiftCopy,\n CreditsCashCopy,\n CreditsMemberPriceCopy,\n CreditsFaqCopy,\n} from './Credits.types'\n\nconst CreditsContent = ({ headlessConfig, pageConfig, userContext }: CreditsContentProps) => {\n const { openMyRewardsModal, setOpenMyRewardsModal, openActivitiesModal, setOpenActivitiesModal, pageCommon } = useCreditsContext()\n\n return (\n <>\n {/* \u5BFC\u822A\u7EC4\u4EF6 - \u56FA\u5B9A\u4F4D\u7F6E\uFF0C\u4E0D\u53C2\u4E0E order \u6392\u5E8F */}\n {pageConfig.components[ComponentKey.Navigation] && (\n <CreditsNavigation copy={pageConfig.components[ComponentKey.Navigation]} />\n )}\n <div className={classNames('bg-[#f5f5f7] leading-[1.2]')}>\n {pageConfig.order.map(key => {\n // \u8DF3\u8FC7\u5BFC\u822A\u7EC4\u4EF6\uFF0C\u56E0\u4E3A\u5B83\u5DF2\u7ECF\u56FA\u5B9A\u6E32\u67D3\u5728\u4E0A\u65B9\n if (key === ComponentKey.Navigation) return null\n const componentCopy = pageConfig.components?.[key]\n if (!componentCopy) return null\n return (\n <>\n {key === ComponentKey.Banner && <CreditsBanner copy={componentCopy as CreditsBannerCopy} id={key} />}\n {key === ComponentKey.InfoCard && userContext?.profile && (\n <CreditsInfoCard copy={componentCopy as CreditsInfoCardCopy} id={key} />\n )}\n {key === ComponentKey.Benefits && (\n <CreditsBenefits copy={componentCopy as CreditsBenefitsCopy} id={key} />\n )}\n {key === ComponentKey.WaysToGetCredits && (\n <CreditsWaysToGetCredits\n copy={componentCopy as CreditsWaysToGetCreditsCopy}\n id={key}\n classNames={\n headlessConfig.brand === 'anker'\n ? {\n subtitle: 'text-white',\n equalCreditsText:\n 'bg-gradient-to-r from-[#3AD1FF] to-[#008CD6] bg-clip-text text-transparent',\n }\n : {\n subtitle: 'text-[#D1D1D1]',\n equalCreditsText: 'text-[#F6EAD0]',\n }\n }\n />\n )}\n {key === ComponentKey.AnkersolixTask && (\n <CreditsAnkersolixTask copy={componentCopy as CreditsAnkersolixTaskCopy} id={key} />\n )}\n {key === ComponentKey.RedeemList && (\n <CreditsRedeemList copy={componentCopy as CreditsRedeemListCopy} id={key} />\n )}\n {key === ComponentKey.GoGift && <CreditsGoGift copy={componentCopy as CreditsGoGiftCopy} id={key} />}\n {key === ComponentKey.SpendCreditsLikeCash && (\n <CreditsCash copy={componentCopy as CreditsCashCopy} id={key} />\n )}\n {key === ComponentKey.MemberPrice && (\n <CreditsMemberPrice copy={componentCopy as CreditsMemberPriceCopy} id={key} />\n )}\n {key === ComponentKey.Faqs && <CreditsFaq copy={componentCopy as CreditsFaqCopy} id={key} />}\n {key !== ComponentKey.Banner && (\n <div className=\"laptop:h-16 desktop:h-[96px] lg-desktop:h-[128px] tablet:h-16 h-16\" />\n )}\n </>\n )\n })}\n </div>\n\n {/* Global Modals */}\n {pageCommon?.activitiesModal && (\n <ActivitiesModal\n isOpen={openActivitiesModal}\n data={pageCommon.activitiesModal}\n onClose={() => setOpenActivitiesModal(false)}\n />\n )}\n {pageCommon?.rewardsModal && (\n <RewardsModal\n isOpen={openMyRewardsModal}\n data={pageCommon.rewardsModal}\n onClose={() => setOpenMyRewardsModal(false)}\n />\n )}\n </>\n )\n}\n\nexport const CreditsTemplate = ({\n headlessConfig,\n siteConfig,\n creditsConfig,\n userContext,\n pageConfig,\n registrationContext,\n gtm,\n cartConfig,\n}: CreditsTemplateProps) => {\n return (\n <HeadlessProvider headlessConfig={headlessConfig}>\n <RegistrationProvider copy={siteConfig.registrationsSettings} email={userContext?.profile?.email}>\n <CreditsProvider\n profile={userContext?.profile}\n removeProfile={userContext?.removeProfile}\n isLoadingProfile={userContext?.isLoadingProfile}\n openSignInPopup={registrationContext.openSignInPopup}\n openSignUpPopup={registrationContext.openSignUpPopup}\n creditInfo={userContext?.creditInfo}\n taskIdToTypeMapping={siteConfig.taskIdToTypeMapping}\n customer={userContext?.customer}\n fetchCreditInfo={userContext?.fetchCreditInfo}\n customerLoading={userContext?.customerLoading}\n gtm={gtm}\n pageCommon={pageConfig.common}\n memberPriceDiscount={siteConfig.memberPriceDiscount}\n alpcBrand={creditsConfig?.alpcBrand}\n cartConfig={cartConfig}\n >\n <CreditsContent headlessConfig={headlessConfig} pageConfig={pageConfig} userContext={userContext} />\n </CreditsProvider>\n </RegistrationProvider>\n </HeadlessProvider>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Credits_exports", "__export", "CreditsTemplate", "__toCommonJS", "import_jsx_runtime", "import_lib", "import_provider", "import_creditsBanner", "import_creditsInfoCard", "import_creditsBenefits", "import_creditsWaysToGetCredits", "import_creditsAnkersolixTask", "import_creditsRedeemList", "import_creditsGoGift", "import_creditsCash", "import_creditsMemberPrice", "import_creditsFaq", "import_creditsNavigation", "import_ActivitiesModal", "import_RewardsModal", "import_Credits", "CreditsContent", "headlessConfig", "pageConfig", "userContext", "openMyRewardsModal", "setOpenMyRewardsModal", "openActivitiesModal", "setOpenActivitiesModal", "pageCommon", "key", "componentCopy", "ActivitiesModal", "RewardsModal", "siteConfig", "creditsConfig", "registrationContext", "gtm", "cartConfig"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { HeadlessConfig } from '@anker-in/lib';
|
|
2
|
+
import { DTC_TASK_TYPE } from '../components/credits/context/const';
|
|
3
|
+
import { CreditsPageCommon } from '../components/credits/type';
|
|
4
|
+
import { FunctionMemberPriceConfig } from '../components/credits/context/memberPriceTypes';
|
|
5
|
+
import { AuthCodeActivateCopy } from 'src/components/registration/authCodeActivate/type';
|
|
6
|
+
import type { CreditsBannerCopy } from '../components/credits/creditsBanner';
|
|
7
|
+
import type { CreditsInfoCardCopy } from '../components/credits/creditsInfoCard';
|
|
8
|
+
import type { CreditsBenefitsCopy } from '../components/credits/creditsBenefits';
|
|
9
|
+
import type { CreditsWaysToGetCreditsCopy } from '../components/credits/creditsWaysToGetCredits';
|
|
10
|
+
import type { CreditsAnkersolixTaskCopy } from '../components/credits/creditsAnkersolixTask';
|
|
11
|
+
import type { CreditsRedeemListCopy } from '../components/credits/creditsRedeemList';
|
|
12
|
+
import type { CreditsGoGiftCopy } from '../components/credits/creditsGoGift';
|
|
13
|
+
import type { CreditsCashCopy } from '../components/credits/creditsCash';
|
|
14
|
+
import type { CreditsMemberPriceCopy } from '../components/credits/creditsMemberPrice';
|
|
15
|
+
import type { CreditsFaqCopy } from '../components/credits/creditsFaq';
|
|
16
|
+
import type { CreditsNavigationCopy } from '../components/credits/creditsNavigation';
|
|
17
|
+
export type { CreditsBannerCopy, CreditsInfoCardCopy, CreditsBenefitsCopy, CreditsWaysToGetCreditsCopy, CreditsAnkersolixTaskCopy, CreditsRedeemListCopy, CreditsGoGiftCopy, CreditsCashCopy, CreditsMemberPriceCopy, CreditsFaqCopy, CreditsNavigationCopy, };
|
|
18
|
+
export declare enum ComponentKey {
|
|
19
|
+
Navigation = "creditsNavigation",
|
|
20
|
+
Banner = "creditsBanner",
|
|
21
|
+
InfoCard = "creditsInfoCard",
|
|
22
|
+
Benefits = "creditsBenefits",
|
|
23
|
+
WaysToGetCredits = "creditsWaysToGetCredits",
|
|
24
|
+
AnkersolixTask = "creditsAnkersolixTask",
|
|
25
|
+
RedeemList = "creditsRedeemList",
|
|
26
|
+
GoGift = "creditsGoGift",
|
|
27
|
+
SpendCreditsLikeCash = "creditsCash",
|
|
28
|
+
MemberPrice = "creditsMemberPrice",
|
|
29
|
+
Faqs = "creditsFaq"
|
|
30
|
+
}
|
|
31
|
+
export type CreditsTemplateProps = {
|
|
32
|
+
headlessConfig: HeadlessConfig;
|
|
33
|
+
siteConfig: {
|
|
34
|
+
registrationsSettings: {
|
|
35
|
+
authCodeActivate: AuthCodeActivateCopy;
|
|
36
|
+
};
|
|
37
|
+
taskIdToTypeMapping: Record<string, DTC_TASK_TYPE>;
|
|
38
|
+
memberPriceDiscount?: FunctionMemberPriceConfig[];
|
|
39
|
+
};
|
|
40
|
+
creditsConfig?: {
|
|
41
|
+
alpcBrand?: string;
|
|
42
|
+
};
|
|
43
|
+
pageConfig: {
|
|
44
|
+
order: ComponentKey[];
|
|
45
|
+
common: CreditsPageCommon;
|
|
46
|
+
components: {
|
|
47
|
+
[ComponentKey.Navigation]?: CreditsNavigationCopy;
|
|
48
|
+
[ComponentKey.Banner]?: CreditsBannerCopy;
|
|
49
|
+
[ComponentKey.InfoCard]?: CreditsInfoCardCopy;
|
|
50
|
+
[ComponentKey.Benefits]?: CreditsBenefitsCopy;
|
|
51
|
+
[ComponentKey.WaysToGetCredits]?: CreditsWaysToGetCreditsCopy;
|
|
52
|
+
[ComponentKey.AnkersolixTask]?: CreditsAnkersolixTaskCopy;
|
|
53
|
+
[ComponentKey.RedeemList]?: CreditsRedeemListCopy;
|
|
54
|
+
[ComponentKey.GoGift]?: CreditsGoGiftCopy;
|
|
55
|
+
[ComponentKey.SpendCreditsLikeCash]?: CreditsCashCopy;
|
|
56
|
+
[ComponentKey.MemberPrice]?: CreditsMemberPriceCopy;
|
|
57
|
+
[ComponentKey.Faqs]?: CreditsFaqCopy;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
userContext: {
|
|
61
|
+
profile: any;
|
|
62
|
+
removeProfile: () => void;
|
|
63
|
+
isLoadingProfile: boolean;
|
|
64
|
+
creditInfo: any;
|
|
65
|
+
customer: any;
|
|
66
|
+
customerLoading: boolean;
|
|
67
|
+
fetchCreditInfo: () => void;
|
|
68
|
+
};
|
|
69
|
+
registrationContext: {
|
|
70
|
+
openSignUpPopup: () => void;
|
|
71
|
+
openSignInPopup: () => void;
|
|
72
|
+
};
|
|
73
|
+
gtm: {
|
|
74
|
+
pageGroup: string;
|
|
75
|
+
pageHandle?: string;
|
|
76
|
+
};
|
|
77
|
+
cartConfig?: {
|
|
78
|
+
addToCart: (params: {
|
|
79
|
+
variantList: Array<{
|
|
80
|
+
variant: any;
|
|
81
|
+
quantity: number;
|
|
82
|
+
attributes?: Array<{
|
|
83
|
+
key: string;
|
|
84
|
+
value: string;
|
|
85
|
+
}>;
|
|
86
|
+
}>;
|
|
87
|
+
cartAttributes?: Record<string, string>;
|
|
88
|
+
discountCodes?: string[];
|
|
89
|
+
}) => void | Promise<any>;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
export type CreditsContentProps = {
|
|
93
|
+
headlessConfig: HeadlessConfig;
|
|
94
|
+
pageConfig: CreditsTemplateProps['pageConfig'];
|
|
95
|
+
userContext: CreditsTemplateProps['userContext'];
|
|
96
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var m=(i,t)=>{for(var o in t)s(i,o,{get:t[o],enumerable:!0})},c=(i,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of p(t))!a.call(i,r)&&r!==o&&s(i,r,{get:()=>t[r],enumerable:!(n=d(t,r))||n.enumerable});return i};var y=i=>c(s({},"__esModule",{value:!0}),i);var f={};m(f,{ComponentKey:()=>C});module.exports=y(f);var C=(e=>(e.Navigation="creditsNavigation",e.Banner="creditsBanner",e.InfoCard="creditsInfoCard",e.Benefits="creditsBenefits",e.WaysToGetCredits="creditsWaysToGetCredits",e.AnkersolixTask="creditsAnkersolixTask",e.RedeemList="creditsRedeemList",e.GoGift="creditsGoGift",e.SpendCreditsLikeCash="creditsCash",e.MemberPrice="creditsMemberPrice",e.Faqs="creditsFaq",e))(C||{});
|
|
2
|
+
//# sourceMappingURL=Credits.types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/templates/Credits.types.ts"],
|
|
4
|
+
"sourcesContent": ["import { HeadlessConfig } from '@anker-in/lib'\nimport { DTC_TASK_TYPE } from '../components/credits/context/const'\nimport { CreditsPageCommon } from '../components/credits/type'\nimport { FunctionMemberPriceConfig } from '../components/credits/context/memberPriceTypes'\nimport { AuthCodeActivateCopy } from 'src/components/registration/authCodeActivate/type'\nimport type { CreditsBannerCopy } from '../components/credits/creditsBanner'\nimport type { CreditsInfoCardCopy } from '../components/credits/creditsInfoCard'\nimport type { CreditsBenefitsCopy } from '../components/credits/creditsBenefits'\nimport type { CreditsWaysToGetCreditsCopy } from '../components/credits/creditsWaysToGetCredits'\nimport type { CreditsAnkersolixTaskCopy } from '../components/credits/creditsAnkersolixTask'\nimport type { CreditsRedeemListCopy } from '../components/credits/creditsRedeemList'\nimport type { CreditsGoGiftCopy } from '../components/credits/creditsGoGift'\nimport type { CreditsCashCopy } from '../components/credits/creditsCash'\nimport type { CreditsMemberPriceCopy } from '../components/credits/creditsMemberPrice'\nimport type { CreditsFaqCopy } from '../components/credits/creditsFaq'\nimport type { CreditsNavigationCopy } from '../components/credits/creditsNavigation'\n\n// Re-export copy types for convenience\nexport type {\n CreditsBannerCopy,\n CreditsInfoCardCopy,\n CreditsBenefitsCopy,\n CreditsWaysToGetCreditsCopy,\n CreditsAnkersolixTaskCopy,\n CreditsRedeemListCopy,\n CreditsGoGiftCopy,\n CreditsCashCopy,\n CreditsMemberPriceCopy,\n CreditsFaqCopy,\n CreditsNavigationCopy,\n}\n\nexport enum ComponentKey {\n Navigation = 'creditsNavigation',\n Banner = 'creditsBanner',\n InfoCard = 'creditsInfoCard',\n Benefits = 'creditsBenefits',\n WaysToGetCredits = 'creditsWaysToGetCredits',\n AnkersolixTask = 'creditsAnkersolixTask',\n RedeemList = 'creditsRedeemList',\n GoGift = 'creditsGoGift',\n SpendCreditsLikeCash = 'creditsCash',\n MemberPrice = 'creditsMemberPrice',\n Faqs = 'creditsFaq',\n}\n\nexport type CreditsTemplateProps = {\n headlessConfig: HeadlessConfig\n siteConfig: {\n registrationsSettings: {\n authCodeActivate: AuthCodeActivateCopy\n }\n taskIdToTypeMapping: Record<string, DTC_TASK_TYPE>\n memberPriceDiscount?: FunctionMemberPriceConfig[]\n }\n creditsConfig?: {\n alpcBrand?: string\n }\n pageConfig: {\n order: ComponentKey[]\n common: CreditsPageCommon\n components: {\n [ComponentKey.Navigation]?: CreditsNavigationCopy\n [ComponentKey.Banner]?: CreditsBannerCopy\n [ComponentKey.InfoCard]?: CreditsInfoCardCopy\n [ComponentKey.Benefits]?: CreditsBenefitsCopy\n [ComponentKey.WaysToGetCredits]?: CreditsWaysToGetCreditsCopy\n [ComponentKey.AnkersolixTask]?: CreditsAnkersolixTaskCopy\n [ComponentKey.RedeemList]?: CreditsRedeemListCopy\n [ComponentKey.GoGift]?: CreditsGoGiftCopy\n [ComponentKey.SpendCreditsLikeCash]?: CreditsCashCopy\n [ComponentKey.MemberPrice]?: CreditsMemberPriceCopy\n [ComponentKey.Faqs]?: CreditsFaqCopy\n }\n }\n userContext: {\n profile: any\n removeProfile: () => void\n isLoadingProfile: boolean\n creditInfo: any\n customer: any\n customerLoading: boolean\n fetchCreditInfo: () => void\n }\n registrationContext: {\n openSignUpPopup: () => void\n openSignInPopup: () => void\n }\n gtm: {\n pageGroup: string\n pageHandle?: string\n }\n cartConfig?: {\n addToCart: (params: {\n variantList: Array<{\n variant: any\n quantity: number\n attributes?: Array<{ key: string; value: string }>\n }>\n cartAttributes?: Record<string, string>\n discountCodes?: string[]\n }) => void | Promise<any>\n }\n}\n\nexport type CreditsContentProps = {\n headlessConfig: HeadlessConfig\n pageConfig: CreditsTemplateProps['pageConfig']\n userContext: CreditsTemplateProps['userContext']\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,IAAA,eAAAC,EAAAH,GAgCO,IAAKE,OACVA,EAAA,WAAa,oBACbA,EAAA,OAAS,gBACTA,EAAA,SAAW,kBACXA,EAAA,SAAW,kBACXA,EAAA,iBAAmB,0BACnBA,EAAA,eAAiB,wBACjBA,EAAA,WAAa,oBACbA,EAAA,OAAS,gBACTA,EAAA,qBAAuB,cACvBA,EAAA,YAAc,qBACdA,EAAA,KAAO,aAXGA,OAAA",
|
|
6
|
+
"names": ["Credits_types_exports", "__export", "ComponentKey", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Fragment as
|
|
1
|
+
import{Fragment as Ue,jsx as x,jsxs as be}from"react/jsx-runtime";import _,{useEffect as qe,useCallback as C}from"react";import*as Y from"@radix-ui/react-dialog";import{DEFAULT_COMMON_TEXT as Ie}from"./constants";import{ChatBubble as Oe}from"./components/ChatBubble";import{ChatWindow as Fe}from"./components/ChatWindow";import{ComplianceDialog as Be}from"./components/ComplianceDialog";import{useChatState as Le}from"./hooks/useChatState";import{useChatAPI as We}from"./hooks/useChatAPI";import{MessageRendererRegistry as Ne}from"./utils/messageRenderers";import{sanitizeInput as $e}from"./utils/validation";import{transformProducts as se}from"./utils/productTransformers.js";import{transformCartData as ke}from"./utils/cartTransformers.js";import ae from"js-cookie";import{TextBlock as ze,ProductCard as Qe,ProductList as He,ProductComparisonRenderer as Ye,PolicyBlock as Ge,createQuickRepliesRenderer as Ve,ThinkingBlock as Xe,ErrorBlock as Ke,FAQListRenderer as Je,PromotionListRenderer as Ze,CartCard as je}from"./components/MessageContent/index.js";const mt=({apiBaseUrl:re,headers:ne,recaptchaSitekey:G,recaptchaAction:ie,site:i,channelCode:m,loginUserId:l,cartId:V,accessToken:X,position:oe,welcomeMessage:g,quickReplies:u,customRenderers:B,logoUrl:ce,title:de,chatBubbleIcon:pe,open:le,onOpenChange:ue,onOpen:me,onClose:ge,onMessageSend:L,onError:f,onTextMessage:fe,onProductList:he,onPromotionList:ye,onAddToCart:T,onCart:W,showNewSessionButton:_e,commonText:K,productCardRender:Ce,bottomTips:Re,complianceConfig:R})=>{const N=R?.cookieName||"livechat_compliance_agreed",[J,$]=_.useState(!1),[Z,we]=_.useState(()=>R?ae.get(N)!==void 0:!0),S=_.useMemo(()=>({...Ie,...K}),[K]),xe=Le({welcomeMessage:g,site:i,open:le,onOpenChange:ue,onOpen:me,onClose:ge,onMessageSend:L,onError:f,onTextMessage:fe,onProductList:he,onPromotionList:ye,onAddToCart:T,onCart:W,productCardRender:Ce}),{messages:A,isOpen:v,userId:o,sessionId:k,inputValue:z,isStreaming:Se,openChat:D,closeChat:j,setInputValue:Q,addMessage:p,setMessages:w,clearMessages:q,handleSSEEvent:U,saveSession:E,clearSession:P}=xe,[De,I]=_.useState(!1),{sendMessageStream:b,createSession:h}=We({apiBaseUrl:re,headers:ne,recaptchaConfig:{needRecaptcha:!!G,recaptchaSitekey:G,recaptchaAction:ie},onError:f}),ee=_.useRef(async t=>{}),Ee=_.useMemo(()=>{const t=new Ne;t.register("text",ze),t.register("product_card",Qe),t.register("product_list",He),t.register("product_comparison",Ye),t.register("policy",Ge),t.register("thinking",Xe),t.register("error",Ke),t.register("faq_list",Je),t.register("promotion_list",Ze),t.register("cart",je);const s=Ve(r=>{ee.current(r.value)});return t.register("quick_replies",s),B&&t.registerMany(B),t},[B]);qe(()=>{if(!v||!o)return;const t=k;t?Pe(t):M()},[v,o]);const te=C(t=>{if(Array.isArray(t.content))return t;const s=[];typeof t.content=="string"&&t.content.trim()&&s.push({type:"text",text:t.content});const r=t.structuredContent||t.structured_content;return Array.isArray(r)&&r.forEach(e=>{if(e.type==="product_list"&&Array.isArray(e.data))s.push({type:"product_list",data:{products:se(e.data,i),title:void 0,commonText:S}});else if(e.type==="quick_replies"&&e.data?.replies)s.push({type:"quick_replies",data:{replies:e.data.replies}});else if(e.type==="policy"&&e.data?.title&&e.data?.content)s.push({type:"policy",data:{title:e.data.title,content:e.data.content}});else if(e.type==="product_comparison"&&e.data?.products&&e.data?.dimensions)s.push({type:"product_comparison",data:{products:se(e.data.products,i),dimensions:e.data.dimensions,onAddToCart:T,commonText:S}});else if(e.type==="faq_list"&&e.data?.found!==void 0)s.push({type:"faq_list",data:e.data});else if(e.type==="promotion_list"&&e.data?.found!==void 0)s.push({type:"promotion_list",data:{...e.data,commonText:S}});else if(e.type==="cart"&&e.data?.id!==void 0){const c=ke(e.data);s.push({type:"cart",data:{...c,onCart:W,commonText:S}})}else s.push(e)}),s.length===0&&s.push({type:"text",text:""}),{...t,content:s}},[i,W,T,S]),M=C(async()=>{if(o){g||I(!0);try{const t=await h({user_id:o,site:i,channel_code:m,real_user_id:l});if(t.success){E(t.sessionId),q();const s=t.welcomeMessage||g;if(s){const r=[{type:"text",text:s}],e=t.quickQuestions;if(e&&e.length>0){const c=e.map((d,a)=>({id:`quick-${a}`,label:d,value:d}));r.push({type:"quick_replies",data:{replies:c}})}else u&&u.length>0&&r.push({type:"quick_replies",data:{replies:u}});p({id:`welcome-${Date.now()}`,role:"assistant",content:r,timestamp:Date.now()})}}}catch(t){console.error("[LiveChatWidget] Failed to create new session:",t),f?.(t);const s=t?.type==="GoogleRecaptchaError";p({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:s?"Your session has expired. Please refresh the page and try again.":"Failed to create session. Please refresh the page and try again.",code:s?"RECAPTCHA_ERROR":"SESSION_CREATE_ERROR"}}],timestamp:Date.now()})}finally{I(!1)}}},[o,i,m,l,h,E,q,g,u,p,f]),Pe=C(async t=>{g||I(!0);try{const s=await h({user_id:o,session_id:t,site:i,channel_code:m,real_user_id:l});if(s.success&&s.resumed){const r=s.welcomeMessage||g,e=r?[{type:"text",text:r}]:[],c=s.quickQuestions;if(c&&c.length>0){const d=c.map((a,F)=>({id:`quick-${F}`,label:a,value:a}));e.push({type:"quick_replies",data:{replies:d}})}else u&&u.length>0&&e.push({type:"quick_replies",data:{replies:u}});if(s.messages&&s.messages.length>0){const d=s.messages.filter(a=>a!=null).map(te).filter(a=>a.content&&a.content.length>0&&!(a.content.length===1&&a.content[0].type==="text"&&!a.content[0].text));if(e.length>0){const a={id:`welcome-${Date.now()}`,role:"assistant",content:e,timestamp:Date.now()};w([a,...d])}else w(d)}else q(),e.length>0&&p({id:`welcome-${Date.now()}`,role:"assistant",content:e,timestamp:Date.now()})}else s.resumed||(P(),M())}catch(s){console.error("[LiveChatWidget] Failed to resume session:",s),s?.type==="GoogleRecaptchaError"?p({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:"Your session has expired. Please refresh the page and try again.",code:"RECAPTCHA_ERROR"}}],timestamp:Date.now()}):(p({id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:"Failed to resume session. Creating a new session...",code:"SESSION_RESUME_ERROR"}}],timestamp:Date.now()}),P(),M())}finally{I(!1)}},[o,i,m,l,h,w,P,q,te,M,g,u,p]),O=C(async(t,s=!1)=>{const r=t||z.trim();if(!r)return;!t&&!s&&Q("");const e=$e(r);if(!e){f?.(new Error("Invalid message"));return}if(!s){const a={id:`user-${Date.now()}`,role:"user",content:[{type:"text",text:e}],timestamp:Date.now()};p(a)}const c={id:`thinking-${Date.now()}`,role:"assistant",content:[{type:"thinking",data:{status:"thinking"}}],timestamp:Date.now()};p(c),s||L?.(e);let d=!1;try{let a=k;if(!a){const n=await h({user_id:o,site:i,channel_code:m,real_user_id:l});if(n.success)a=n.sessionId,E(a);else throw new Error("Failed to create session")}if(await b({message:e,user_id:o,session_id:a,context:{cartId:V,accessToken:X,real_user_id:l}},n=>{U(n),n.event==="error"&&n.data.type==="validation_error"&&(d=!0,P())}),d&&!s){console.log("[LiveChatWidget] Session expired (validation_error), creating new session and retrying...");const n=A.filter(H=>H.id!==c.id);w(n);const y=await h({user_id:o,site:i,channel_code:m,real_user_id:l});if(y.success)E(y.sessionId),await O(e,!0);else throw new Error("Failed to recreate session after expiration")}}catch(a){console.error("[LiveChatWidget] Failed to send message:",a),f?.(a);const F=a?.type==="GoogleRecaptchaError";let n,y;F?(n="Your session has expired. Please refresh the page and try again.",y="RECAPTCHA_ERROR"):d?(n="Your session has expired. We tried to reconnect but failed. Please try again.",y="SESSION_EXPIRED"):(n="Failed to send message. Please check your network connection and try again.",y="NETWORK_ERROR");const H=A.filter(ve=>ve.id!==c.id);w([...H,{id:`error-${Date.now()}`,role:"system",content:[{type:"error",data:{message:n,code:y}}],timestamp:Date.now()}])}},[z,o,k,i,m,l,V,X,A,Q,p,w,h,b,U,E,P,L,f]);_.useEffect(()=>{ee.current=O},[O]);const Me=C(()=>{R&&!Z?$(!0):D()},[R,Z,D]),Te=C(()=>{we(!0),$(!1),ae.set(N,"true",{expires:365}),D()},[D,N]),Ae=C(()=>{$(!1)},[]);return be(Ue,{children:[R&&x(Be,{open:J,config:R,onAgree:Te,onClose:Ae}),x(Oe,{position:oe,onClick:Me,visible:!v&&!J,iconImageUrl:pe}),x(Y.Root,{open:v,onOpenChange:t=>t?D():j(),children:x(Y.Portal,{children:x(Y.Content,{className:"livechat-window-enter",style:{position:"fixed",zIndex:9998},children:x(Fe,{messages:A,inputValue:z,onInputChange:Q,onSend:()=>O(),onClose:j,onNewSession:M,title:de,logoUrl:ce,isSending:Se,isLoadingHistory:De,rendererRegistry:Ee,inputPlaceholder:"",onAddToCart:T,showNewSessionButton:_e,bottomTips:Re})})})})]})};export{mt as LiveChatWidget};
|
|
2
2
|
//# sourceMappingURL=LiveChatWidget.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/LiveChatWidget/LiveChatWidget.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * LiveChat \u4E3B\u7EC4\u4EF6\n * \u96C6\u6210\u6240\u6709\u5B50\u7EC4\u4EF6\uFF0C\u63D0\u4F9B\u5B8C\u6574\u7684\u804A\u5929\u529F\u80FD\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u4E09\u5C42\u67B6\u6784\u8BBE\u8BA1\n */\n\nimport React, { useEffect, useCallback } from 'react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type {\n LiveChatWidgetProps,\n QuickReply,\n Message,\n MessageContent,\n ChatStreamRequest,\n BackendCartData,\n CommonText,\n} from './types'\nimport { DEFAULT_COMMON_TEXT } from './constants'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport { ComplianceDialog } from './components/ComplianceDialog'\nimport { useChatState } from './hooks/useChatState'\nimport { useChatAPI } from './hooks/useChatAPI'\nimport { MessageRendererRegistry } from './utils/messageRenderers'\nimport { sanitizeInput } from './utils/validation'\nimport { transformProducts } from './utils/productTransformers.js'\nimport { transformCartData } from './utils/cartTransformers.js'\nimport Cookies from 'js-cookie'\nimport {\n TextBlock,\n ProductCard,\n ProductList,\n ProductComparisonRenderer,\n PolicyBlock,\n createQuickRepliesRenderer,\n ThinkingBlock,\n ErrorBlock,\n FAQListRenderer,\n PromotionListRenderer,\n CartCard,\n} from './components/MessageContent/index.js'\n\n/**\n * LiveChat \u804A\u5929\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u6C14\u6CE1\u5F39\u7A97\u804A\u5929\u754C\u9762\n * - SSE \u6D41\u5F0F\u6D88\u606F\u63A5\u6536\n * - \u4F1A\u8BDD\u7BA1\u7406\uFF08userId, sessionId\uFF09\n * - \u5386\u53F2\u6D88\u606F\u52A0\u8F7D\n * - \u591A\u79CD\u6D88\u606F\u7C7B\u578B\u6E32\u67D3\n * - \u81EA\u5B9A\u4E49\u6269\u5C55\u673A\u5236\n * - reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\n *\n * \u67B6\u6784\uFF1A\n * - UI Layer: ChatBubble, ChatWindow, MessageList, etc.\n * - Logic Layer: useChatState, useChatAPI, useSession\n * - Core Layer: MessageRendererRegistry, \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n *\n * @example\n * ```tsx\n * // \u57FA\u7840\u4F7F\u7528\uFF08\u4F7F\u7528\u9ED8\u8BA4\u4F4D\u7F6E\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * welcomeMessage=\"\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\"\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49\u4F4D\u7F6E\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * position={{ bottom: \"20px\", right: \"30px\" }}\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u542F\u7528 reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\uFF08\u63D0\u4F9B sitekey \u5373\u81EA\u52A8\u542F\u7528\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * recaptchaSitekey=\"6LfS4J4pAAAAACX1e_WrxutmxxzCK7FU4WzVqL14\"\n * recaptchaAction=\"livechat\"\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49 headers \u548C reCAPTCHA\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * headers={{\n * \"Authorization\": \"Bearer your-token\",\n * \"X-Custom-Header\": \"value\"\n * }}\n * recaptchaSitekey=\"your-site-key\"\n * />\n * ```\n */\nexport const LiveChatWidget: React.FC<LiveChatWidgetProps> = ({\n apiBaseUrl,\n headers,\n recaptchaSitekey,\n recaptchaAction,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n position,\n welcomeMessage,\n quickReplies,\n customRenderers,\n logoUrl,\n title,\n chatBubbleIcon,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n showNewSessionButton,\n commonText,\n productCardRender,\n bottomTips,\n complianceConfig,\n}) => {\n // \u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97\u72B6\u6001\n // \u4ECE Cookie \u8BFB\u53D6\u7528\u6237\u662F\u5426\u5DF2\u540C\u610F\uFF08\u6709\u6548\u671F 365 \u5929\uFF09\n const cookieName = complianceConfig?.cookieName || 'livechat_compliance_agreed'\n const [showComplianceDialog, setShowComplianceDialog] = React.useState(false)\n const [hasAgreedCompliance, setHasAgreedCompliance] = React.useState(() => {\n // \u521D\u59CB\u5316\u65F6\u68C0\u67E5 Cookie\n return complianceConfig ? Cookies.get(cookieName) !== undefined : true\n })\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText: Required<CommonText> = React.useMemo(\n () => ({\n ...DEFAULT_COMMON_TEXT,\n ...commonText,\n }),\n [commonText]\n )\n\n // \u72B6\u6001\u7BA1\u7406\n const chatState = useChatState({\n welcomeMessage,\n site,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n productCardRender,\n })\n\n const {\n messages,\n isOpen,\n userId,\n sessionId,\n inputValue,\n isStreaming,\n openChat,\n closeChat,\n setInputValue,\n addMessage,\n setMessages,\n clearMessages,\n handleSSEEvent,\n saveSession,\n clearSession,\n } = chatState\n\n // API \u8C03\u7528\n const { sendMessageStream, createSession } = useChatAPI({\n apiBaseUrl,\n headers,\n recaptchaConfig: {\n needRecaptcha: !!recaptchaSitekey, // \u6839\u636E sitekey \u81EA\u52A8\u5224\u65AD\u662F\u5426\u542F\u7528\n recaptchaSitekey,\n recaptchaAction,\n },\n onError,\n })\n\n // \u4F7F\u7528 ref \u5B58\u50A8\u6700\u65B0\u7684 handleSendMessage\uFF0C\u907F\u514D\u5FAA\u73AF\u4F9D\u8D56\n const handleSendMessageRef = React.useRef<(_message?: string) => Promise<void>>(async (_message?: string) => {})\n\n // \u6D88\u606F\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n const rendererRegistry = React.useMemo(() => {\n const registry = new MessageRendererRegistry()\n\n // \u6CE8\u518C\u9ED8\u8BA4\u6E32\u67D3\u5668\n registry.register('text', TextBlock)\n registry.register('product_card', ProductCard)\n registry.register('product_list', ProductList)\n registry.register('product_comparison', ProductComparisonRenderer)\n registry.register('policy', PolicyBlock)\n registry.register('thinking', ThinkingBlock)\n registry.register('error', ErrorBlock)\n registry.register('faq_list', FAQListRenderer)\n registry.register('promotion_list', PromotionListRenderer)\n registry.register('cart', CartCard)\n\n // \u6CE8\u518C\u5FEB\u6377\u56DE\u590D\u6E32\u67D3\u5668\uFF08\u5E26\u56DE\u8C03\uFF09\n const quickRepliesRenderer = createQuickRepliesRenderer((reply: QuickReply) => {\n // \u4F7F\u7528 ref \u8C03\u7528\u6700\u65B0\u7684 handleSendMessage\n handleSendMessageRef.current(reply.value)\n })\n registry.register('quick_replies', quickRepliesRenderer)\n\n // \u6CE8\u518C\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n if (customRenderers) {\n registry.registerMany(customRenderers)\n }\n\n return registry\n }, [customRenderers])\n\n /**\n * T043: \u6253\u5F00\u804A\u5929\u7A97\u53E3\u65F6\u521D\u59CB\u5316\u4F1A\u8BDD\n * \u4F7F\u7528 API v2.0.0 \u7684\u7EDF\u4E00\u63A5\u53E3\uFF1A\n * - \u5982\u679C\u6CA1\u6709 sessionId\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n * - \u5982\u679C\u6709 sessionId\uFF0C\u6062\u590D\u4F1A\u8BDD\u5E76\u52A0\u8F7D\u5386\u53F2\u6D88\u606F\n */\n useEffect(() => {\n if (!isOpen || !userId) return\n\n const currentSessionId = sessionId\n\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n handleCreateNewSession()\n } else {\n // \u6709\u4F1A\u8BDD\uFF0C\u5C1D\u8BD5\u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\n handleResumeSession(currentSessionId)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, userId])\n\n /**\n * \u89C4\u8303\u5316\u6D88\u606F\u683C\u5F0F\uFF08\u786E\u4FDD content \u662F\u6570\u7EC4\uFF09\n * \u540E\u7AEF\u8FD4\u56DE\u683C\u5F0F\uFF1A\n * - content: \u5B57\u7B26\u4E32\uFF08\u6587\u672C\u5185\u5BB9\uFF09\n * - structuredContent: \u6570\u7EC4\uFF08\u7ED3\u6784\u5316\u5185\u5BB9\uFF0C\u5982\u4EA7\u54C1\u5217\u8868\u3001\u653F\u7B56\u7B49\uFF09\n * \u9700\u8981\u5408\u5E76\u4E3A\u7EDF\u4E00\u7684 content \u6570\u7EC4\u683C\u5F0F\n */\n const normalizeMessage = useCallback(\n (message: any): Message => {\n // \u5982\u679C content \u5DF2\u7ECF\u662F\u6570\u7EC4\uFF0C\u76F4\u63A5\u8FD4\u56DE\n if (Array.isArray(message.content)) {\n return message as Message\n }\n\n const contentBlocks: MessageContent[] = []\n\n // \u5904\u7406\u6587\u672C\u5185\u5BB9\n if (typeof message.content === 'string' && message.content.trim()) {\n contentBlocks.push({\n type: 'text',\n text: message.content,\n })\n }\n\n // \u5904\u7406\u7ED3\u6784\u5316\u5185\u5BB9\n // \u5386\u53F2\u6D88\u606F\u683C\u5F0F: structured_content: [{type, data}]\n const structuredData = message.structuredContent || message.structured_content\n\n if (Array.isArray(structuredData)) {\n structuredData.forEach((block: any) => {\n if (block.type === 'product_list' && Array.isArray(block.data)) {\n // \u8F6C\u6362\u4EA7\u54C1\u5217\u8868\u6570\u636E\u7ED3\u6784 - data \u76F4\u63A5\u662F\u4EA7\u54C1\u6570\u7EC4\n contentBlocks.push({\n type: 'product_list',\n data: {\n products: transformProducts(block.data, site),\n title: undefined, // \u5386\u53F2\u6D88\u606F\u4E0D\u5305\u542B title\n commonText: mergedText,\n },\n })\n } else if (block.type === 'quick_replies' && block.data?.replies) {\n contentBlocks.push({\n type: 'quick_replies',\n data: {\n replies: block.data.replies,\n },\n })\n } else if (block.type === 'policy' && block.data?.title && block.data?.content) {\n contentBlocks.push({\n type: 'policy',\n data: {\n title: block.data.title,\n content: block.data.content,\n },\n })\n } else if (block.type === 'product_comparison' && block.data?.products && block.data?.dimensions) {\n // \u8F6C\u6362\u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\u5E76\u6CE8\u5165 onAddToCart \u56DE\u8C03\n contentBlocks.push({\n type: 'product_comparison',\n data: {\n products: transformProducts(block.data.products, site),\n dimensions: block.data.dimensions,\n onAddToCart: onAddToCart,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'faq_list' && block.data?.found !== undefined) {\n // FAQ \u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'faq_list',\n data: block.data,\n })\n } else if (block.type === 'promotion_list' && block.data?.found !== undefined) {\n // \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'promotion_list',\n data: {\n ...block.data,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'cart' && block.data?.id !== undefined) {\n // \u8D2D\u7269\u8F66\u5361\u7247 - \u8F6C\u6362\u540E\u7AEF\u6570\u636E\u683C\u5F0F\u5E76\u6CE8\u5165 onCart \u56DE\u8C03\n const transformedData = transformCartData(block.data as BackendCartData)\n contentBlocks.push({\n type: 'cart',\n data: {\n ...transformedData,\n onCart: onCart,\n commonText: mergedText,\n },\n })\n } else {\n // \u5176\u4ED6\u7C7B\u578B\u76F4\u63A5\u6DFB\u52A0\n contentBlocks.push(block)\n }\n })\n }\n\n // \u5982\u679C\u6CA1\u6709\u4EFB\u4F55\u5185\u5BB9\u5757\uFF0C\u8FD4\u56DE\u7A7A\u6587\u672C\u5757\n if (contentBlocks.length === 0) {\n contentBlocks.push({\n type: 'text',\n text: '',\n })\n }\n\n return {\n ...message,\n content: contentBlocks,\n } as Message\n },\n [site, onCart, onAddToCart, mergedText]\n )\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\n */\n const handleCreateNewSession = useCallback(async () => {\n if (!userId) return\n\n try {\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success) {\n // \u4FDD\u5B58\u65B0\u4F1A\u8BDD ID\n saveSession(response.sessionId)\n\n // \u6E05\u7A7A\u6D88\u606F\u5217\u8868\n clearMessages()\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u6B22\u8FCE\u6D88\u606F\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u9ED8\u8BA4\u503C\n const messageText = response.welcomeMessage || welcomeMessage\n\n if (messageText) {\n const welcomeContent: MessageContent[] = [{ type: 'text', text: messageText }]\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u5FEB\u6377\u95EE\u9898\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n // \u5C06\u540E\u7AEF\u7684 quickQuestions (\u5B57\u7B26\u4E32\u6570\u7EC4) \u8F6C\u6362\u4E3A QuickReply \u683C\u5F0F\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n // \u5982\u679C\u540E\u7AEF\u6CA1\u6709\u8FD4\u56DE\uFF0C\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to create new session:', error)\n onError?.(error as Error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n // \u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\u5230\u754C\u9762\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: isRecaptcha\n ? 'Your session has expired. Please refresh the page and try again.'\n : 'Failed to create session. Please refresh the page and try again.',\n code: isRecaptcha ? 'RECAPTCHA_ERROR' : 'SESSION_CREATE_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n }\n }, [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n saveSession,\n clearMessages,\n welcomeMessage,\n quickReplies,\n addMessage,\n onError,\n ])\n\n /**\n * \u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\uFF08\u4F7F\u7528\u65B0\u7684 API v2.0.0\uFF09\n */\n const handleResumeSession = useCallback(\n async (existingSessionId: string) => {\n try {\n const response = await createSession({\n user_id: userId,\n session_id: existingSessionId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success && response.resumed) {\n // \u4F1A\u8BDD\u6062\u590D\u6210\u529F\n\n // \u51C6\u5907\u6B22\u8FCE\u6D88\u606F\uFF08\u65E0\u8BBA\u662F\u5426\u6709\u5386\u53F2\u6D88\u606F\u90FD\u9700\u8981\uFF09\n const messageText = response.welcomeMessage || welcomeMessage\n const welcomeContent: MessageContent[] = messageText ? [{ type: 'text', text: messageText }] : []\n\n // \u6DFB\u52A0\u5FEB\u6377\u56DE\u590D\u5230\u6B22\u8FCE\u6D88\u606F\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n if (response.messages && response.messages.length > 0) {\n // \u6709\u5386\u53F2\u6D88\u606F\uFF0C\u89C4\u8303\u5316\u5E76\u52A0\u8F7D\uFF08\u8FC7\u6EE4\u6389 null/undefined \u503C\u548C\u7A7A\u5185\u5BB9\u6D88\u606F\uFF09\n const normalizedMessages = response.messages\n .filter((msg: any) => msg != null)\n .map(normalizeMessage)\n .filter((msg: Message) => msg.content && msg.content.length > 0 && !(msg.content.length === 1 && msg.content[0].type === 'text' && !msg.content[0].text))\n\n // \u5982\u679C\u6709\u6B22\u8FCE\u6D88\u606F\uFF0C\u5C06\u5176\u6DFB\u52A0\u5230\u5386\u53F2\u6D88\u606F\u7684\u5F00\u5934\n if (welcomeContent.length > 0) {\n const welcomeMsg: Message = {\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n }\n setMessages([welcomeMsg, ...normalizedMessages])\n } else {\n setMessages(normalizedMessages)\n }\n } else {\n // \u6CA1\u6709\u5386\u53F2\u6D88\u606F\uFF0C\u4EC5\u663E\u793A\u6B22\u8FCE\u6D88\u606F\n clearMessages()\n\n if (welcomeContent.length > 0) {\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } else if (!response.resumed) {\n // \u4F1A\u8BDD\u65E0\u6548\u6216\u8FC7\u671F\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n clearSession()\n handleCreateNewSession()\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to resume session:', error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n if (isRecaptcha) {\n // reCAPTCHA error - show refresh page message, don't retry\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Your session has expired. Please refresh the page and try again.',\n code: 'RECAPTCHA_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n } else {\n // Other errors - show message and try to create new session\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Failed to resume session. Creating a new session...',\n code: 'SESSION_RESUME_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n\n // \u6062\u590D\u5931\u8D25\uFF0C\u6E05\u7A7A\u4F1A\u8BDD\u5E76\u521B\u5EFA\u65B0\u7684\n clearSession()\n handleCreateNewSession()\n }\n }\n },\n [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n setMessages,\n clearSession,\n clearMessages,\n normalizeMessage,\n handleCreateNewSession,\n welcomeMessage,\n quickReplies,\n addMessage,\n ]\n )\n\n /**\n * \u53D1\u9001\u6D88\u606F\n */\n const handleSendMessage = useCallback(\n async (message?: string, isRetry: boolean = false) => {\n const textToSend = message || inputValue.trim()\n\n if (!textToSend) return\n\n // \u6E05\u7A7A\u8F93\u5165\u6846\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!message && !isRetry) {\n setInputValue('')\n }\n\n // \u8F93\u5165\u9A8C\u8BC1\n const sanitized = sanitizeInput(textToSend)\n if (!sanitized) {\n onError?.(new Error('Invalid message'))\n return\n }\n\n // \u6DFB\u52A0\u7528\u6237\u6D88\u606F\u5230\u754C\u9762\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!isRetry) {\n const userMessage = {\n id: `user-${Date.now()}`,\n role: 'user' as const,\n content: [{ type: 'text' as const, text: sanitized }],\n timestamp: Date.now(),\n }\n addMessage(userMessage)\n }\n\n // \u7ACB\u5373\u6DFB\u52A0\u601D\u8003\u72B6\u6001\u6D88\u606F\uFF0C\u63D0\u5347\u7528\u6237\u4F53\u9A8C\n const thinkingMessage = {\n id: `thinking-${Date.now()}`,\n role: 'assistant' as const,\n content: [{ type: 'thinking' as const, data: { status: 'thinking' } }],\n timestamp: Date.now(),\n }\n addMessage(thinkingMessage)\n\n // \u89E6\u53D1\u6D88\u606F\u53D1\u9001\u56DE\u8C03\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!isRetry) {\n onMessageSend?.(sanitized)\n }\n\n // \u6807\u8BB0\u662F\u5426\u68C0\u6D4B\u5230\u4F1A\u8BDD\u8FC7\u671F\n let sessionExpiredDetected = false\n\n try {\n // \u786E\u4FDD\u6709 sessionId\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u5148\u521B\u5EFA\u4F1A\u8BDD\n let currentSessionId = sessionId\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n if (response.success) {\n currentSessionId = response.sessionId\n saveSession(currentSessionId)\n } else {\n throw new Error('Failed to create session')\n }\n }\n\n // \u6784\u5EFA\u8BF7\u6C42\u53C2\u6570\uFF08session_id \u73B0\u5728\u662F\u5FC5\u586B\u7684\uFF09\n const requestPayload: ChatStreamRequest = {\n message: sanitized,\n user_id: userId,\n session_id: currentSessionId,\n context: {\n cartId: cartId,\n accessToken: accessToken,\n real_user_id: loginUserId,\n },\n }\n\n // \u53D1\u9001\u6D88\u606F\u5230\u540E\u7AEF\n await sendMessageStream(requestPayload, event => {\n // \u5904\u7406 SSE \u4E8B\u4EF6\n handleSSEEvent(event)\n\n // \u7279\u6B8A\u5904\u7406\uFF1A\u4F1A\u8BDD\u8FC7\u671F\uFF08error \u4E8B\u4EF6\u4E14 type \u4E3A validation_error\uFF09\n if (event.event === 'error' && event.data.type === 'validation_error') {\n sessionExpiredDetected = true\n clearSession()\n }\n })\n\n // \u5982\u679C\u68C0\u6D4B\u5230\u4F1A\u8BDD\u8FC7\u671F\u4E14\u4E0D\u662F\u91CD\u8BD5\uFF0C\u81EA\u52A8\u521B\u5EFA\u65B0\u4F1A\u8BDD\u5E76\u91CD\u8BD5\n if (sessionExpiredDetected && !isRetry) {\n console.log('[LiveChatWidget] Session expired (validation_error), creating new session and retrying...')\n\n // \u79FB\u9664 thinking \u6D88\u606F\n const messagesWithoutThinking = messages.filter(msg => msg.id !== thinkingMessage.id)\n setMessages(messagesWithoutThinking)\n\n // \u521B\u5EFA\u65B0\u4F1A\u8BDD\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success) {\n saveSession(response.sessionId)\n // \u91CD\u8BD5\u53D1\u9001\u6D88\u606F\n await handleSendMessage(sanitized, true)\n } else {\n throw new Error('Failed to recreate session after expiration')\n }\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to send message:', error)\n onError?.(error as Error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n // Determine error message based on error type\n let errorMessage: string\n let errorCode: string\n\n if (isRecaptcha) {\n errorMessage = 'Your session has expired. Please refresh the page and try again.'\n errorCode = 'RECAPTCHA_ERROR'\n } else if (sessionExpiredDetected) {\n errorMessage = 'Your session has expired. We tried to reconnect but failed. Please try again.'\n errorCode = 'SESSION_EXPIRED'\n } else {\n errorMessage = 'Failed to send message. Please check your network connection and try again.'\n errorCode = 'NETWORK_ERROR'\n }\n\n // \u79FB\u9664\u521A\u624D\u6DFB\u52A0\u7684 thinking \u6D88\u606F\uFF0C\u5E76\u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\n const messagesWithoutThinking = messages.filter(msg => msg.id !== thinkingMessage.id)\n setMessages([\n ...messagesWithoutThinking,\n {\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: errorMessage,\n code: errorCode,\n },\n },\n ],\n timestamp: Date.now(),\n },\n ])\n }\n },\n [\n inputValue,\n userId,\n sessionId,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n messages,\n setInputValue,\n addMessage,\n setMessages,\n createSession,\n sendMessageStream,\n handleSSEEvent,\n saveSession,\n clearSession,\n onMessageSend,\n onError,\n ]\n )\n\n // \u66F4\u65B0 ref \u4EE5\u4FDD\u6301\u6700\u65B0\u7684 handleSendMessage\n React.useEffect(() => {\n handleSendMessageRef.current = handleSendMessage\n }, [handleSendMessage])\n\n /**\n * \u5904\u7406\u6C14\u6CE1\u6309\u94AE\u70B9\u51FB\n * \u5982\u679C\u914D\u7F6E\u4E86\u6CD5\u89C4\u534F\u8BAE\u4E14\u7528\u6237\u672A\u540C\u610F\uFF0C\u5148\u663E\u793A\u6CD5\u89C4\u5F39\u7A97\n * \u5426\u5219\u76F4\u63A5\u6253\u5F00\u804A\u5929\u7A97\u53E3\n */\n const handleBubbleClick = useCallback(() => {\n if (complianceConfig && !hasAgreedCompliance) {\n // \u663E\u793A\u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97\n setShowComplianceDialog(true)\n } else {\n // \u76F4\u63A5\u6253\u5F00\u804A\u5929\u7A97\u53E3\n openChat()\n }\n }, [complianceConfig, hasAgreedCompliance, openChat])\n\n /**\n * \u5904\u7406\u7528\u6237\u540C\u610F\u6CD5\u89C4\u534F\u8BAE\n */\n const handleComplianceAgree = useCallback(() => {\n // \u8BBE\u7F6E\u540C\u610F\u72B6\u6001\n setHasAgreedCompliance(true)\n setShowComplianceDialog(false)\n\n // \u4FDD\u5B58\u5230 Cookie\uFF08\u6709\u6548\u671F 365 \u5929\uFF09\n Cookies.set(cookieName, 'true', { expires: 365 })\n\n // \u540C\u610F\u540E\u7ACB\u5373\u6253\u5F00\u804A\u5929\u7A97\u53E3\n openChat()\n }, [openChat, cookieName])\n\n /**\n * \u5904\u7406\u6CD5\u89C4\u5F39\u7A97\u5173\u95ED\n */\n const handleComplianceClose = useCallback(() => {\n setShowComplianceDialog(false)\n }, [])\n\n return (\n <>\n {/* \u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97 */}\n {complianceConfig && (\n <ComplianceDialog\n open={showComplianceDialog}\n config={complianceConfig}\n onAgree={handleComplianceAgree}\n onClose={handleComplianceClose}\n />\n )}\n\n {/* \u6C14\u6CE1\u6309\u94AE */}\n <ChatBubble\n position={position}\n onClick={handleBubbleClick}\n visible={!isOpen && !showComplianceDialog}\n iconImageUrl={chatBubbleIcon}\n />\n\n {/* \u804A\u5929\u7A97\u53E3\uFF08\u4F7F\u7528 Radix UI Dialog\uFF09 */}\n <Dialog.Root open={isOpen} onOpenChange={open => (open ? openChat() : closeChat())}>\n <Dialog.Portal>\n <Dialog.Content\n className=\"livechat-window-enter\"\n style={{\n position: 'fixed',\n zIndex: 9998,\n }}\n >\n <ChatWindow\n messages={messages}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSend={() => handleSendMessage()}\n onClose={closeChat}\n onNewSession={handleCreateNewSession}\n title={title}\n logoUrl={logoUrl}\n isSending={isStreaming}\n rendererRegistry={rendererRegistry}\n inputPlaceholder=\"\"\n onAddToCart={onAddToCart}\n showNewSessionButton={showNewSessionButton}\n bottomTips={bottomTips}\n />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </>\n )\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["Fragment", "jsx", "jsxs", "React", "useEffect", "useCallback", "Dialog", "DEFAULT_COMMON_TEXT", "ChatBubble", "ChatWindow", "ComplianceDialog", "useChatState", "useChatAPI", "MessageRendererRegistry", "sanitizeInput", "transformProducts", "transformCartData", "Cookies", "TextBlock", "ProductCard", "ProductList", "ProductComparisonRenderer", "PolicyBlock", "createQuickRepliesRenderer", "ThinkingBlock", "ErrorBlock", "FAQListRenderer", "PromotionListRenderer", "CartCard", "LiveChatWidget", "apiBaseUrl", "headers", "recaptchaSitekey", "recaptchaAction", "site", "channelCode", "loginUserId", "cartId", "accessToken", "position", "welcomeMessage", "quickReplies", "customRenderers", "logoUrl", "title", "chatBubbleIcon", "open", "onOpenChange", "onOpen", "onClose", "onMessageSend", "onError", "onTextMessage", "onProductList", "onPromotionList", "onAddToCart", "onCart", "showNewSessionButton", "commonText", "productCardRender", "bottomTips", "complianceConfig", "cookieName", "showComplianceDialog", "setShowComplianceDialog", "hasAgreedCompliance", "setHasAgreedCompliance", "mergedText", "chatState", "messages", "isOpen", "userId", "sessionId", "inputValue", "isStreaming", "openChat", "closeChat", "setInputValue", "addMessage", "setMessages", "clearMessages", "handleSSEEvent", "saveSession", "clearSession", "sendMessageStream", "createSession", "handleSendMessageRef", "_message", "rendererRegistry", "registry", "quickRepliesRenderer", "reply", "currentSessionId", "handleResumeSession", "handleCreateNewSession", "normalizeMessage", "message", "contentBlocks", "structuredData", "block", "transformedData", "response", "messageText", "welcomeContent", "questions", "quickRepliesFromBackend", "question", "index", "error", "isRecaptcha", "existingSessionId", "normalizedMessages", "msg", "welcomeMsg", "handleSendMessage", "isRetry", "textToSend", "sanitized", "userMessage", "thinkingMessage", "sessionExpiredDetected", "event", "messagesWithoutThinking", "errorMessage", "errorCode", "handleBubbleClick", "handleComplianceAgree", "handleComplianceClose"]
|
|
4
|
+
"sourcesContent": ["/**\n * LiveChat \u4E3B\u7EC4\u4EF6\n * \u96C6\u6210\u6240\u6709\u5B50\u7EC4\u4EF6\uFF0C\u63D0\u4F9B\u5B8C\u6574\u7684\u804A\u5929\u529F\u80FD\n * \u57FA\u4E8E specs/livechat-widget/plan.md \u7684\u4E09\u5C42\u67B6\u6784\u8BBE\u8BA1\n */\n\nimport React, { useEffect, useCallback } from 'react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type {\n LiveChatWidgetProps,\n QuickReply,\n Message,\n MessageContent,\n ChatStreamRequest,\n BackendCartData,\n CommonText,\n} from './types'\nimport { DEFAULT_COMMON_TEXT } from './constants'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport { ComplianceDialog } from './components/ComplianceDialog'\nimport { useChatState } from './hooks/useChatState'\nimport { useChatAPI } from './hooks/useChatAPI'\nimport { MessageRendererRegistry } from './utils/messageRenderers'\nimport { sanitizeInput } from './utils/validation'\nimport { transformProducts } from './utils/productTransformers.js'\nimport { transformCartData } from './utils/cartTransformers.js'\nimport Cookies from 'js-cookie'\nimport {\n TextBlock,\n ProductCard,\n ProductList,\n ProductComparisonRenderer,\n PolicyBlock,\n createQuickRepliesRenderer,\n ThinkingBlock,\n ErrorBlock,\n FAQListRenderer,\n PromotionListRenderer,\n CartCard,\n} from './components/MessageContent/index.js'\n\n/**\n * LiveChat \u804A\u5929\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u6C14\u6CE1\u5F39\u7A97\u804A\u5929\u754C\u9762\n * - SSE \u6D41\u5F0F\u6D88\u606F\u63A5\u6536\n * - \u4F1A\u8BDD\u7BA1\u7406\uFF08userId, sessionId\uFF09\n * - \u5386\u53F2\u6D88\u606F\u52A0\u8F7D\n * - \u591A\u79CD\u6D88\u606F\u7C7B\u578B\u6E32\u67D3\n * - \u81EA\u5B9A\u4E49\u6269\u5C55\u673A\u5236\n * - reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\n *\n * \u67B6\u6784\uFF1A\n * - UI Layer: ChatBubble, ChatWindow, MessageList, etc.\n * - Logic Layer: useChatState, useChatAPI, useSession\n * - Core Layer: MessageRendererRegistry, \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n *\n * @example\n * ```tsx\n * // \u57FA\u7840\u4F7F\u7528\uFF08\u4F7F\u7528\u9ED8\u8BA4\u4F4D\u7F6E\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * welcomeMessage=\"\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\"\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49\u4F4D\u7F6E\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * position={{ bottom: \"20px\", right: \"30px\" }}\n * onMessageSend={(msg) => console.log('Sent:', msg)}\n * />\n *\n * // \u542F\u7528 reCAPTCHA v3 \u5B89\u5168\u9632\u62A4\uFF08\u63D0\u4F9B sitekey \u5373\u81EA\u52A8\u542F\u7528\uFF09\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * recaptchaSitekey=\"6LfS4J4pAAAAACX1e_WrxutmxxzCK7FU4WzVqL14\"\n * recaptchaAction=\"livechat\"\n * />\n *\n * // \u4F7F\u7528\u81EA\u5B9A\u4E49 headers \u548C reCAPTCHA\n * <LiveChatWidget\n * apiBaseUrl=\"https://beta-api-livechat.anker.com\"\n * site=\"www.eufy.com\"\n * headers={{\n * \"Authorization\": \"Bearer your-token\",\n * \"X-Custom-Header\": \"value\"\n * }}\n * recaptchaSitekey=\"your-site-key\"\n * />\n * ```\n */\nexport const LiveChatWidget: React.FC<LiveChatWidgetProps> = ({\n apiBaseUrl,\n headers,\n recaptchaSitekey,\n recaptchaAction,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n position,\n welcomeMessage,\n quickReplies,\n customRenderers,\n logoUrl,\n title,\n chatBubbleIcon,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n showNewSessionButton,\n commonText,\n productCardRender,\n bottomTips,\n complianceConfig,\n}) => {\n // \u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97\u72B6\u6001\n // \u4ECE Cookie \u8BFB\u53D6\u7528\u6237\u662F\u5426\u5DF2\u540C\u610F\uFF08\u6709\u6548\u671F 365 \u5929\uFF09\n const cookieName = complianceConfig?.cookieName || 'livechat_compliance_agreed'\n const [showComplianceDialog, setShowComplianceDialog] = React.useState(false)\n const [hasAgreedCompliance, setHasAgreedCompliance] = React.useState(() => {\n // \u521D\u59CB\u5316\u65F6\u68C0\u67E5 Cookie\n return complianceConfig ? Cookies.get(cookieName) !== undefined : true\n })\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText: Required<CommonText> = React.useMemo(\n () => ({\n ...DEFAULT_COMMON_TEXT,\n ...commonText,\n }),\n [commonText]\n )\n\n // \u72B6\u6001\u7BA1\u7406\n const chatState = useChatState({\n welcomeMessage,\n site,\n open,\n onOpenChange,\n onOpen,\n onClose,\n onMessageSend,\n onError,\n onTextMessage,\n onProductList,\n onPromotionList,\n onAddToCart,\n onCart,\n productCardRender,\n })\n\n const {\n messages,\n isOpen,\n userId,\n sessionId,\n inputValue,\n isStreaming,\n openChat,\n closeChat,\n setInputValue,\n addMessage,\n setMessages,\n clearMessages,\n handleSSEEvent,\n saveSession,\n clearSession,\n } = chatState\n\n // \u521D\u59CB\u5316\u52A0\u8F7D\u72B6\u6001\uFF08\u7528\u6237\u672A\u914D\u7F6E\u6B22\u8FCE\u8BED\u65F6\uFF0C\u663E\u793A loading \u76F4\u5230\u63A5\u53E3\u8FD4\u56DE\uFF09\n const [isInitializing, setIsInitializing] = React.useState(false)\n\n // API \u8C03\u7528\n const { sendMessageStream, createSession } = useChatAPI({\n apiBaseUrl,\n headers,\n recaptchaConfig: {\n needRecaptcha: !!recaptchaSitekey, // \u6839\u636E sitekey \u81EA\u52A8\u5224\u65AD\u662F\u5426\u542F\u7528\n recaptchaSitekey,\n recaptchaAction,\n },\n onError,\n })\n\n // \u4F7F\u7528 ref \u5B58\u50A8\u6700\u65B0\u7684 handleSendMessage\uFF0C\u907F\u514D\u5FAA\u73AF\u4F9D\u8D56\n const handleSendMessageRef = React.useRef<(_message?: string) => Promise<void>>(async (_message?: string) => {})\n\n // \u6D88\u606F\u6E32\u67D3\u5668\u6CE8\u518C\u8868\n const rendererRegistry = React.useMemo(() => {\n const registry = new MessageRendererRegistry()\n\n // \u6CE8\u518C\u9ED8\u8BA4\u6E32\u67D3\u5668\n registry.register('text', TextBlock)\n registry.register('product_card', ProductCard)\n registry.register('product_list', ProductList)\n registry.register('product_comparison', ProductComparisonRenderer)\n registry.register('policy', PolicyBlock)\n registry.register('thinking', ThinkingBlock)\n registry.register('error', ErrorBlock)\n registry.register('faq_list', FAQListRenderer)\n registry.register('promotion_list', PromotionListRenderer)\n registry.register('cart', CartCard)\n\n // \u6CE8\u518C\u5FEB\u6377\u56DE\u590D\u6E32\u67D3\u5668\uFF08\u5E26\u56DE\u8C03\uFF09\n const quickRepliesRenderer = createQuickRepliesRenderer((reply: QuickReply) => {\n // \u4F7F\u7528 ref \u8C03\u7528\u6700\u65B0\u7684 handleSendMessage\n handleSendMessageRef.current(reply.value)\n })\n registry.register('quick_replies', quickRepliesRenderer)\n\n // \u6CE8\u518C\u81EA\u5B9A\u4E49\u6E32\u67D3\u5668\n if (customRenderers) {\n registry.registerMany(customRenderers)\n }\n\n return registry\n }, [customRenderers])\n\n /**\n * T043: \u6253\u5F00\u804A\u5929\u7A97\u53E3\u65F6\u521D\u59CB\u5316\u4F1A\u8BDD\n * \u4F7F\u7528 API v2.0.0 \u7684\u7EDF\u4E00\u63A5\u53E3\uFF1A\n * - \u5982\u679C\u6CA1\u6709 sessionId\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n * - \u5982\u679C\u6709 sessionId\uFF0C\u6062\u590D\u4F1A\u8BDD\u5E76\u52A0\u8F7D\u5386\u53F2\u6D88\u606F\n */\n useEffect(() => {\n if (!isOpen || !userId) return\n\n const currentSessionId = sessionId\n\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n handleCreateNewSession()\n } else {\n // \u6709\u4F1A\u8BDD\uFF0C\u5C1D\u8BD5\u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\n handleResumeSession(currentSessionId)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, userId])\n\n /**\n * \u89C4\u8303\u5316\u6D88\u606F\u683C\u5F0F\uFF08\u786E\u4FDD content \u662F\u6570\u7EC4\uFF09\n * \u540E\u7AEF\u8FD4\u56DE\u683C\u5F0F\uFF1A\n * - content: \u5B57\u7B26\u4E32\uFF08\u6587\u672C\u5185\u5BB9\uFF09\n * - structuredContent: \u6570\u7EC4\uFF08\u7ED3\u6784\u5316\u5185\u5BB9\uFF0C\u5982\u4EA7\u54C1\u5217\u8868\u3001\u653F\u7B56\u7B49\uFF09\n * \u9700\u8981\u5408\u5E76\u4E3A\u7EDF\u4E00\u7684 content \u6570\u7EC4\u683C\u5F0F\n */\n const normalizeMessage = useCallback(\n (message: any): Message => {\n // \u5982\u679C content \u5DF2\u7ECF\u662F\u6570\u7EC4\uFF0C\u76F4\u63A5\u8FD4\u56DE\n if (Array.isArray(message.content)) {\n return message as Message\n }\n\n const contentBlocks: MessageContent[] = []\n\n // \u5904\u7406\u6587\u672C\u5185\u5BB9\n if (typeof message.content === 'string' && message.content.trim()) {\n contentBlocks.push({\n type: 'text',\n text: message.content,\n })\n }\n\n // \u5904\u7406\u7ED3\u6784\u5316\u5185\u5BB9\n // \u5386\u53F2\u6D88\u606F\u683C\u5F0F: structured_content: [{type, data}]\n const structuredData = message.structuredContent || message.structured_content\n\n if (Array.isArray(structuredData)) {\n structuredData.forEach((block: any) => {\n if (block.type === 'product_list' && Array.isArray(block.data)) {\n // \u8F6C\u6362\u4EA7\u54C1\u5217\u8868\u6570\u636E\u7ED3\u6784 - data \u76F4\u63A5\u662F\u4EA7\u54C1\u6570\u7EC4\n contentBlocks.push({\n type: 'product_list',\n data: {\n products: transformProducts(block.data, site),\n title: undefined, // \u5386\u53F2\u6D88\u606F\u4E0D\u5305\u542B title\n commonText: mergedText,\n },\n })\n } else if (block.type === 'quick_replies' && block.data?.replies) {\n contentBlocks.push({\n type: 'quick_replies',\n data: {\n replies: block.data.replies,\n },\n })\n } else if (block.type === 'policy' && block.data?.title && block.data?.content) {\n contentBlocks.push({\n type: 'policy',\n data: {\n title: block.data.title,\n content: block.data.content,\n },\n })\n } else if (block.type === 'product_comparison' && block.data?.products && block.data?.dimensions) {\n // \u8F6C\u6362\u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\u5E76\u6CE8\u5165 onAddToCart \u56DE\u8C03\n contentBlocks.push({\n type: 'product_comparison',\n data: {\n products: transformProducts(block.data.products, site),\n dimensions: block.data.dimensions,\n onAddToCart: onAddToCart,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'faq_list' && block.data?.found !== undefined) {\n // FAQ \u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'faq_list',\n data: block.data,\n })\n } else if (block.type === 'promotion_list' && block.data?.found !== undefined) {\n // \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u5361\u7247 - \u76F4\u63A5\u4F7F\u7528\u540E\u7AEF\u6570\u636E\n contentBlocks.push({\n type: 'promotion_list',\n data: {\n ...block.data,\n commonText: mergedText,\n },\n })\n } else if (block.type === 'cart' && block.data?.id !== undefined) {\n // \u8D2D\u7269\u8F66\u5361\u7247 - \u8F6C\u6362\u540E\u7AEF\u6570\u636E\u683C\u5F0F\u5E76\u6CE8\u5165 onCart \u56DE\u8C03\n const transformedData = transformCartData(block.data as BackendCartData)\n contentBlocks.push({\n type: 'cart',\n data: {\n ...transformedData,\n onCart: onCart,\n commonText: mergedText,\n },\n })\n } else {\n // \u5176\u4ED6\u7C7B\u578B\u76F4\u63A5\u6DFB\u52A0\n contentBlocks.push(block)\n }\n })\n }\n\n // \u5982\u679C\u6CA1\u6709\u4EFB\u4F55\u5185\u5BB9\u5757\uFF0C\u8FD4\u56DE\u7A7A\u6587\u672C\u5757\n if (contentBlocks.length === 0) {\n contentBlocks.push({\n type: 'text',\n text: '',\n })\n }\n\n return {\n ...message,\n content: contentBlocks,\n } as Message\n },\n [site, onCart, onAddToCart, mergedText]\n )\n\n /**\n * \u521B\u5EFA\u65B0\u4F1A\u8BDD\n */\n const handleCreateNewSession = useCallback(async () => {\n if (!userId) return\n\n // \u5982\u679C\u7528\u6237\u6CA1\u6709\u914D\u7F6E\u6B22\u8FCE\u8BED\uFF0C\u663E\u793A loading \u72B6\u6001\n if (!welcomeMessage) {\n setIsInitializing(true)\n }\n\n try {\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success) {\n // \u4FDD\u5B58\u65B0\u4F1A\u8BDD ID\n saveSession(response.sessionId)\n\n // \u6E05\u7A7A\u6D88\u606F\u5217\u8868\n clearMessages()\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u6B22\u8FCE\u6D88\u606F\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u9ED8\u8BA4\u503C\n const messageText = response.welcomeMessage || welcomeMessage\n\n if (messageText) {\n const welcomeContent: MessageContent[] = [{ type: 'text', text: messageText }]\n\n // \u4F7F\u7528\u540E\u7AEF\u8FD4\u56DE\u7684\u5FEB\u6377\u95EE\u9898\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n // \u5C06\u540E\u7AEF\u7684 quickQuestions (\u5B57\u7B26\u4E32\u6570\u7EC4) \u8F6C\u6362\u4E3A QuickReply \u683C\u5F0F\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n // \u5982\u679C\u540E\u7AEF\u6CA1\u6709\u8FD4\u56DE\uFF0C\u4F7F\u7528 props \u4E2D\u7684\u5FEB\u6377\u56DE\u590D\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to create new session:', error)\n onError?.(error as Error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n // \u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\u5230\u754C\u9762\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: isRecaptcha\n ? 'Your session has expired. Please refresh the page and try again.'\n : 'Failed to create session. Please refresh the page and try again.',\n code: isRecaptcha ? 'RECAPTCHA_ERROR' : 'SESSION_CREATE_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n } finally {\n // \u63A5\u53E3\u8FD4\u56DE\u540E\u5173\u95ED loading \u72B6\u6001\n setIsInitializing(false)\n }\n }, [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n saveSession,\n clearMessages,\n welcomeMessage,\n quickReplies,\n addMessage,\n onError,\n ])\n\n /**\n * \u6062\u590D\u4F1A\u8BDD\u548C\u5386\u53F2\u6D88\u606F\uFF08\u4F7F\u7528\u65B0\u7684 API v2.0.0\uFF09\n */\n const handleResumeSession = useCallback(\n async (existingSessionId: string) => {\n // \u5982\u679C\u7528\u6237\u6CA1\u6709\u914D\u7F6E\u6B22\u8FCE\u8BED\uFF0C\u663E\u793A loading \u72B6\u6001\n if (!welcomeMessage) {\n setIsInitializing(true)\n }\n\n try {\n const response = await createSession({\n user_id: userId,\n session_id: existingSessionId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success && response.resumed) {\n // \u4F1A\u8BDD\u6062\u590D\u6210\u529F\n\n // \u51C6\u5907\u6B22\u8FCE\u6D88\u606F\uFF08\u65E0\u8BBA\u662F\u5426\u6709\u5386\u53F2\u6D88\u606F\u90FD\u9700\u8981\uFF09\n const messageText = response.welcomeMessage || welcomeMessage\n const welcomeContent: MessageContent[] = messageText ? [{ type: 'text', text: messageText }] : []\n\n // \u6DFB\u52A0\u5FEB\u6377\u56DE\u590D\u5230\u6B22\u8FCE\u6D88\u606F\n const questions = response.quickQuestions\n if (questions && questions.length > 0) {\n const quickRepliesFromBackend = questions.map((question, index) => ({\n id: `quick-${index}`,\n label: question,\n value: question,\n }))\n\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickRepliesFromBackend,\n },\n })\n } else if (quickReplies && quickReplies.length > 0) {\n welcomeContent.push({\n type: 'quick_replies',\n data: {\n replies: quickReplies,\n },\n })\n }\n\n if (response.messages && response.messages.length > 0) {\n // \u6709\u5386\u53F2\u6D88\u606F\uFF0C\u89C4\u8303\u5316\u5E76\u52A0\u8F7D\uFF08\u8FC7\u6EE4\u6389 null/undefined \u503C\u548C\u7A7A\u5185\u5BB9\u6D88\u606F\uFF09\n const normalizedMessages = response.messages\n .filter((msg: any) => msg != null)\n .map(normalizeMessage)\n .filter((msg: Message) => msg.content && msg.content.length > 0 && !(msg.content.length === 1 && msg.content[0].type === 'text' && !msg.content[0].text))\n\n // \u5982\u679C\u6709\u6B22\u8FCE\u6D88\u606F\uFF0C\u5C06\u5176\u6DFB\u52A0\u5230\u5386\u53F2\u6D88\u606F\u7684\u5F00\u5934\n if (welcomeContent.length > 0) {\n const welcomeMsg: Message = {\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n }\n setMessages([welcomeMsg, ...normalizedMessages])\n } else {\n setMessages(normalizedMessages)\n }\n } else {\n // \u6CA1\u6709\u5386\u53F2\u6D88\u606F\uFF0C\u4EC5\u663E\u793A\u6B22\u8FCE\u6D88\u606F\n clearMessages()\n\n if (welcomeContent.length > 0) {\n addMessage({\n id: `welcome-${Date.now()}`,\n role: 'assistant',\n content: welcomeContent,\n timestamp: Date.now(),\n })\n }\n }\n } else if (!response.resumed) {\n // \u4F1A\u8BDD\u65E0\u6548\u6216\u8FC7\u671F\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n clearSession()\n handleCreateNewSession()\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to resume session:', error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n if (isRecaptcha) {\n // reCAPTCHA error - show refresh page message, don't retry\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Your session has expired. Please refresh the page and try again.',\n code: 'RECAPTCHA_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n } else {\n // Other errors - show message and try to create new session\n addMessage({\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: 'Failed to resume session. Creating a new session...',\n code: 'SESSION_RESUME_ERROR',\n },\n },\n ],\n timestamp: Date.now(),\n })\n\n // \u6062\u590D\u5931\u8D25\uFF0C\u6E05\u7A7A\u4F1A\u8BDD\u5E76\u521B\u5EFA\u65B0\u7684\n clearSession()\n handleCreateNewSession()\n }\n } finally {\n // \u63A5\u53E3\u8FD4\u56DE\u540E\u5173\u95ED loading \u72B6\u6001\n setIsInitializing(false)\n }\n },\n [\n userId,\n site,\n channelCode,\n loginUserId,\n createSession,\n setMessages,\n clearSession,\n clearMessages,\n normalizeMessage,\n handleCreateNewSession,\n welcomeMessage,\n quickReplies,\n addMessage,\n ]\n )\n\n /**\n * \u53D1\u9001\u6D88\u606F\n */\n const handleSendMessage = useCallback(\n async (message?: string, isRetry: boolean = false) => {\n const textToSend = message || inputValue.trim()\n\n if (!textToSend) return\n\n // \u6E05\u7A7A\u8F93\u5165\u6846\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!message && !isRetry) {\n setInputValue('')\n }\n\n // \u8F93\u5165\u9A8C\u8BC1\n const sanitized = sanitizeInput(textToSend)\n if (!sanitized) {\n onError?.(new Error('Invalid message'))\n return\n }\n\n // \u6DFB\u52A0\u7528\u6237\u6D88\u606F\u5230\u754C\u9762\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!isRetry) {\n const userMessage = {\n id: `user-${Date.now()}`,\n role: 'user' as const,\n content: [{ type: 'text' as const, text: sanitized }],\n timestamp: Date.now(),\n }\n addMessage(userMessage)\n }\n\n // \u7ACB\u5373\u6DFB\u52A0\u601D\u8003\u72B6\u6001\u6D88\u606F\uFF0C\u63D0\u5347\u7528\u6237\u4F53\u9A8C\n const thinkingMessage = {\n id: `thinking-${Date.now()}`,\n role: 'assistant' as const,\n content: [{ type: 'thinking' as const, data: { status: 'thinking' } }],\n timestamp: Date.now(),\n }\n addMessage(thinkingMessage)\n\n // \u89E6\u53D1\u6D88\u606F\u53D1\u9001\u56DE\u8C03\uFF08\u4EC5\u5728\u975E\u91CD\u8BD5\u65F6\uFF09\n if (!isRetry) {\n onMessageSend?.(sanitized)\n }\n\n // \u6807\u8BB0\u662F\u5426\u68C0\u6D4B\u5230\u4F1A\u8BDD\u8FC7\u671F\n let sessionExpiredDetected = false\n\n try {\n // \u786E\u4FDD\u6709 sessionId\uFF0C\u5982\u679C\u6CA1\u6709\u5219\u5148\u521B\u5EFA\u4F1A\u8BDD\n let currentSessionId = sessionId\n if (!currentSessionId) {\n // \u6CA1\u6709\u4F1A\u8BDD\uFF0C\u521B\u5EFA\u65B0\u4F1A\u8BDD\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n if (response.success) {\n currentSessionId = response.sessionId\n saveSession(currentSessionId)\n } else {\n throw new Error('Failed to create session')\n }\n }\n\n // \u6784\u5EFA\u8BF7\u6C42\u53C2\u6570\uFF08session_id \u73B0\u5728\u662F\u5FC5\u586B\u7684\uFF09\n const requestPayload: ChatStreamRequest = {\n message: sanitized,\n user_id: userId,\n session_id: currentSessionId,\n context: {\n cartId: cartId,\n accessToken: accessToken,\n real_user_id: loginUserId,\n },\n }\n\n // \u53D1\u9001\u6D88\u606F\u5230\u540E\u7AEF\n await sendMessageStream(requestPayload, event => {\n // \u5904\u7406 SSE \u4E8B\u4EF6\n handleSSEEvent(event)\n\n // \u7279\u6B8A\u5904\u7406\uFF1A\u4F1A\u8BDD\u8FC7\u671F\uFF08error \u4E8B\u4EF6\u4E14 type \u4E3A validation_error\uFF09\n if (event.event === 'error' && event.data.type === 'validation_error') {\n sessionExpiredDetected = true\n clearSession()\n }\n })\n\n // \u5982\u679C\u68C0\u6D4B\u5230\u4F1A\u8BDD\u8FC7\u671F\u4E14\u4E0D\u662F\u91CD\u8BD5\uFF0C\u81EA\u52A8\u521B\u5EFA\u65B0\u4F1A\u8BDD\u5E76\u91CD\u8BD5\n if (sessionExpiredDetected && !isRetry) {\n console.log('[LiveChatWidget] Session expired (validation_error), creating new session and retrying...')\n\n // \u79FB\u9664 thinking \u6D88\u606F\n const messagesWithoutThinking = messages.filter(msg => msg.id !== thinkingMessage.id)\n setMessages(messagesWithoutThinking)\n\n // \u521B\u5EFA\u65B0\u4F1A\u8BDD\n const response = await createSession({\n user_id: userId,\n site: site,\n channel_code: channelCode,\n real_user_id: loginUserId,\n })\n\n if (response.success) {\n saveSession(response.sessionId)\n // \u91CD\u8BD5\u53D1\u9001\u6D88\u606F\n await handleSendMessage(sanitized, true)\n } else {\n throw new Error('Failed to recreate session after expiration')\n }\n }\n } catch (error) {\n console.error('[LiveChatWidget] Failed to send message:', error)\n onError?.(error as Error)\n\n // Check if it's a reCAPTCHA error\n const isRecaptcha = (error as any)?.type === 'GoogleRecaptchaError'\n\n // Determine error message based on error type\n let errorMessage: string\n let errorCode: string\n\n if (isRecaptcha) {\n errorMessage = 'Your session has expired. Please refresh the page and try again.'\n errorCode = 'RECAPTCHA_ERROR'\n } else if (sessionExpiredDetected) {\n errorMessage = 'Your session has expired. We tried to reconnect but failed. Please try again.'\n errorCode = 'SESSION_EXPIRED'\n } else {\n errorMessage = 'Failed to send message. Please check your network connection and try again.'\n errorCode = 'NETWORK_ERROR'\n }\n\n // \u79FB\u9664\u521A\u624D\u6DFB\u52A0\u7684 thinking \u6D88\u606F\uFF0C\u5E76\u6DFB\u52A0\u9519\u8BEF\u6D88\u606F\n const messagesWithoutThinking = messages.filter(msg => msg.id !== thinkingMessage.id)\n setMessages([\n ...messagesWithoutThinking,\n {\n id: `error-${Date.now()}`,\n role: 'system',\n content: [\n {\n type: 'error',\n data: {\n message: errorMessage,\n code: errorCode,\n },\n },\n ],\n timestamp: Date.now(),\n },\n ])\n }\n },\n [\n inputValue,\n userId,\n sessionId,\n site,\n channelCode,\n loginUserId,\n cartId,\n accessToken,\n messages,\n setInputValue,\n addMessage,\n setMessages,\n createSession,\n sendMessageStream,\n handleSSEEvent,\n saveSession,\n clearSession,\n onMessageSend,\n onError,\n ]\n )\n\n // \u66F4\u65B0 ref \u4EE5\u4FDD\u6301\u6700\u65B0\u7684 handleSendMessage\n React.useEffect(() => {\n handleSendMessageRef.current = handleSendMessage\n }, [handleSendMessage])\n\n /**\n * \u5904\u7406\u6C14\u6CE1\u6309\u94AE\u70B9\u51FB\n * \u5982\u679C\u914D\u7F6E\u4E86\u6CD5\u89C4\u534F\u8BAE\u4E14\u7528\u6237\u672A\u540C\u610F\uFF0C\u5148\u663E\u793A\u6CD5\u89C4\u5F39\u7A97\n * \u5426\u5219\u76F4\u63A5\u6253\u5F00\u804A\u5929\u7A97\u53E3\n */\n const handleBubbleClick = useCallback(() => {\n if (complianceConfig && !hasAgreedCompliance) {\n // \u663E\u793A\u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97\n setShowComplianceDialog(true)\n } else {\n // \u76F4\u63A5\u6253\u5F00\u804A\u5929\u7A97\u53E3\n openChat()\n }\n }, [complianceConfig, hasAgreedCompliance, openChat])\n\n /**\n * \u5904\u7406\u7528\u6237\u540C\u610F\u6CD5\u89C4\u534F\u8BAE\n */\n const handleComplianceAgree = useCallback(() => {\n // \u8BBE\u7F6E\u540C\u610F\u72B6\u6001\n setHasAgreedCompliance(true)\n setShowComplianceDialog(false)\n\n // \u4FDD\u5B58\u5230 Cookie\uFF08\u6709\u6548\u671F 365 \u5929\uFF09\n Cookies.set(cookieName, 'true', { expires: 365 })\n\n // \u540C\u610F\u540E\u7ACB\u5373\u6253\u5F00\u804A\u5929\u7A97\u53E3\n openChat()\n }, [openChat, cookieName])\n\n /**\n * \u5904\u7406\u6CD5\u89C4\u5F39\u7A97\u5173\u95ED\n */\n const handleComplianceClose = useCallback(() => {\n setShowComplianceDialog(false)\n }, [])\n\n return (\n <>\n {/* \u6CD5\u89C4\u534F\u8BAE\u5F39\u7A97 */}\n {complianceConfig && (\n <ComplianceDialog\n open={showComplianceDialog}\n config={complianceConfig}\n onAgree={handleComplianceAgree}\n onClose={handleComplianceClose}\n />\n )}\n\n {/* \u6C14\u6CE1\u6309\u94AE */}\n <ChatBubble\n position={position}\n onClick={handleBubbleClick}\n visible={!isOpen && !showComplianceDialog}\n iconImageUrl={chatBubbleIcon}\n />\n\n {/* \u804A\u5929\u7A97\u53E3\uFF08\u4F7F\u7528 Radix UI Dialog\uFF09 */}\n <Dialog.Root open={isOpen} onOpenChange={open => (open ? openChat() : closeChat())}>\n <Dialog.Portal>\n <Dialog.Content\n className=\"livechat-window-enter\"\n style={{\n position: 'fixed',\n zIndex: 9998,\n }}\n >\n <ChatWindow\n messages={messages}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSend={() => handleSendMessage()}\n onClose={closeChat}\n onNewSession={handleCreateNewSession}\n title={title}\n logoUrl={logoUrl}\n isSending={isStreaming}\n isLoadingHistory={isInitializing}\n rendererRegistry={rendererRegistry}\n inputPlaceholder=\"\"\n onAddToCart={onAddToCart}\n showNewSessionButton={showNewSessionButton}\n bottomTips={bottomTips}\n />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Fragment", "jsx", "jsxs", "React", "useEffect", "useCallback", "Dialog", "DEFAULT_COMMON_TEXT", "ChatBubble", "ChatWindow", "ComplianceDialog", "useChatState", "useChatAPI", "MessageRendererRegistry", "sanitizeInput", "transformProducts", "transformCartData", "Cookies", "TextBlock", "ProductCard", "ProductList", "ProductComparisonRenderer", "PolicyBlock", "createQuickRepliesRenderer", "ThinkingBlock", "ErrorBlock", "FAQListRenderer", "PromotionListRenderer", "CartCard", "LiveChatWidget", "apiBaseUrl", "headers", "recaptchaSitekey", "recaptchaAction", "site", "channelCode", "loginUserId", "cartId", "accessToken", "position", "welcomeMessage", "quickReplies", "customRenderers", "logoUrl", "title", "chatBubbleIcon", "open", "onOpenChange", "onOpen", "onClose", "onMessageSend", "onError", "onTextMessage", "onProductList", "onPromotionList", "onAddToCart", "onCart", "showNewSessionButton", "commonText", "productCardRender", "bottomTips", "complianceConfig", "cookieName", "showComplianceDialog", "setShowComplianceDialog", "hasAgreedCompliance", "setHasAgreedCompliance", "mergedText", "chatState", "messages", "isOpen", "userId", "sessionId", "inputValue", "isStreaming", "openChat", "closeChat", "setInputValue", "addMessage", "setMessages", "clearMessages", "handleSSEEvent", "saveSession", "clearSession", "isInitializing", "setIsInitializing", "sendMessageStream", "createSession", "handleSendMessageRef", "_message", "rendererRegistry", "registry", "quickRepliesRenderer", "reply", "currentSessionId", "handleResumeSession", "handleCreateNewSession", "normalizeMessage", "message", "contentBlocks", "structuredData", "block", "transformedData", "response", "messageText", "welcomeContent", "questions", "quickRepliesFromBackend", "question", "index", "error", "isRecaptcha", "existingSessionId", "normalizedMessages", "msg", "welcomeMsg", "handleSendMessage", "isRetry", "textToSend", "sanitized", "userMessage", "thinkingMessage", "sessionExpiredDetected", "event", "messagesWithoutThinking", "errorMessage", "errorCode", "handleBubbleClick", "handleComplianceAgree", "handleComplianceClose"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/PromotionList.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\u4FE1\u606F\n * \u57FA\u4E8E\u540E\u7AEF\u6570\u636E\u7ED3\u6784\u89C4\u8303\uFF1Apromotion_list\n */\n\nimport React from 'react'\nimport type { MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT } from '../../constants'\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionItem {\n id: string // \u6D3B\u52A8 ID\n title: string // \u6D3B\u52A8\u6807\u9898\n subtitle?: string // \u526F\u6807\u9898\uFF08\u5982 \"Up to 30% off\"\uFF09\n description?: string // \u6D3B\u52A8\u63CF\u8FF0\n banner_url?: string // Banner \u56FE\u7247 URL\n url?: string // \u6D3B\u52A8\u8BE6\u60C5\u9875 URL\n time_range: {\n start: string // \u5F00\u59CB\u65F6\u95F4 (ISO 8601)\n end?: string | null // \u7ED3\u675F\u65F6\u95F4\uFF0Cnull \u8868\u793A\u65E0\u7ED3\u675F\u65E5\u671F\n is_active: boolean // \u662F\u5426\u5F53\u524D\u6D3B\u8DC3\n }\n priority?: number // \u4F18\u5148\u7EA7\uFF08\u6570\u5B57\u8D8A\u5927\u8D8A\u9760\u524D\uFF09\n product_count?: number // \u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n metadata?: {\n display_order?: number\n target_audience?: string\n highlight_color?: string\n banner_url?:string\n }\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionListData {\n found: boolean // \u662F\u5426\u627E\u5230\u6D3B\u52A8\n count: number // \u8FD4\u56DE\u7684\u6D3B\u52A8\u6570\u91CF\n total?: number // \u603B\u6D3B\u52A8\u6570\u91CF\uFF08\u53EF\u9009\uFF09\n results: PromotionItem[] // \u6D3B\u52A8\u5217\u8868\n commonText?: CommonText // \u901A\u7528\u6587\u6848\u914D\u7F6E\n}\n\nexport interface PromotionListProps {\n /**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\n */\n data: PromotionListData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n}\n\n/**\n * \u683C\u5F0F\u5316\u65E5\u671F\u663E\u793A\n */\nconst formatDate = (dateStr: string): string => {\n const date = new Date(dateStr)\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\n * - \u652F\u6301\u6D3B\u52A8 Banner \u56FE\u7247\u5C55\u793A\n * - \u663E\u793A\u6D3B\u52A8\u65F6\u95F4\u8303\u56F4\n * - \u663E\u793A\u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n * - \u652F\u6301\u8DF3\u8F6C\u5230\u6D3B\u52A8\u8BE6\u60C5\u9875\n *\n * @example\n * ```tsx\n * <PromotionList\n * data={{\n * found: true,\n * count: 2,\n * results: [...]\n * }}\n * />\n * ```\n */\nexport const PromotionList: React.FC<PromotionListProps> = ({ data, isUser = false, isSystem = false }) => {\n const { found, results, commonText } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n return (\n <div className=\"space-y-3\">\n {results.map(promotion => {\n const bannerUrl = promotion.banner_url ||promotion?.metadata?.banner_url\n\n // \u6CA1\u6709\u56FE\u7247\u5219\u4E0D\u5C55\u793A\n if (!bannerUrl) {\n return null\n }\n\n return (\n <div key={promotion.id} className=\"relative overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* Banner \u56FE\u7247 */}\n <div className=\"aspect-[16/9] w-full overflow-hidden bg-gray-100\">\n <img\n src={bannerUrl}\n alt={promotion.title}\n className=\"size-full object-cover object-center\"\n loading=\"lazy\"\n />\n </div>\n\n {/* \u6D3B\u52A8\u4FE1\u606F - \u53E0\u52A0\u5728\u56FE\u7247\u4E0A */}\n <div\n className=\"absolute inset-0 flex flex-col justify-end p-4 text-[#080A0F]\"\n style={{ color: promotion?.metadata?.highlight_color }}\n >\n <div className=\"mb-2\">\n <h3 className=\"text-xl font-bold leading-[1.2] tracking-[-0.04em]\">{promotion.title}</h3>\n {promotion.subtitle && (\n <p className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em]\">{promotion.subtitle}</p>\n )}\n </div>\n\n {/* \u67E5\u770B\u8BE6\u60C5\u6309\u94AE */}\n {promotion.url && (\n <a\n href={promotion.url + '?ref=LiveChat'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm font-bold tracking-[-0.04em]\"\n >\n {mergedText.learnMore}\n <svg className=\"size-[18px]\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </a>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6E32\u67D3\u5668\n */\nexport const PromotionListRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'promotion_list' || !content.data) {\n return null\n }\n\n return <PromotionList data={content.data as PromotionListData} isUser={isUser} isSystem={isSystem} />\n },\n}\n"],
|
|
5
|
-
"mappings": "AAoHc,cAAAA,EAaA,QAAAC,MAbA,oBA5Gd,OAAS,uBAAAC,MAA2B,kBA0DpC,MAAMC,EAAcC,GACL,IAAI,KAAKA,CAAO,EACjB,mBAAmB,QAAS,CACtC,KAAM,UACN,MAAO,QACP,IAAK,SACP,CAAC,EAwBUC,EAA8C,CAAC,CAAE,KAAAC,EAAM,OAAAC,EAAS,GAAO,SAAAC,EAAW,EAAM,IAAM,CACzG,KAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,WAAAC,CAAW,EAAIL,EAGjCM,EAAa,CAAE,GAAGV,EAAqB,GAAGS,CAAW,EAE3D,OACEX,EAAC,OAAI,UAAU,YACZ,SAAAU,EAAQ,IAAIG,GAAa,CACxB,MAAMC,EAAYD,EAAU,
|
|
4
|
+
"sourcesContent": ["/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n * \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\u4FE1\u606F\n * \u57FA\u4E8E\u540E\u7AEF\u6570\u636E\u7ED3\u6784\u89C4\u8303\uFF1Apromotion_list\n */\n\nimport React from 'react'\nimport type { MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT } from '../../constants'\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionItem {\n id: string // \u6D3B\u52A8 ID\n title: string // \u6D3B\u52A8\u6807\u9898\n subtitle?: string // \u526F\u6807\u9898\uFF08\u5982 \"Up to 30% off\"\uFF09\n description?: string // \u6D3B\u52A8\u63CF\u8FF0\n banner_url?: string // Banner \u56FE\u7247 URL\n url?: string // \u6D3B\u52A8\u8BE6\u60C5\u9875 URL\n time_range: {\n start: string // \u5F00\u59CB\u65F6\u95F4 (ISO 8601)\n end?: string | null // \u7ED3\u675F\u65F6\u95F4\uFF0Cnull \u8868\u793A\u65E0\u7ED3\u675F\u65E5\u671F\n is_active: boolean // \u662F\u5426\u5F53\u524D\u6D3B\u8DC3\n }\n priority?: number // \u4F18\u5148\u7EA7\uFF08\u6570\u5B57\u8D8A\u5927\u8D8A\u9760\u524D\uFF09\n product_count?: number // \u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n metadata?: {\n display_order?: number\n target_audience?: string\n highlight_color?: string\n banner_url?:string\n }\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\u7ED3\u6784\n */\nexport interface PromotionListData {\n found: boolean // \u662F\u5426\u627E\u5230\u6D3B\u52A8\n count: number // \u8FD4\u56DE\u7684\u6D3B\u52A8\u6570\u91CF\n total?: number // \u603B\u6D3B\u52A8\u6570\u91CF\uFF08\u53EF\u9009\uFF09\n results: PromotionItem[] // \u6D3B\u52A8\u5217\u8868\n commonText?: CommonText // \u901A\u7528\u6587\u6848\u914D\u7F6E\n}\n\nexport interface PromotionListProps {\n /**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6570\u636E\n */\n data: PromotionListData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n}\n\n/**\n * \u683C\u5F0F\u5316\u65E5\u671F\u663E\u793A\n */\nconst formatDate = (dateStr: string): string => {\n const date = new Date(dateStr)\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n}\n\n/**\n * \u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u7EC4\u4EF6\n *\n * \u529F\u80FD\uFF1A\n * - \u663E\u793A\u5F53\u524D\u8FDB\u884C\u4E2D\u7684\u4FC3\u9500\u6D3B\u52A8\n * - \u652F\u6301\u6D3B\u52A8 Banner \u56FE\u7247\u5C55\u793A\n * - \u663E\u793A\u6D3B\u52A8\u65F6\u95F4\u8303\u56F4\n * - \u663E\u793A\u53C2\u4E0E\u5546\u54C1\u6570\u91CF\n * - \u652F\u6301\u8DF3\u8F6C\u5230\u6D3B\u52A8\u8BE6\u60C5\u9875\n *\n * @example\n * ```tsx\n * <PromotionList\n * data={{\n * found: true,\n * count: 2,\n * results: [...]\n * }}\n * />\n * ```\n */\nexport const PromotionList: React.FC<PromotionListProps> = ({ data, isUser = false, isSystem = false }) => {\n const { found, results, commonText } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n return (\n <div className=\"space-y-3\">\n {results.map(promotion => {\n const bannerUrl = promotion.banner_url || promotion?.metadata?.banner_url\n\n // \u6CA1\u6709\u56FE\u7247\u5219\u4E0D\u5C55\u793A\n if (!bannerUrl) {\n return null\n }\n\n return (\n <div key={promotion.id} className=\"relative overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* Banner \u56FE\u7247 */}\n <div className=\"aspect-[16/9] w-full overflow-hidden bg-gray-100\">\n <img\n src={bannerUrl}\n alt={promotion.title}\n className=\"size-full object-cover object-center\"\n loading=\"lazy\"\n />\n </div>\n\n {/* \u6D3B\u52A8\u4FE1\u606F - \u53E0\u52A0\u5728\u56FE\u7247\u4E0A */}\n <div\n className=\"absolute inset-0 flex flex-col justify-end p-4 text-[#080A0F]\"\n style={{ color: promotion?.metadata?.highlight_color }}\n >\n <div className=\"mb-2\">\n <h3 className=\"text-xl font-bold leading-[1.2] tracking-[-0.04em]\">{promotion.title}</h3>\n {promotion.subtitle && (\n <p className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em]\">{promotion.subtitle}</p>\n )}\n </div>\n\n {/* \u67E5\u770B\u8BE6\u60C5\u6309\u94AE */}\n {promotion.url && (\n <a\n href={promotion.url + '?ref=LiveChat'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm font-bold tracking-[-0.04em]\"\n >\n {mergedText.learnMore}\n <svg className=\"size-[18px]\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </a>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4FC3\u9500\u6D3B\u52A8\u5217\u8868\u6E32\u67D3\u5668\n */\nexport const PromotionListRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'promotion_list' || !content.data) {\n return null\n }\n\n return <PromotionList data={content.data as PromotionListData} isUser={isUser} isSystem={isSystem} />\n },\n}\n"],
|
|
5
|
+
"mappings": "AAoHc,cAAAA,EAaA,QAAAC,MAbA,oBA5Gd,OAAS,uBAAAC,MAA2B,kBA0DpC,MAAMC,EAAcC,GACL,IAAI,KAAKA,CAAO,EACjB,mBAAmB,QAAS,CACtC,KAAM,UACN,MAAO,QACP,IAAK,SACP,CAAC,EAwBUC,EAA8C,CAAC,CAAE,KAAAC,EAAM,OAAAC,EAAS,GAAO,SAAAC,EAAW,EAAM,IAAM,CACzG,KAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,WAAAC,CAAW,EAAIL,EAGjCM,EAAa,CAAE,GAAGV,EAAqB,GAAGS,CAAW,EAE3D,OACEX,EAAC,OAAI,UAAU,YACZ,SAAAU,EAAQ,IAAIG,GAAa,CACxB,MAAMC,EAAYD,EAAU,YAAcA,GAAW,UAAU,WAG/D,OAAKC,EAKHb,EAAC,OAAuB,UAAU,oDAEhC,UAAAD,EAAC,OAAI,UAAU,mDACb,SAAAA,EAAC,OACC,IAAKc,EACL,IAAKD,EAAU,MACf,UAAU,uCACV,QAAQ,OACV,EACF,EAGAZ,EAAC,OACC,UAAU,gEACV,MAAO,CAAE,MAAOY,GAAW,UAAU,eAAgB,EAErD,UAAAZ,EAAC,OAAI,UAAU,OACb,UAAAD,EAAC,MAAG,UAAU,qDAAsD,SAAAa,EAAU,MAAM,EACnFA,EAAU,UACTb,EAAC,KAAE,UAAU,qDAAsD,SAAAa,EAAU,SAAS,GAE1F,EAGCA,EAAU,KACTZ,EAAC,KACC,KAAMY,EAAU,IAAM,gBACtB,OAAO,SACP,IAAI,sBACJ,UAAU,sEAET,UAAAD,EAAW,UACZZ,EAAC,OAAI,UAAU,cAAc,KAAK,OAAO,OAAO,eAAe,QAAQ,YACrE,SAAAA,EAAC,QAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,eAAe,EACtF,GACF,GAEJ,IArCQa,EAAU,EAsCpB,EA1CO,IA4CX,CAAC,EACH,CAEJ,EAKaE,EAAyC,CACpD,OAAQ,CAACC,EAAST,EAAQC,IACpBQ,EAAQ,OAAS,kBAAoB,CAACA,EAAQ,KACzC,KAGFhB,EAACK,EAAA,CAAc,KAAMW,EAAQ,KAA2B,OAAQT,EAAQ,SAAUC,EAAU,CAEvG",
|
|
6
6
|
"names": ["jsx", "jsxs", "DEFAULT_COMMON_TEXT", "formatDate", "dateStr", "PromotionList", "data", "isUser", "isSystem", "found", "results", "commonText", "mergedText", "promotion", "bannerUrl", "PromotionListRenderer", "content"]
|
|
7
7
|
}
|