@anker-in/campaign-ui 0.4.3 → 0.4.4-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/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/cjs/components/credits/creditsCash/CreditsCash.js.map +2 -2
- package/dist/cjs/components/credits/creditsCash/RedeemableItem.js +1 -1
- package/dist/cjs/components/credits/creditsCash/RedeemableItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsCash/type.d.ts +0 -2
- package/dist/cjs/components/credits/creditsCash/type.js +1 -1
- package/dist/cjs/components/credits/creditsCash/type.js.map +1 -1
- 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/creditsMemberPrice/MemberPriceItem.js +1 -1
- package/dist/cjs/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsMemberPrice/type.d.ts +0 -2
- package/dist/cjs/components/credits/creditsMemberPrice/type.js.map +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js.map +2 -2
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
- package/dist/cjs/components/credits/creditsRedeemList/type.d.ts +0 -1
- package/dist/cjs/components/credits/creditsRedeemList/type.js.map +1 -1
- package/dist/cjs/components/credits/type.d.ts +0 -1
- package/dist/cjs/components/credits/type.js.map +1 -1
- package/dist/esm/components/credits/creditsCash/CreditsCash.js +1 -1
- package/dist/esm/components/credits/creditsCash/CreditsCash.js.map +2 -2
- package/dist/esm/components/credits/creditsCash/RedeemableItem.js +1 -1
- package/dist/esm/components/credits/creditsCash/RedeemableItem.js.map +3 -3
- package/dist/esm/components/credits/creditsCash/type.d.ts +0 -2
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
- package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +2 -2
- package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js +1 -1
- package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
- package/dist/esm/components/credits/creditsMemberPrice/type.d.ts +0 -2
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js.map +2 -2
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
- package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
- package/dist/esm/components/credits/creditsRedeemList/type.d.ts +0 -1
- package/dist/esm/components/credits/type.d.ts +0 -1
- package/package.json +19 -19
- package/src/components/credits/creditsCash/CreditsCash.tsx +0 -1
- package/src/components/credits/creditsCash/RedeemableItem.tsx +8 -7
- package/src/components/credits/creditsCash/type.ts +1 -2
- package/src/components/credits/creditsMemberPrice/CreditsMemberPrice.tsx +0 -1
- package/src/components/credits/creditsMemberPrice/MemberPriceItem.tsx +8 -10
- package/src/components/credits/creditsMemberPrice/type.ts +1 -2
- package/src/components/credits/creditsRedeemList/CreditsRedeemList.tsx +0 -1
- package/src/components/credits/creditsRedeemList/RedeemableItem.tsx +5 -7
- package/src/components/credits/creditsRedeemList/type.ts +0 -1
- package/src/components/credits/type.ts +0 -1
- package/dist/cjs/helpers/fetchResponse.d.ts +0 -14
- package/dist/cjs/helpers/fetchResponse.js +0 -2
- package/dist/cjs/helpers/fetchResponse.js.map +0 -7
- package/dist/cjs/helpers/fetcher.d.ts +0 -2
- package/dist/cjs/helpers/fetcher.js +0 -2
- package/dist/cjs/helpers/fetcher.js.map +0 -7
- package/dist/cjs/helpers/index.d.ts +0 -2
- package/dist/cjs/helpers/index.js +0 -2
- package/dist/cjs/helpers/index.js.map +0 -7
- package/dist/cjs/helpers/utils.d.ts +0 -3
- package/dist/cjs/helpers/utils.js +0 -2
- package/dist/cjs/helpers/utils.js.map +0 -7
- package/dist/cjs/tsconfig.tsbuildinfo +0 -1
- package/dist/esm/helpers/fetchResponse.d.ts +0 -14
- package/dist/esm/helpers/fetchResponse.js +0 -2
- package/dist/esm/helpers/fetchResponse.js.map +0 -7
- package/dist/esm/helpers/fetcher.d.ts +0 -2
- package/dist/esm/helpers/fetcher.js +0 -2
- package/dist/esm/helpers/fetcher.js.map +0 -7
- package/dist/esm/helpers/index.d.ts +0 -2
- package/dist/esm/helpers/index.js +0 -2
- package/dist/esm/helpers/index.js.map +0 -7
- package/dist/esm/helpers/utils.d.ts +0 -3
- package/dist/esm/helpers/utils.js +0 -2
- package/dist/esm/helpers/utils.js.map +0 -7
- package/dist/esm/tsconfig.tsbuildinfo +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/credits/creditsMemberPrice/CreditsMemberPrice.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Container, Heading, Tabs, TabsList, TabsTrigger } from '@anker-in/headless-ui'\nimport { useMemo, useState, useEffect, useCallback, useRef } from 'react'\nimport Decimal from 'decimal.js'\n\nimport MemberPriceItem from './MemberPriceItem'\nimport RedeemableItem from '../creditsCash/RedeemableItem'\nimport useRedeemableList from '../context/hooks/useRedeemableList'\nimport RulesModal from '../modal/RulesModal'\nimport { Pagination } from './Pagination'\nimport { useProductsByHandles, useHeadlessContext, gaTrack } from '@anker-in/lib'\nimport { CreditsMemberPriceCopy, MemberPriceProduct } from './type'\nimport { Product, classNames as cn } from '@anker-in/lib'\nimport { useCreditsContext } from '../context/provider'\nimport { RedeemItem } from '../creditsCash/type'\nimport { FunctionDiscountType } from '../context/memberPriceConst'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nexport const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy; id?: string }) => {\n const [activeTab, setActiveTab] = useState<'memberPrice' | 'redeem'>(copy.tabs[0]?.type || 'memberPrice')\n const [rules, setRules] = useState<string | string[]>()\n const [currentPage, setCurrentPage] = useState(1)\n const [itemsPerPage, setItemsPerPage] = useState(9) // \u9ED8\u8BA4 1024px \u4EE5\u4E0A\uFF1A3\u5217 \u00D7 3\u884C = 9\n const { redeemableList } = useRedeemableList()\n const { pageCommon, memberPriceDiscount, profile, gtm } = useCreditsContext()\n const { brand } = useHeadlessContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // \u5B9A\u4E49\u9700\u8981\u83B7\u53D6\u7684 metafield\uFF0C\u5305\u62EC\u900F\u660E\u56FE\u548C\u4F18\u60E0\u5238\u4FE1\u606F\n const variantMetafieldIdentifiers: any[] = [\n {\n namespace: 'global',\n key: 'transparentImg',\n },\n {\n namespace: '__discountCodeApp',\n key: 'data',\n },\n ]\n\n // \u6839\u636E\u5C4F\u5E55\u5C3A\u5BF8\u52A8\u6001\u8C03\u6574\u6BCF\u9875\u663E\u793A\u7684\u5546\u54C1\u6570\u91CF\n useEffect(() => {\n const updateItemsPerPage = () => {\n const width = window.innerWidth\n if (width >= 1440) {\n // 1920px \u4EE5\u4E0A\uFF1A4\u5217 \u00D7 3\u884C = 12\u4E2A\n setItemsPerPage(12)\n } else if (width >= 1024) {\n // 1024px - 1919px\uFF1A3\u5217 \u00D7 3\u884C = 9\u4E2A\n setItemsPerPage(9)\n } else if (width >= 768) {\n // 1024px \u4EE5\u4E0B\uFF1A3\u5217 \u00D7 4\u884C = 12\u4E2A\n setItemsPerPage(12)\n } else {\n // 768px \u4EE5\u4E0B\uFF1A2\u5217 \u00D7 4\u884C = 8\u4E2A\n setItemsPerPage(8)\n }\n }\n\n updateItemsPerPage()\n window.addEventListener('resize', updateItemsPerPage)\n return () => window.removeEventListener('resize', updateItemsPerPage)\n }, [])\n\n // \u5F53\u5207\u6362 tab \u6216\u6BCF\u9875\u6570\u91CF\u53D8\u5316\u65F6\u91CD\u7F6E\u9875\u7801\n useEffect(() => {\n setCurrentPage(1)\n }, [activeTab, itemsPerPage])\n\n // \u6839\u636E\u914D\u7F6E\u7684 ruleId \u67E5\u627E\u5BF9\u5E94\u7684\u4F1A\u5458\u4EF7\u89C4\u5219\n const targetRule = useMemo(() => {\n if (!memberPriceDiscount || !copy.memberPriceTab.memberPriceRuleId) return null\n return memberPriceDiscount.find(rule => String(rule.rule_id) === String(copy.memberPriceTab.memberPriceRuleId))\n }, [memberPriceDiscount, copy.memberPriceTab.memberPriceRuleId])\n\n const memberPriceHandles = useMemo(() => {\n if (!targetRule) return []\n\n // \u83B7\u53D6\u6240\u6709 user_identity === 1 \u7684 discounts\n const allDiscounts = targetRule.result_detail?.member_discounts?.filter(\n (discount: any) => discount.user_identity === 1\n ) || []\n\n // \u5408\u5E76\u6240\u6709 discounts \u7684 variants \u7684 handles\n const handles = allDiscounts.flatMap((discount: any) =>\n discount.main_products?.variants?.map((variant: any) => variant.handle) || []\n )\n\n return handles\n }, [targetRule])\n\n // \u83B7\u53D6\u4F1A\u5458\u4EF7\u4EA7\u54C1\u6570\u636E\uFF08\u901A\u8FC7\u4ECE memberPriceDiscount \u63D0\u53D6\u7684 handles \u83B7\u53D6\u4EA7\u54C1\uFF09\n const { data: memberPriceProducts } = useProductsByHandles({\n handles: memberPriceHandles,\n metafieldIdentifiers: {\n variant: variantMetafieldIdentifiers,\n },\n })\n\n // \u83B7\u53D6\u79EF\u5206\u5151\u6362\u4EA7\u54C1\u6570\u636E\n const { data: redeemProducts } = useProductsByHandles({\n handles: copy?.redeemTab?.list?.map(item => item.products?.[0]?.handle) || [],\n metafieldIdentifiers: {\n variant: variantMetafieldIdentifiers,\n },\n })\n\n // \u4ECE variant metafields \u4E2D\u83B7\u53D6\u6709\u6548\u7684 coupon \u6298\u6263\u91D1\u989D\n const getCouponDiscount = useCallback((variant: any) => {\n try {\n const discountData = variant?.metafields?.__discountCodeApp?.data\n if (!discountData) return 0\n\n // discountData \u5DF2\u7ECF\u662F\u5BF9\u8C61\uFF0C\u4E0D\u9700\u8981 JSON.parse\n const discounts = discountData\n if (!Array.isArray(discounts) || discounts.length === 0) return 0\n\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u6709\u6548\u7684 coupon\uFF08\u68C0\u67E5\u65F6\u95F4\u8303\u56F4\uFF09\n const now = new Date()\n const validDiscount = discounts.find((discount: any) => {\n const startsAt = discount.starts_at ? new Date(discount.starts_at) : null\n const endsAt = discount.ends_at ? new Date(discount.ends_at) : null\n\n // \u68C0\u67E5 coupon \u662F\u5426\u5728\u6709\u6548\u671F\u5185\n if (startsAt && startsAt > now) return false\n if (endsAt && endsAt < now) return false\n\n return true\n })\n\n // \u8FD4\u56DE\u6298\u6263\u91D1\u989D\uFF08fixed_amount \u7C7B\u578B\uFF09\n if (validDiscount?.fixed_value) {\n return parseFloat(validDiscount.fixed_value)\n }\n\n return 0\n } catch (error) {\n console.error('Failed to get coupon discount:', error)\n return 0\n }\n }, [])\n\n // \u8BA1\u7B97\u4F1A\u5458\u4EF7\u7684\u8F85\u52A9\u51FD\u6570\uFF08\u4EC5\u4F7F\u7528\u666E\u901A\u4F1A\u5458 user_identity = 1 \u7684\u6298\u6263\uFF0C\u5E76\u53E0\u52A0 coupon \u6298\u6263\uFF09\n const calculateMemberPrice = useCallback(\n (price: number, discount: any, variant?: any) => {\n const discountConfig = discount?.discount_conf\n if (!discountConfig) return null\n\n // \u6839\u636E\u6298\u6263\u7C7B\u578B\u8BA1\u7B97\u4F1A\u5458\u4EF7\n let salePrice = new Decimal(price)\n switch (discountConfig.discount_type) {\n case FunctionDiscountType.Percentage:\n salePrice = salePrice.mul(100 - discountConfig.discount_value).div(100)\n break\n case FunctionDiscountType.FixedAmount:\n salePrice = salePrice.sub(discountConfig.discount_value)\n break\n case FunctionDiscountType.FixedPrice:\n salePrice = new Decimal(discountConfig.discount_value)\n break\n }\n\n // \u53E0\u52A0 coupon \u6298\u6263\n if (variant) {\n const couponDiscount = getCouponDiscount(variant)\n if (couponDiscount > 0) {\n salePrice = salePrice.sub(couponDiscount)\n }\n }\n\n // \u786E\u4FDD\u4EF7\u683C\u4E0D\u4E3A\u8D1F\u6570\n if (salePrice.lessThan(0)) {\n salePrice = new Decimal(0)\n }\n\n return {\n memberPrice: salePrice.toNumber(),\n originalPrice: price,\n }\n },\n [getCouponDiscount]\n )\n\n // \u5904\u7406\u4F1A\u5458\u4EF7\u4EA7\u54C1\u5217\u8868\uFF08\u4EC5\u666E\u901A\u4F1A\u5458 user_identity = 1 \u7684\u6298\u6263\uFF09\n const memberPriceList = useMemo(() => {\n if (!targetRule || !memberPriceProducts) return []\n\n // \u83B7\u53D6\u6240\u6709 user_identity === 1 \u7684 discounts\n const allDiscounts = targetRule.result_detail?.member_discounts?.filter(\n (discount: any) => discount.user_identity === 1\n ) || []\n\n // \u5408\u5E76\u6240\u6709 discounts \u7684 variants\uFF0C\u5E76\u4FDD\u5B58\u5BF9\u5E94\u7684 discount \u4FE1\u606F\n const allVariantsWithDiscount = allDiscounts.flatMap((discount: any) =>\n (discount.main_products?.variants || []).map((variant: any) => ({\n ...variant,\n discount, // \u5C06 discount \u4FE1\u606F\u4FDD\u5B58\u5230 variant \u4E2D\n }))\n )\n\n return (\n (allVariantsWithDiscount\n .map((variantWithDiscount: any) => {\n const product = memberPriceProducts.find(p => p.handle === variantWithDiscount.handle)\n if (!product) return null\n\n const productVariant = product.variants?.find(v => v.sku === variantWithDiscount.sku) || product.variants?.[0]\n if (!productVariant || !productVariant.availableForSale) return null\n\n const priceResult = calculateMemberPrice(\n productVariant.price.amount,\n variantWithDiscount.discount,\n productVariant\n )\n if (!priceResult) return null\n\n return {\n product,\n productVariant,\n memberPrice: priceResult.memberPrice,\n originalPrice: priceResult.originalPrice,\n }\n })\n ?.filter(Boolean) as unknown as MemberPriceProduct[]) || []\n )\n }, [targetRule, memberPriceProducts, calculateMemberPrice])\n\n // \u5904\u7406\u79EF\u5206\u5151\u6362\u4EA7\u54C1\u5217\u8868\uFF08\u590D\u7528 creditsCash \u7684\u903B\u8F91\uFF0C\u8FC7\u6EE4\u7F3A\u8D27\u5546\u54C1\uFF09\n const redeemList = useMemo(() => {\n return redeemProducts\n ?.map((product: Product) => {\n const config = copy.redeemTab.list.find(item => item.products?.[0]?.handle === product.handle)\n const alpcData = redeemableList.find(item => item.id?.toString() === config?.redeemId?.toString())\n const productVariant =\n product.variants?.find((variant: any) => variant.sku === config?.products?.[0]?.sku) || product.variants?.[0]\n\n // \u8FC7\u6EE4\u6761\u4EF6\uFF1A\n // 1. \u5FC5\u987B\u6709 alpcData \u548C productVariant\n // 2. \u5546\u54C1\u4E0D\u80FD\u7F3A\u8D27\n // 3. \u5982\u679C\u6709\u5E93\u5B58\u9650\u5236\uFF0C\u5219\u5E93\u5B58\u5FC5\u987B\u5927\u4E8E 0\n if (!alpcData || !productVariant) return null\n if (!productVariant.availableForSale) return null\n if (alpcData.is_limited && alpcData.remaining_inventory <= 0) return null\n\n return {\n product,\n productVariant,\n productHref: config?.products?.[0]?.href,\n alpcData: {\n id: alpcData?.id,\n consumeCredits: alpcData?.consume_credits,\n remainingInventory: alpcData?.remaining_inventory,\n isLimited: alpcData?.is_limited,\n consumeType: alpcData?.consume_type,\n title: alpcData?.name,\n desc: alpcData?.note,\n },\n config,\n }\n })\n .filter(Boolean) as unknown as RedeemItem[]\n }, [redeemProducts, copy.redeemTab.list, redeemableList])\n\n // \u8BA1\u7B97\u4F1A\u5458\u4EF7\u5206\u9875\n const memberPricePagination = useMemo(() => {\n const totalItems = memberPriceList?.length || 0\n const totalPages = Math.ceil(totalItems / itemsPerPage)\n const startIndex = (currentPage - 1) * itemsPerPage\n const endIndex = startIndex + itemsPerPage\n const currentItems = memberPriceList?.slice(startIndex, endIndex) || []\n\n return {\n totalPages,\n currentItems,\n showPagination: totalPages > 1,\n }\n }, [memberPriceList, currentPage, itemsPerPage])\n\n // \u8BA1\u7B97\u79EF\u5206\u5151\u6362\u5206\u9875\n const redeemPagination = useMemo(() => {\n const totalItems = redeemList?.length || 0\n const totalPages = Math.ceil(totalItems / itemsPerPage)\n const startIndex = (currentPage - 1) * itemsPerPage\n const endIndex = startIndex + itemsPerPage\n const currentItems = redeemList?.slice(startIndex, endIndex) || []\n\n return {\n totalPages,\n currentItems,\n showPagination: totalPages > 1,\n }\n }, [redeemList, currentPage, itemsPerPage])\n\n // \u5904\u7406\u9875\u9762\u5207\u6362\uFF0C\u6EDA\u52A8\u5230\u6A21\u5757\u9876\u90E8\n const handlePageChange = useCallback(\n (page: number) => {\n setCurrentPage(page)\n // \u6EDA\u52A8\u5230\u6A21\u5757\u9876\u90E8\n if (containerRef.current) {\n const top = containerRef.current.offsetTop\n window.scrollTo({\n top: top - 80, // \u51CF\u53BB 80px \u7684\u504F\u79FB\u91CF\uFF0C\u907F\u514D\u88AB\u56FA\u5B9A\u5934\u90E8\u906E\u6321\n behavior: 'smooth',\n })\n }\n },\n [setCurrentPage]\n )\n\n // \u5904\u7406 tab \u5207\u6362\u5E76\u53D1\u9001\u57CB\u70B9\n const handleTabChange = useCallback(\n (value: string) => {\n const tabType = value as 'memberPrice' | 'redeem'\n setActiveTab(tabType)\n\n // \u67E5\u627E\u5F53\u524D tab \u7684 label\n const currentTab = copy.tabs.find(tab => tab.type === tabType)\n const tabLabel = currentTab?.label || ''\n\n // \u53D1\u9001 tab \u70B9\u51FB\u57CB\u70B9\n gaTrack({\n event: 'ga4Event',\n event_name: 'lp_button',\n member_active_status: profile?.activated ? 'active' : 'not active',\n event_parameters: {\n page_group: gtm.pageGroup,\n position: copy.title,\n button_name: tabLabel,\n },\n })\n },\n [copy.tabs, copy.title, profile?.activated, gtm.pageGroup]\n )\n\n return (\n <Container id={id} className={cn('bg-[#F5F5F5]')} ref={containerRef}>\n <Heading as=\"h2\" size=\"4\" html={copy.title} className=\"mx:px-[16px]\" />\n\n <Tabs\n align=\"left\"\n className=\"mt-[24px]\"\n value={activeTab}\n onValueChange={handleTabChange}\n >\n <TabsList>\n {copy.tabs.map((tab, index) => (\n <TabsTrigger key={index} value={tab.type}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n\n {/* Tab \u5185\u5BB9 */}\n <div className=\"relative mt-[24px]\">\n {/* \u4F1A\u5458\u4EF7 Tab */}\n {activeTab === 'memberPrice' && (\n <>\n <div className=\"grid md:grid-cols-2 gap-[12px] grid-cols-4 md-xl:grid-cols-3 lg:gap-[16px]\">\n {memberPricePagination.currentItems?.map((item, index: number) => (\n <MemberPriceItem key={index} itemData={item} copy={copy.memberPriceTab} />\n ))}\n </div>\n <Pagination\n currentPage={currentPage}\n totalPages={memberPricePagination.totalPages}\n onPageChange={handlePageChange}\n />\n </>\n )}\n\n {/* \u79EF\u5206\u5151\u6362 Tab */}\n {activeTab === 'redeem' && (\n <>\n <div className=\"grid md:grid-cols-2 gap-[12px] grid-cols-4 md-xl:grid-cols-3 lg:gap-[16px]\">\n {redeemPagination.currentItems?.map((item, index: number) => (\n <RedeemableItem\n key={index}\n copy={{\n title: copy.title,\n ...copy.redeemTab,\n }}\n itemData={item}\n setRules={setRules}\n currencyCode={redeemProducts?.[0]?.price.currencyCode || 'USD'}\n />\n ))}\n </div>\n <Pagination\n currentPage={currentPage}\n totalPages={redeemPagination.totalPages}\n onPageChange={handlePageChange}\n />\n </>\n )}\n </div>\n\n {/* Rules Modal */}\n {rules && (\n <RulesModal\n overlayClassName=\"md:px-[16px] md:items-center\"\n className={cn('md:h-fit md:rounded-b-[16px]', !rounded && 'md:rounded-none')}\n isOpen={rules.length > 0}\n onClose={() => setRules([])}\n titleClassName=\"border-b-transparent h-[56px]\"\n rules={rules}\n scrollClassName=\"md:mt-[8px] md:mb-[24px] md:pt-0\"\n title={pageCommon?.ruleLabel}\n ruleClassName=\"text-[#1d1d1f] font-bold\"\n />\n )}\n </Container>\n )\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { Container, Heading, Tabs, TabsList, TabsTrigger } from '@anker-in/headless-ui'\nimport { useMemo, useState, useEffect, useCallback, useRef } from 'react'\nimport Decimal from 'decimal.js'\n\nimport MemberPriceItem from './MemberPriceItem'\nimport RedeemableItem from '../creditsCash/RedeemableItem'\nimport useRedeemableList from '../context/hooks/useRedeemableList'\nimport RulesModal from '../modal/RulesModal'\nimport { Pagination } from './Pagination'\nimport { useProductsByHandles, useHeadlessContext, gaTrack } from '@anker-in/lib'\nimport { CreditsMemberPriceCopy, MemberPriceProduct } from './type'\nimport { Product, classNames as cn } from '@anker-in/lib'\nimport { useCreditsContext } from '../context/provider'\nimport { RedeemItem } from '../creditsCash/type'\nimport { FunctionDiscountType } from '../context/memberPriceConst'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nexport const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy; id?: string }) => {\n const [activeTab, setActiveTab] = useState<'memberPrice' | 'redeem'>(copy.tabs[0]?.type || 'memberPrice')\n const [rules, setRules] = useState<string | string[]>()\n const [currentPage, setCurrentPage] = useState(1)\n const [itemsPerPage, setItemsPerPage] = useState(9) // \u9ED8\u8BA4 1024px \u4EE5\u4E0A\uFF1A3\u5217 \u00D7 3\u884C = 9\n const { redeemableList } = useRedeemableList()\n const { pageCommon, memberPriceDiscount, profile, gtm } = useCreditsContext()\n const { brand } = useHeadlessContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // \u5B9A\u4E49\u9700\u8981\u83B7\u53D6\u7684 metafield\uFF0C\u5305\u62EC\u900F\u660E\u56FE\u548C\u4F18\u60E0\u5238\u4FE1\u606F\n const variantMetafieldIdentifiers: any[] = [\n {\n namespace: 'global',\n key: 'transparentImg',\n },\n {\n namespace: '__discountCodeApp',\n key: 'data',\n },\n ]\n\n // \u6839\u636E\u5C4F\u5E55\u5C3A\u5BF8\u52A8\u6001\u8C03\u6574\u6BCF\u9875\u663E\u793A\u7684\u5546\u54C1\u6570\u91CF\n useEffect(() => {\n const updateItemsPerPage = () => {\n const width = window.innerWidth\n if (width >= 1440) {\n // 1920px \u4EE5\u4E0A\uFF1A4\u5217 \u00D7 3\u884C = 12\u4E2A\n setItemsPerPage(12)\n } else if (width >= 1024) {\n // 1024px - 1919px\uFF1A3\u5217 \u00D7 3\u884C = 9\u4E2A\n setItemsPerPage(9)\n } else if (width >= 768) {\n // 1024px \u4EE5\u4E0B\uFF1A3\u5217 \u00D7 4\u884C = 12\u4E2A\n setItemsPerPage(12)\n } else {\n // 768px \u4EE5\u4E0B\uFF1A2\u5217 \u00D7 4\u884C = 8\u4E2A\n setItemsPerPage(8)\n }\n }\n\n updateItemsPerPage()\n window.addEventListener('resize', updateItemsPerPage)\n return () => window.removeEventListener('resize', updateItemsPerPage)\n }, [])\n\n // \u5F53\u5207\u6362 tab \u6216\u6BCF\u9875\u6570\u91CF\u53D8\u5316\u65F6\u91CD\u7F6E\u9875\u7801\n useEffect(() => {\n setCurrentPage(1)\n }, [activeTab, itemsPerPage])\n\n // \u6839\u636E\u914D\u7F6E\u7684 ruleId \u67E5\u627E\u5BF9\u5E94\u7684\u4F1A\u5458\u4EF7\u89C4\u5219\n const targetRule = useMemo(() => {\n if (!memberPriceDiscount || !copy.memberPriceTab.memberPriceRuleId) return null\n return memberPriceDiscount.find(rule => String(rule.rule_id) === String(copy.memberPriceTab.memberPriceRuleId))\n }, [memberPriceDiscount, copy.memberPriceTab.memberPriceRuleId])\n\n const memberPriceHandles = useMemo(() => {\n if (!targetRule) return []\n\n // \u83B7\u53D6\u6240\u6709 user_identity === 1 \u7684 discounts\n const allDiscounts = targetRule.result_detail?.member_discounts?.filter(\n (discount: any) => discount.user_identity === 1\n ) || []\n\n // \u5408\u5E76\u6240\u6709 discounts \u7684 variants \u7684 handles\n const handles = allDiscounts.flatMap((discount: any) =>\n discount.main_products?.variants?.map((variant: any) => variant.handle) || []\n )\n\n return handles\n }, [targetRule])\n\n // \u83B7\u53D6\u4F1A\u5458\u4EF7\u4EA7\u54C1\u6570\u636E\uFF08\u901A\u8FC7\u4ECE memberPriceDiscount \u63D0\u53D6\u7684 handles \u83B7\u53D6\u4EA7\u54C1\uFF09\n const { data: memberPriceProducts } = useProductsByHandles({\n handles: memberPriceHandles,\n metafieldIdentifiers: {\n variant: variantMetafieldIdentifiers,\n },\n })\n\n // \u83B7\u53D6\u79EF\u5206\u5151\u6362\u4EA7\u54C1\u6570\u636E\n const { data: redeemProducts } = useProductsByHandles({\n handles: copy?.redeemTab?.list?.map(item => item.products?.[0]?.handle) || [],\n metafieldIdentifiers: {\n variant: variantMetafieldIdentifiers,\n },\n })\n\n // \u4ECE variant metafields \u4E2D\u83B7\u53D6\u6709\u6548\u7684 coupon \u6298\u6263\u91D1\u989D\n const getCouponDiscount = useCallback((variant: any) => {\n try {\n const discountData = variant?.metafields?.__discountCodeApp?.data\n if (!discountData) return 0\n\n // discountData \u5DF2\u7ECF\u662F\u5BF9\u8C61\uFF0C\u4E0D\u9700\u8981 JSON.parse\n const discounts = discountData\n if (!Array.isArray(discounts) || discounts.length === 0) return 0\n\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u6709\u6548\u7684 coupon\uFF08\u68C0\u67E5\u65F6\u95F4\u8303\u56F4\uFF09\n const now = new Date()\n const validDiscount = discounts.find((discount: any) => {\n const startsAt = discount.starts_at ? new Date(discount.starts_at) : null\n const endsAt = discount.ends_at ? new Date(discount.ends_at) : null\n\n // \u68C0\u67E5 coupon \u662F\u5426\u5728\u6709\u6548\u671F\u5185\n if (startsAt && startsAt > now) return false\n if (endsAt && endsAt < now) return false\n\n return true\n })\n\n // \u8FD4\u56DE\u6298\u6263\u91D1\u989D\uFF08fixed_amount \u7C7B\u578B\uFF09\n if (validDiscount?.fixed_value) {\n return parseFloat(validDiscount.fixed_value)\n }\n\n return 0\n } catch (error) {\n console.error('Failed to get coupon discount:', error)\n return 0\n }\n }, [])\n\n // \u8BA1\u7B97\u4F1A\u5458\u4EF7\u7684\u8F85\u52A9\u51FD\u6570\uFF08\u4EC5\u4F7F\u7528\u666E\u901A\u4F1A\u5458 user_identity = 1 \u7684\u6298\u6263\uFF0C\u5E76\u53E0\u52A0 coupon \u6298\u6263\uFF09\n const calculateMemberPrice = useCallback(\n (price: number, discount: any, variant?: any) => {\n const discountConfig = discount?.discount_conf\n if (!discountConfig) return null\n\n // \u6839\u636E\u6298\u6263\u7C7B\u578B\u8BA1\u7B97\u4F1A\u5458\u4EF7\n let salePrice = new Decimal(price)\n switch (discountConfig.discount_type) {\n case FunctionDiscountType.Percentage:\n salePrice = salePrice.mul(100 - discountConfig.discount_value).div(100)\n break\n case FunctionDiscountType.FixedAmount:\n salePrice = salePrice.sub(discountConfig.discount_value)\n break\n case FunctionDiscountType.FixedPrice:\n salePrice = new Decimal(discountConfig.discount_value)\n break\n }\n\n // \u53E0\u52A0 coupon \u6298\u6263\n if (variant) {\n const couponDiscount = getCouponDiscount(variant)\n if (couponDiscount > 0) {\n salePrice = salePrice.sub(couponDiscount)\n }\n }\n\n // \u786E\u4FDD\u4EF7\u683C\u4E0D\u4E3A\u8D1F\u6570\n if (salePrice.lessThan(0)) {\n salePrice = new Decimal(0)\n }\n\n return {\n memberPrice: salePrice.toNumber(),\n originalPrice: price,\n }\n },\n [getCouponDiscount]\n )\n\n // \u5904\u7406\u4F1A\u5458\u4EF7\u4EA7\u54C1\u5217\u8868\uFF08\u4EC5\u666E\u901A\u4F1A\u5458 user_identity = 1 \u7684\u6298\u6263\uFF09\n const memberPriceList = useMemo(() => {\n if (!targetRule || !memberPriceProducts) return []\n\n // \u83B7\u53D6\u6240\u6709 user_identity === 1 \u7684 discounts\n const allDiscounts = targetRule.result_detail?.member_discounts?.filter(\n (discount: any) => discount.user_identity === 1\n ) || []\n\n // \u5408\u5E76\u6240\u6709 discounts \u7684 variants\uFF0C\u5E76\u4FDD\u5B58\u5BF9\u5E94\u7684 discount \u4FE1\u606F\n const allVariantsWithDiscount = allDiscounts.flatMap((discount: any) =>\n (discount.main_products?.variants || []).map((variant: any) => ({\n ...variant,\n discount, // \u5C06 discount \u4FE1\u606F\u4FDD\u5B58\u5230 variant \u4E2D\n }))\n )\n\n return (\n (allVariantsWithDiscount\n .map((variantWithDiscount: any) => {\n const product = memberPriceProducts.find(p => p.handle === variantWithDiscount.handle)\n if (!product) return null\n\n const productVariant = product.variants?.find(v => v.sku === variantWithDiscount.sku) || product.variants?.[0]\n if (!productVariant || !productVariant.availableForSale) return null\n\n const priceResult = calculateMemberPrice(\n productVariant.price.amount,\n variantWithDiscount.discount,\n productVariant\n )\n if (!priceResult) return null\n\n return {\n product,\n productVariant,\n memberPrice: priceResult.memberPrice,\n originalPrice: priceResult.originalPrice,\n }\n })\n ?.filter(Boolean) as unknown as MemberPriceProduct[]) || []\n )\n }, [targetRule, memberPriceProducts, calculateMemberPrice])\n\n // \u5904\u7406\u79EF\u5206\u5151\u6362\u4EA7\u54C1\u5217\u8868\uFF08\u590D\u7528 creditsCash \u7684\u903B\u8F91\uFF0C\u8FC7\u6EE4\u7F3A\u8D27\u5546\u54C1\uFF09\n const redeemList = useMemo(() => {\n return redeemProducts\n ?.map((product: Product) => {\n const config = copy.redeemTab.list.find(item => item.products?.[0]?.handle === product.handle)\n const alpcData = redeemableList.find(item => item.id?.toString() === config?.redeemId?.toString())\n const productVariant =\n product.variants?.find((variant: any) => variant.sku === config?.products?.[0]?.sku) || product.variants?.[0]\n\n // \u8FC7\u6EE4\u6761\u4EF6\uFF1A\n // 1. \u5FC5\u987B\u6709 alpcData \u548C productVariant\n // 2. \u5546\u54C1\u4E0D\u80FD\u7F3A\u8D27\n // 3. \u5982\u679C\u6709\u5E93\u5B58\u9650\u5236\uFF0C\u5219\u5E93\u5B58\u5FC5\u987B\u5927\u4E8E 0\n if (!alpcData || !productVariant) return null\n if (!productVariant.availableForSale) return null\n if (alpcData.is_limited && alpcData.remaining_inventory <= 0) return null\n\n return {\n product,\n productVariant,\n alpcData: {\n id: alpcData?.id,\n consumeCredits: alpcData?.consume_credits,\n remainingInventory: alpcData?.remaining_inventory,\n isLimited: alpcData?.is_limited,\n consumeType: alpcData?.consume_type,\n title: alpcData?.name,\n desc: alpcData?.note,\n },\n config,\n }\n })\n .filter(Boolean) as unknown as RedeemItem[]\n }, [redeemProducts, copy.redeemTab.list, redeemableList])\n\n // \u8BA1\u7B97\u4F1A\u5458\u4EF7\u5206\u9875\n const memberPricePagination = useMemo(() => {\n const totalItems = memberPriceList?.length || 0\n const totalPages = Math.ceil(totalItems / itemsPerPage)\n const startIndex = (currentPage - 1) * itemsPerPage\n const endIndex = startIndex + itemsPerPage\n const currentItems = memberPriceList?.slice(startIndex, endIndex) || []\n\n return {\n totalPages,\n currentItems,\n showPagination: totalPages > 1,\n }\n }, [memberPriceList, currentPage, itemsPerPage])\n\n // \u8BA1\u7B97\u79EF\u5206\u5151\u6362\u5206\u9875\n const redeemPagination = useMemo(() => {\n const totalItems = redeemList?.length || 0\n const totalPages = Math.ceil(totalItems / itemsPerPage)\n const startIndex = (currentPage - 1) * itemsPerPage\n const endIndex = startIndex + itemsPerPage\n const currentItems = redeemList?.slice(startIndex, endIndex) || []\n\n return {\n totalPages,\n currentItems,\n showPagination: totalPages > 1,\n }\n }, [redeemList, currentPage, itemsPerPage])\n\n // \u5904\u7406\u9875\u9762\u5207\u6362\uFF0C\u6EDA\u52A8\u5230\u6A21\u5757\u9876\u90E8\n const handlePageChange = useCallback(\n (page: number) => {\n setCurrentPage(page)\n // \u6EDA\u52A8\u5230\u6A21\u5757\u9876\u90E8\n if (containerRef.current) {\n const top = containerRef.current.offsetTop\n window.scrollTo({\n top: top - 80, // \u51CF\u53BB 80px \u7684\u504F\u79FB\u91CF\uFF0C\u907F\u514D\u88AB\u56FA\u5B9A\u5934\u90E8\u906E\u6321\n behavior: 'smooth',\n })\n }\n },\n [setCurrentPage]\n )\n\n // \u5904\u7406 tab \u5207\u6362\u5E76\u53D1\u9001\u57CB\u70B9\n const handleTabChange = useCallback(\n (value: string) => {\n const tabType = value as 'memberPrice' | 'redeem'\n setActiveTab(tabType)\n\n // \u67E5\u627E\u5F53\u524D tab \u7684 label\n const currentTab = copy.tabs.find(tab => tab.type === tabType)\n const tabLabel = currentTab?.label || ''\n\n // \u53D1\u9001 tab \u70B9\u51FB\u57CB\u70B9\n gaTrack({\n event: 'ga4Event',\n event_name: 'lp_button',\n member_active_status: profile?.activated ? 'active' : 'not active',\n event_parameters: {\n page_group: gtm.pageGroup,\n position: copy.title,\n button_name: tabLabel,\n },\n })\n },\n [copy.tabs, copy.title, profile?.activated, gtm.pageGroup]\n )\n\n return (\n <Container id={id} className={cn('bg-[#F5F5F5]')} ref={containerRef}>\n <Heading as=\"h2\" size=\"4\" html={copy.title} className=\"mx:px-[16px]\" />\n\n <Tabs\n align=\"left\"\n className=\"mt-[24px]\"\n value={activeTab}\n onValueChange={handleTabChange}\n >\n <TabsList>\n {copy.tabs.map((tab, index) => (\n <TabsTrigger key={index} value={tab.type}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n\n {/* Tab \u5185\u5BB9 */}\n <div className=\"relative mt-[24px]\">\n {/* \u4F1A\u5458\u4EF7 Tab */}\n {activeTab === 'memberPrice' && (\n <>\n <div className=\"grid md:grid-cols-2 gap-[12px] grid-cols-4 md-xl:grid-cols-3 lg:gap-[16px]\">\n {memberPricePagination.currentItems?.map((item, index: number) => (\n <MemberPriceItem key={index} itemData={item} copy={copy.memberPriceTab} />\n ))}\n </div>\n <Pagination\n currentPage={currentPage}\n totalPages={memberPricePagination.totalPages}\n onPageChange={handlePageChange}\n />\n </>\n )}\n\n {/* \u79EF\u5206\u5151\u6362 Tab */}\n {activeTab === 'redeem' && (\n <>\n <div className=\"grid md:grid-cols-2 gap-[12px] grid-cols-4 md-xl:grid-cols-3 lg:gap-[16px]\">\n {redeemPagination.currentItems?.map((item, index: number) => (\n <RedeemableItem\n key={index}\n copy={{\n title: copy.title,\n ...copy.redeemTab,\n }}\n itemData={item}\n setRules={setRules}\n currencyCode={redeemProducts?.[0]?.price.currencyCode || 'USD'}\n />\n ))}\n </div>\n <Pagination\n currentPage={currentPage}\n totalPages={redeemPagination.totalPages}\n onPageChange={handlePageChange}\n />\n </>\n )}\n </div>\n\n {/* Rules Modal */}\n {rules && (\n <RulesModal\n overlayClassName=\"md:px-[16px] md:items-center\"\n className={cn('md:h-fit md:rounded-b-[16px]', !rounded && 'md:rounded-none')}\n isOpen={rules.length > 0}\n onClose={() => setRules([])}\n titleClassName=\"border-b-transparent h-[56px]\"\n rules={rules}\n scrollClassName=\"md:mt-[8px] md:mb-[24px] md:pt-0\"\n title={pageCommon?.ruleLabel}\n ruleClassName=\"text-[#1d1d1f] font-bold\"\n />\n )}\n </Container>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "Container", "Heading", "Tabs", "TabsList", "TabsTrigger", "useMemo", "useState", "useEffect", "useCallback", "useRef", "Decimal", "MemberPriceItem", "RedeemableItem", "useRedeemableList", "RulesModal", "Pagination", "useProductsByHandles", "useHeadlessContext", "gaTrack", "cn", "useCreditsContext", "FunctionDiscountType", "ROUNDED_BRANDS", "CreditsMemberPrice", "copy", "id", "activeTab", "setActiveTab", "rules", "setRules", "currentPage", "setCurrentPage", "itemsPerPage", "setItemsPerPage", "redeemableList", "pageCommon", "memberPriceDiscount", "profile", "gtm", "brand", "rounded", "containerRef", "variantMetafieldIdentifiers", "updateItemsPerPage", "width", "targetRule", "rule", "memberPriceHandles", "discount", "variant", "memberPriceProducts", "redeemProducts", "item", "getCouponDiscount", "discountData", "discounts", "now", "validDiscount", "startsAt", "endsAt", "error", "calculateMemberPrice", "price", "discountConfig", "salePrice", "couponDiscount", "memberPriceList", "variantWithDiscount", "product", "p", "productVariant", "v", "priceResult", "redeemList", "config", "alpcData", "memberPricePagination", "totalItems", "totalPages", "startIndex", "endIndex", "currentItems", "redeemPagination", "handlePageChange", "page", "top", "handleTabChange", "value", "tabType", "tabLabel", "tab", "index"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as r,jsxs as
|
|
1
|
+
import{jsx as r,jsxs as i}from"react/jsx-runtime";import{Button as A,Text as p,Picture as M,Badge as H}from"@anker-in/headless-ui";import{useMemo as c,useState as L}from"react";import{formatPrice as w,extractVariantId as P}from"../context/utils";import{classNames as u,useHeadlessContext as E,useBuyNow as F}from"@anker-in/lib";import{useCreditsContext as U}from"../context/provider";import{ROUNDED_BRANDS as z}from"../../../constants";function O({itemData:e,copy:n,className:_}){const{brand:g,locale:o}=E(),{profile:d,openSignUpPopup:T,cartConfig:x,gtm:l}=U(),V=z.includes(g),{trigger:k,isMutating:f}=F({},{throwOnError:!0}),[b,v]=L(!1),C=c(()=>e.productVariant?.availableForSale,[e.productVariant?.availableForSale]),S=c(()=>!!d,[d]),a=c(()=>{try{const t=e.productVariant?.metafields?.__discountCodeApp?.data;if(!t)return;const m=t;if(!Array.isArray(m)||m.length===0)return;const h=new Date;return m.find(s=>{const y=s.starts_at?new Date(s.starts_at):null,N=s.ends_at?new Date(s.ends_at):null;return!(y&&y>h||N&&N<h)})?.title}catch(t){console.error("Failed to get discount code:",t);return}},[e.productVariant?.metafields]),$=c(()=>{const t=o==="us"?"":`/${o}`;return P(e.productVariant?.id)?`${t}/products/${e.product.handle}?variant=${P(e.productVariant?.id)}${l.pageHandle?`&ref=${l.pageHandle}`:""}`:`${t}/products/${e.product.handle}${l.pageHandle?`?ref=${l.pageHandle}`:""}`},[e.productVariant?.id,e.product.handle,l.pageHandle,o]),B=async()=>{if(!x?.addToCart){console.warn("cartConfig.addToCart is required");return}try{v(!0);const t=[];a&&t.push({key:"_member_price",value:JSON.stringify({code:a})}),await x.addToCart({variantList:[{variant:e.productVariant,quantity:1,attributes:t.length>0?t:void 0}],cartAttributes:{_member_type:String(d?.memberType||0)},discountCodes:a?[a]:void 0})}catch(t){console.error("Add to cart failed:",t)}finally{v(!1)}},I=()=>{if(!S){T();return}const t=[];a&&t.push({key:"_member_price",value:JSON.stringify({code:a})}),k({customAttributes:[{key:"_member_type",value:String(d?.memberType||0)}],lineItems:[{variant:e.productVariant,quantity:1,attributes:t.length>0?t:void 0}],discountCodes:a?[a]:void 0,gtmParams:{pageGroup:l.pageGroup,position:"mmeber-price-card"}})};return i("div",{className:u("relative flex flex-col items-center bg-[#EAEAEC] px-[24px] pb-[24px] l:px-[8px] l:pb-[8px] rounded-[16px] md-xl:px-[16px] md-xl:pb-[16px] md:rounded-[12px]",!V&&"rounded-none md:rounded-none",n.badgeLabel?"pt-[48px] l:pt-[44px]":"pt-[24px] md-xl:pt-[16px] l:pt-[8px]",_),children:[n.badgeLabel&&r(H,{className:"absolute left-[24px] !bg-gradient-brand l:left-[16px] top-[16px] z-10",size:"lg",variant:"promotional",promotionalType:"regular-member",children:n.badgeLabel}),r("a",{href:$,className:u("relative mx-auto h-[196px] w-fit md:h-[120px] md-xxl:h-[138px]"),children:r(M,{className:"mx-auto h-full w-auto",imgClassName:"h-full object-contain",source:e?.productVariant?.metafields?.global?.transparentImg||e?.config?.image?.url||e?.productVariant?.image?.url})}),i("div",{className:u("mt-[10px] xl:mt-[8px] w-full"),children:[r(p,{html:e?.product?.title,title:e?.product?.title,className:"line-clamp-2 text-[24px] min-h-[58px] l-xxl:min-h-[48px] l:min-h-[38px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#080A0F]"}),i("div",{className:"mt-[24px] l:mt-[12px] flex flex-col gap-[8px] l:gap-0",children:[r(p,{html:n.memberPriceLabel,className:u("text-brand-color-0 text-[16px] l-xl:text-[14px] l:text-[12px] w-fit font-bold leading-[1.4] tracking-[-0.28px]",g==="ankersolix"&&"leading-none bg-gradient-to-r from-[#2c7ed0] via-[#00a9e1] via-[43%] to-[#00db84] bg-clip-text text-transparent"),as:"p"}),i("div",{className:"flex items-center gap-[4px]",children:[r(p,{html:w({amount:e.memberPrice,currencyCode:e?.productVariant?.price.currencyCode||"USD",locale:o}),className:"text-[24px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#080A0F]",as:"span"}),r(p,{html:w({amount:e.originalPrice,currencyCode:e?.productVariant?.price.currencyCode||"USD",locale:o}),className:"text-[24px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#4A4C56] line-through",as:"span"})]}),i("div",{className:"flex w-full mt-[8px] gap-[8px] l:flex-col",children:[r(A,{variant:"secondary",className:"flex-1 md:w-full",size:"lg",onClick:B,disabled:!C||!x?.addToCart||b,loading:b,children:n.addToCart}),r(A,{variant:"primary",className:"flex-1 md:w-full",size:"lg",onClick:I,disabled:!C||f,loading:f,children:n.shopNowText})]})]})]})]})}var Z=O;export{Z as default};
|
|
2
2
|
//# sourceMappingURL=MemberPriceItem.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/credits/creditsMemberPrice/MemberPriceItem.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Button, Text, Picture, Badge } from '@anker-in/headless-ui'\nimport { useMemo, useState } from 'react'\n\nimport { CreditsMemberPriceCopy, MemberPriceProduct } from './type'\nimport { formatPrice, extractVariantId } from '../context/utils'\nimport { classNames as cn, useHeadlessContext, useBuyNow } from '@anker-in/lib'\nimport { useCreditsContext } from '../context/provider'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nfunction MemberPriceItem({\n itemData,\n copy,\n className,\n}: {\n itemData: MemberPriceProduct\n copy: CreditsMemberPriceCopy['memberPriceTab']\n className?: string\n}) {\n const { brand, locale } = useHeadlessContext()\n const { profile, openSignUpPopup, cartConfig, gtm } = useCreditsContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n // \u4F7F\u7528 buyNow hook \u6765\u5904\u7406\u7ED3\u7B97\n const { trigger: buyNow, isMutating: isBuying } = useBuyNow({}, { throwOnError: true })\n\n // \u672C\u5730 loading \u72B6\u6001\uFF0C\u907F\u514D\u5168\u5C40 loading \u5F71\u54CD\u6240\u6709\u5361\u7247\n const [isAddingToCart, setIsAddingToCart] = useState(false)\n\n const isAvailable = useMemo(() => {\n return itemData.productVariant?.availableForSale\n }, [itemData.productVariant?.availableForSale])\n\n const isLogin = useMemo(() => {\n return !!profile\n }, [profile])\n\n // \u4ECE variant metafields \u4E2D\u83B7\u53D6 coupon code\n const getCouponCode = useMemo(() => {\n try {\n const discountData = itemData.productVariant?.metafields?.__discountCodeApp?.data\n if (!discountData) return undefined\n\n // discountData \u5DF2\u7ECF\u662F\u5BF9\u8C61\uFF0C\u4E0D\u9700\u8981 JSON.parse\n const discounts = discountData\n if (!Array.isArray(discounts) || discounts.length === 0) return undefined\n\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u6709\u6548\u7684 coupon\uFF08\u68C0\u67E5\u65F6\u95F4\u8303\u56F4\uFF09\n const now = new Date()\n const validDiscount = discounts.find((discount: any) => {\n const startsAt = discount.starts_at ? new Date(discount.starts_at) : null\n const endsAt = discount.ends_at ? new Date(discount.ends_at) : null\n\n // \u68C0\u67E5 coupon \u662F\u5426\u5728\u6709\u6548\u671F\u5185\n if (startsAt && startsAt > now) return false\n if (endsAt && endsAt < now) return false\n\n return true\n })\n\n return validDiscount?.title\n } catch (error) {\n console.error('Failed to get discount code:', error)\n return undefined\n }\n }, [itemData.productVariant?.metafields])\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB - \u8C03\u7528\u52A0\u8D2D\u65B9\u6CD5\n const handleAddToCart = async () => {\n if (!cartConfig?.addToCart) {\n console.warn('cartConfig.addToCart is required')\n return\n }\n\n try {\n setIsAddingToCart(true)\n\n // \u6784\u5EFA lineItem attributes\n const lineItemAttributes: Array<{ key: string; value: string }> = []\n if (getCouponCode) {\n lineItemAttributes.push({\n key: '_member_price',\n value: JSON.stringify({ code: getCouponCode }),\n })\n }\n\n await cartConfig.addToCart({\n variantList: [\n {\n variant: itemData.productVariant,\n quantity: 1,\n attributes: lineItemAttributes.length > 0 ? lineItemAttributes : undefined,\n },\n ],\n cartAttributes: {\n _member_type: String(profile?.memberType || 0),\n },\n discountCodes: getCouponCode ? [getCouponCode] : undefined,\n })\n } catch (error) {\n console.error('Add to cart failed:', error)\n } finally {\n setIsAddingToCart(false)\n }\n }\n\n // Shop Now \u6309\u94AE\u70B9\u51FB - \u68C0\u67E5\u767B\u5F55\u72B6\u6001\u540E\u4F7F\u7528 buyNow \u8FDB\u884C\u7ED3\u7B97\n const handleShopNow = () => {\n // \u5982\u679C\u672A\u767B\u5F55\uFF0C\u5F39\u51FA\u767B\u5F55\u5F39\u7A97\n if (!isLogin) {\n openSignUpPopup()\n return\n }\n\n // \u6784\u5EFA lineItem attributes\n const lineItemAttributes: Array<{ key: string; value: string }> = []\n if (getCouponCode) {\n lineItemAttributes.push({\n key: '_member_price',\n value: JSON.stringify({ code: getCouponCode }),\n })\n }\n\n // \u5DF2\u767B\u5F55\uFF0C\u6267\u884C\u8D2D\u4E70\n buyNow({\n customAttributes: [\n {\n key: '_member_type',\n value: String(profile?.memberType || 0),\n },\n ],\n lineItems: [\n {\n variant: itemData.productVariant,\n quantity: 1,\n attributes: lineItemAttributes.length > 0 ? lineItemAttributes : undefined,\n },\n ],\n discountCodes: getCouponCode ? [getCouponCode] : undefined,\n gtmParams: {\n pageGroup: gtm.pageGroup,\n position: 'mmeber-price-card',\n },\n })\n }\n\n return (\n <div\n className={cn(\n 'relative flex flex-col items-center bg-[#EAEAEC] px-[24px] pb-[24px] l:px-[8px] l:pb-[8px] rounded-[16px] md-xl:px-[16px] md-xl:pb-[16px] md:rounded-[12px]',\n !rounded && 'rounded-none md:rounded-none',\n copy.badgeLabel ? 'pt-[48px] l:pt-[44px]' : 'pt-[24px] md-xl:pt-[16px] l:pt-[8px]',\n className\n )}\n >\n {/* Member \u6807\u7B7E Badge */}\n {copy.badgeLabel && (\n <Badge\n className=\"absolute left-[24px] !bg-gradient-brand l:left-[16px] top-[16px] z-10\"\n size=\"lg\"\n variant=\"promotional\"\n promotionalType=\"regular-member\"\n >\n {copy.badgeLabel}\n </Badge>\n )}\n\n {/* \u4EA7\u54C1\u56FE\u7247 - \u4F18\u5148\u4F7F\u7528\u4EA7\u54C1\u7684 metafields \u900F\u660E\u56FE */}\n <a
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "Button", "Text", "Picture", "Badge", "useMemo", "useState", "formatPrice", "extractVariantId", "cn", "useHeadlessContext", "useBuyNow", "useCreditsContext", "ROUNDED_BRANDS", "MemberPriceItem", "itemData", "copy", "className", "brand", "locale", "profile", "openSignUpPopup", "cartConfig", "gtm", "rounded", "buyNow", "isBuying", "isAddingToCart", "setIsAddingToCart", "isAvailable", "isLogin", "getCouponCode", "discountData", "discounts", "now", "discount", "startsAt", "endsAt", "error", "handleAddToCart", "lineItemAttributes", "handleShopNow", "MemberPriceItem_default"]
|
|
4
|
+
"sourcesContent": ["import { Button, Text, Picture, Badge } from '@anker-in/headless-ui'\nimport { useMemo, useState } from 'react'\n\nimport { CreditsMemberPriceCopy, MemberPriceProduct } from './type'\nimport { formatPrice, extractVariantId } from '../context/utils'\nimport { classNames as cn, useHeadlessContext, useBuyNow } from '@anker-in/lib'\nimport { useCreditsContext } from '../context/provider'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nfunction MemberPriceItem({\n itemData,\n copy,\n className,\n}: {\n itemData: MemberPriceProduct\n copy: CreditsMemberPriceCopy['memberPriceTab']\n className?: string\n}) {\n const { brand, locale } = useHeadlessContext()\n const { profile, openSignUpPopup, cartConfig, gtm } = useCreditsContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n // \u4F7F\u7528 buyNow hook \u6765\u5904\u7406\u7ED3\u7B97\n const { trigger: buyNow, isMutating: isBuying } = useBuyNow({}, { throwOnError: true })\n\n // \u672C\u5730 loading \u72B6\u6001\uFF0C\u907F\u514D\u5168\u5C40 loading \u5F71\u54CD\u6240\u6709\u5361\u7247\n const [isAddingToCart, setIsAddingToCart] = useState(false)\n\n const isAvailable = useMemo(() => {\n return itemData.productVariant?.availableForSale\n }, [itemData.productVariant?.availableForSale])\n\n const isLogin = useMemo(() => {\n return !!profile\n }, [profile])\n\n // \u4ECE variant metafields \u4E2D\u83B7\u53D6 coupon code\n const getCouponCode = useMemo(() => {\n try {\n const discountData = itemData.productVariant?.metafields?.__discountCodeApp?.data\n if (!discountData) return undefined\n\n // discountData \u5DF2\u7ECF\u662F\u5BF9\u8C61\uFF0C\u4E0D\u9700\u8981 JSON.parse\n const discounts = discountData\n if (!Array.isArray(discounts) || discounts.length === 0) return undefined\n\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u6709\u6548\u7684 coupon\uFF08\u68C0\u67E5\u65F6\u95F4\u8303\u56F4\uFF09\n const now = new Date()\n const validDiscount = discounts.find((discount: any) => {\n const startsAt = discount.starts_at ? new Date(discount.starts_at) : null\n const endsAt = discount.ends_at ? new Date(discount.ends_at) : null\n\n // \u68C0\u67E5 coupon \u662F\u5426\u5728\u6709\u6548\u671F\u5185\n if (startsAt && startsAt > now) return false\n if (endsAt && endsAt < now) return false\n\n return true\n })\n\n return validDiscount?.title\n } catch (error) {\n console.error('Failed to get discount code:', error)\n return undefined\n }\n }, [itemData.productVariant?.metafields])\n\n const productUrl = useMemo(() => {\n const localePrefix = locale === 'us' ? '' : `/${locale}`\n return extractVariantId(itemData.productVariant?.id)\n ? `${localePrefix}/products/${itemData.product.handle}?variant=${extractVariantId(itemData.productVariant?.id)}${gtm.pageHandle ? `&ref=${gtm.pageHandle}` : ''}`\n : `${localePrefix}/products/${itemData.product.handle}${gtm.pageHandle ? `?ref=${gtm.pageHandle}` : ''}`\n }, [itemData.productVariant?.id, itemData.product.handle, gtm.pageHandle, locale])\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB - \u8C03\u7528\u52A0\u8D2D\u65B9\u6CD5\n const handleAddToCart = async () => {\n if (!cartConfig?.addToCart) {\n console.warn('cartConfig.addToCart is required')\n return\n }\n\n try {\n setIsAddingToCart(true)\n\n // \u6784\u5EFA lineItem attributes\n const lineItemAttributes: Array<{ key: string; value: string }> = []\n if (getCouponCode) {\n lineItemAttributes.push({\n key: '_member_price',\n value: JSON.stringify({ code: getCouponCode }),\n })\n }\n\n await cartConfig.addToCart({\n variantList: [\n {\n variant: itemData.productVariant,\n quantity: 1,\n attributes: lineItemAttributes.length > 0 ? lineItemAttributes : undefined,\n },\n ],\n cartAttributes: {\n _member_type: String(profile?.memberType || 0),\n },\n discountCodes: getCouponCode ? [getCouponCode] : undefined,\n })\n } catch (error) {\n console.error('Add to cart failed:', error)\n } finally {\n setIsAddingToCart(false)\n }\n }\n\n // Shop Now \u6309\u94AE\u70B9\u51FB - \u68C0\u67E5\u767B\u5F55\u72B6\u6001\u540E\u4F7F\u7528 buyNow \u8FDB\u884C\u7ED3\u7B97\n const handleShopNow = () => {\n // \u5982\u679C\u672A\u767B\u5F55\uFF0C\u5F39\u51FA\u767B\u5F55\u5F39\u7A97\n if (!isLogin) {\n openSignUpPopup()\n return\n }\n\n // \u6784\u5EFA lineItem attributes\n const lineItemAttributes: Array<{ key: string; value: string }> = []\n if (getCouponCode) {\n lineItemAttributes.push({\n key: '_member_price',\n value: JSON.stringify({ code: getCouponCode }),\n })\n }\n\n // \u5DF2\u767B\u5F55\uFF0C\u6267\u884C\u8D2D\u4E70\n buyNow({\n customAttributes: [\n {\n key: '_member_type',\n value: String(profile?.memberType || 0),\n },\n ],\n lineItems: [\n {\n variant: itemData.productVariant,\n quantity: 1,\n attributes: lineItemAttributes.length > 0 ? lineItemAttributes : undefined,\n },\n ],\n discountCodes: getCouponCode ? [getCouponCode] : undefined,\n gtmParams: {\n pageGroup: gtm.pageGroup,\n position: 'mmeber-price-card',\n },\n })\n }\n\n return (\n <div\n className={cn(\n 'relative flex flex-col items-center bg-[#EAEAEC] px-[24px] pb-[24px] l:px-[8px] l:pb-[8px] rounded-[16px] md-xl:px-[16px] md-xl:pb-[16px] md:rounded-[12px]',\n !rounded && 'rounded-none md:rounded-none',\n copy.badgeLabel ? 'pt-[48px] l:pt-[44px]' : 'pt-[24px] md-xl:pt-[16px] l:pt-[8px]',\n className\n )}\n >\n {/* Member \u6807\u7B7E Badge */}\n {copy.badgeLabel && (\n <Badge\n className=\"absolute left-[24px] !bg-gradient-brand l:left-[16px] top-[16px] z-10\"\n size=\"lg\"\n variant=\"promotional\"\n promotionalType=\"regular-member\"\n >\n {copy.badgeLabel}\n </Badge>\n )}\n\n {/* \u4EA7\u54C1\u56FE\u7247 - \u4F18\u5148\u4F7F\u7528\u4EA7\u54C1\u7684 metafields \u900F\u660E\u56FE */}\n <a href={productUrl} className={cn('relative mx-auto h-[196px] w-fit md:h-[120px] md-xxl:h-[138px]')}>\n <Picture\n className=\"mx-auto h-full w-auto\"\n imgClassName=\"h-full object-contain\"\n source={\n itemData?.productVariant?.metafields?.global?.transparentImg ||\n itemData?.config?.image?.url ||\n itemData?.productVariant?.image?.url\n }\n ></Picture>\n </a>\n\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className={cn('mt-[10px] xl:mt-[8px] w-full')}>\n {/* \u4EA7\u54C1\u6807\u9898 - \u4F7F\u7528\u4EA7\u54C1\u7684\u771F\u5B9E\u6807\u9898 */}\n <Text\n html={itemData?.product?.title}\n title={itemData?.product?.title}\n className=\"line-clamp-2 text-[24px] min-h-[58px] l-xxl:min-h-[48px] l:min-h-[38px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#080A0F]\"\n />\n\n {/* \u4EF7\u683C\u4FE1\u606F */}\n <div className=\"mt-[24px] l:mt-[12px] flex flex-col gap-[8px] l:gap-0\">\n {/* Member Price \u6807\u7B7E - \u4F7F\u7528 text-brand-color-1 */}\n <Text\n html={copy.memberPriceLabel}\n className={cn(\n 'text-brand-color-0 text-[16px] l-xl:text-[14px] l:text-[12px] w-fit font-bold leading-[1.4] tracking-[-0.28px]',\n brand === 'ankersolix' &&\n 'leading-none bg-gradient-to-r from-[#2c7ed0] via-[#00a9e1] via-[43%] to-[#00db84] bg-clip-text text-transparent'\n )}\n as=\"p\"\n />\n\n {/* \u4F1A\u5458\u4EF7\u548C\u539F\u4EF7\u5728\u540C\u4E00\u884C */}\n <div className=\"flex items-center gap-[4px]\">\n <Text\n html={formatPrice({\n amount: itemData.memberPrice,\n currencyCode: itemData?.productVariant?.price.currencyCode || 'USD',\n locale: locale,\n })}\n className=\"text-[24px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#080A0F]\"\n as=\"span\"\n />\n <Text\n html={formatPrice({\n amount: itemData.originalPrice,\n currencyCode: itemData?.productVariant?.price.currencyCode || 'USD',\n locale: locale,\n })}\n className=\"text-[24px] l-xxl:text-[20px] l:text-[16px] font-bold leading-[1.2] tracking-[-0.8px] text-[#4A4C56] line-through\"\n as=\"span\"\n />\n </div>\n\n {/* \u6309\u94AE\u7EC4 */}\n <div className=\"flex w-full mt-[8px] gap-[8px] l:flex-col\">\n {/* Add to Cart \u6309\u94AE */}\n <Button\n variant=\"secondary\"\n className=\"flex-1 md:w-full\"\n size=\"lg\"\n onClick={handleAddToCart}\n disabled={!isAvailable || !cartConfig?.addToCart || isAddingToCart}\n loading={isAddingToCart}\n >\n {copy.addToCart}\n </Button>\n\n {/* Shop Now \u6309\u94AE */}\n <Button\n variant=\"primary\"\n className=\"flex-1 md:w-full\"\n size=\"lg\"\n onClick={handleShopNow}\n disabled={!isAvailable || isBuying}\n loading={isBuying}\n >\n {copy.shopNowText}\n </Button>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default MemberPriceItem\n"],
|
|
5
|
+
"mappings": "AAmKQ,cAAAA,EA8CE,QAAAC,MA9CF,oBAnKR,OAAS,UAAAC,EAAQ,QAAAC,EAAM,WAAAC,EAAS,SAAAC,MAAa,wBAC7C,OAAS,WAAAC,EAAS,YAAAC,MAAgB,QAGlC,OAAS,eAAAC,EAAa,oBAAAC,MAAwB,mBAC9C,OAAS,cAAcC,EAAI,sBAAAC,EAAoB,aAAAC,MAAiB,gBAChE,OAAS,qBAAAC,MAAyB,sBAClC,OAAS,kBAAAC,MAAsB,qBAE/B,SAASC,EAAgB,CACvB,SAAAC,EACA,KAAAC,EACA,UAAAC,CACF,EAIG,CACD,KAAM,CAAE,MAAAC,EAAO,OAAAC,CAAO,EAAIT,EAAmB,EACvC,CAAE,QAAAU,EAAS,gBAAAC,EAAiB,WAAAC,EAAY,IAAAC,CAAI,EAAIX,EAAkB,EAClEY,EAAUX,EAAe,SAASK,CAAK,EAGvC,CAAE,QAASO,EAAQ,WAAYC,CAAS,EAAIf,EAAU,CAAC,EAAG,CAAE,aAAc,EAAK,CAAC,EAGhF,CAACgB,EAAgBC,CAAiB,EAAItB,EAAS,EAAK,EAEpDuB,EAAcxB,EAAQ,IACnBU,EAAS,gBAAgB,iBAC/B,CAACA,EAAS,gBAAgB,gBAAgB,CAAC,EAExCe,EAAUzB,EAAQ,IACf,CAAC,CAACe,EACR,CAACA,CAAO,CAAC,EAGNW,EAAgB1B,EAAQ,IAAM,CAClC,GAAI,CACF,MAAM2B,EAAejB,EAAS,gBAAgB,YAAY,mBAAmB,KAC7E,GAAI,CAACiB,EAAc,OAGnB,MAAMC,EAAYD,EAClB,GAAI,CAAC,MAAM,QAAQC,CAAS,GAAKA,EAAU,SAAW,EAAG,OAGzD,MAAMC,EAAM,IAAI,KAYhB,OAXsBD,EAAU,KAAME,GAAkB,CACtD,MAAMC,EAAWD,EAAS,UAAY,IAAI,KAAKA,EAAS,SAAS,EAAI,KAC/DE,EAASF,EAAS,QAAU,IAAI,KAAKA,EAAS,OAAO,EAAI,KAI/D,MADI,EAAAC,GAAYA,EAAWF,GACvBG,GAAUA,EAASH,EAGzB,CAAC,GAEqB,KACxB,OAASI,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,EACnD,MACF,CACF,EAAG,CAACvB,EAAS,gBAAgB,UAAU,CAAC,EAElCwB,EAAalC,EAAQ,IAAM,CAC/B,MAAMmC,EAAerB,IAAW,KAAO,GAAK,IAAIA,CAAM,GACtD,OAAOX,EAAiBO,EAAS,gBAAgB,EAAE,EAC/C,GAAGyB,CAAY,aAAazB,EAAS,QAAQ,MAAM,YAAYP,EAAiBO,EAAS,gBAAgB,EAAE,CAAC,GAAGQ,EAAI,WAAa,QAAQA,EAAI,UAAU,GAAK,EAAE,GAC7J,GAAGiB,CAAY,aAAazB,EAAS,QAAQ,MAAM,GAAGQ,EAAI,WAAa,QAAQA,EAAI,UAAU,GAAK,EAAE,EAC1G,EAAG,CAACR,EAAS,gBAAgB,GAAIA,EAAS,QAAQ,OAAQQ,EAAI,WAAYJ,CAAM,CAAC,EAG3EsB,EAAkB,SAAY,CAClC,GAAI,CAACnB,GAAY,UAAW,CAC1B,QAAQ,KAAK,kCAAkC,EAC/C,MACF,CAEA,GAAI,CACFM,EAAkB,EAAI,EAGtB,MAAMc,EAA4D,CAAC,EAC/DX,GACFW,EAAmB,KAAK,CACtB,IAAK,gBACL,MAAO,KAAK,UAAU,CAAE,KAAMX,CAAc,CAAC,CAC/C,CAAC,EAGH,MAAMT,EAAW,UAAU,CACzB,YAAa,CACX,CACE,QAASP,EAAS,eAClB,SAAU,EACV,WAAY2B,EAAmB,OAAS,EAAIA,EAAqB,MACnE,CACF,EACA,eAAgB,CACd,aAAc,OAAOtB,GAAS,YAAc,CAAC,CAC/C,EACA,cAAeW,EAAgB,CAACA,CAAa,EAAI,MACnD,CAAC,CACH,OAASO,EAAO,CACd,QAAQ,MAAM,sBAAuBA,CAAK,CAC5C,QAAE,CACAV,EAAkB,EAAK,CACzB,CACF,EAGMe,EAAgB,IAAM,CAE1B,GAAI,CAACb,EAAS,CACZT,EAAgB,EAChB,MACF,CAGA,MAAMqB,EAA4D,CAAC,EAC/DX,GACFW,EAAmB,KAAK,CACtB,IAAK,gBACL,MAAO,KAAK,UAAU,CAAE,KAAMX,CAAc,CAAC,CAC/C,CAAC,EAIHN,EAAO,CACL,iBAAkB,CAChB,CACE,IAAK,eACL,MAAO,OAAOL,GAAS,YAAc,CAAC,CACxC,CACF,EACA,UAAW,CACT,CACE,QAASL,EAAS,eAClB,SAAU,EACV,WAAY2B,EAAmB,OAAS,EAAIA,EAAqB,MACnE,CACF,EACA,cAAeX,EAAgB,CAACA,CAAa,EAAI,OACjD,UAAW,CACT,UAAWR,EAAI,UACf,SAAU,mBACZ,CACF,CAAC,CACH,EAEA,OACEvB,EAAC,OACC,UAAWS,EACT,8JACA,CAACe,GAAW,+BACZR,EAAK,WAAa,wBAA0B,uCAC5CC,CACF,EAGC,UAAAD,EAAK,YACJjB,EAACK,EAAA,CACC,UAAU,wEACV,KAAK,KACL,QAAQ,cACR,gBAAgB,iBAEf,SAAAY,EAAK,WACR,EAIFjB,EAAC,KAAE,KAAMwC,EAAY,UAAW9B,EAAG,gEAAgE,EACjG,SAAAV,EAACI,EAAA,CACC,UAAU,wBACV,aAAa,wBACb,OACEY,GAAU,gBAAgB,YAAY,QAAQ,gBAC9CA,GAAU,QAAQ,OAAO,KACzBA,GAAU,gBAAgB,OAAO,IAEpC,EACH,EAGAf,EAAC,OAAI,UAAWS,EAAG,8BAA8B,EAE/C,UAAAV,EAACG,EAAA,CACC,KAAMa,GAAU,SAAS,MACzB,MAAOA,GAAU,SAAS,MAC1B,UAAU,mKACZ,EAGAf,EAAC,OAAI,UAAU,wDAEb,UAAAD,EAACG,EAAA,CACC,KAAMc,EAAK,iBACX,UAAWP,EACT,iHACAS,IAAU,cACR,iHACJ,EACA,GAAG,IACL,EAGAlB,EAAC,OAAI,UAAU,8BACb,UAAAD,EAACG,EAAA,CACC,KAAMK,EAAY,CAChB,OAAQQ,EAAS,YACjB,aAAcA,GAAU,gBAAgB,MAAM,cAAgB,MAC9D,OAAQI,CACV,CAAC,EACD,UAAU,uGACV,GAAG,OACL,EACApB,EAACG,EAAA,CACC,KAAMK,EAAY,CAChB,OAAQQ,EAAS,cACjB,aAAcA,GAAU,gBAAgB,MAAM,cAAgB,MAC9D,OAAQI,CACV,CAAC,EACD,UAAU,oHACV,GAAG,OACL,GACF,EAGAnB,EAAC,OAAI,UAAU,4CAEb,UAAAD,EAACE,EAAA,CACC,QAAQ,YACR,UAAU,mBACV,KAAK,KACL,QAASwC,EACT,SAAU,CAACZ,GAAe,CAACP,GAAY,WAAaK,EACpD,QAASA,EAER,SAAAX,EAAK,UACR,EAGAjB,EAACE,EAAA,CACC,QAAQ,UACR,UAAU,mBACV,KAAK,KACL,QAAS0C,EACT,SAAU,CAACd,GAAeH,EAC1B,QAASA,EAER,SAAAV,EAAK,YACR,GACF,GACF,GACF,GACF,CAEJ,CAEA,IAAO4B,EAAQ9B",
|
|
6
|
+
"names": ["jsx", "jsxs", "Button", "Text", "Picture", "Badge", "useMemo", "useState", "formatPrice", "extractVariantId", "cn", "useHeadlessContext", "useBuyNow", "useCreditsContext", "ROUNDED_BRANDS", "MemberPriceItem", "itemData", "copy", "className", "brand", "locale", "profile", "openSignUpPopup", "cartConfig", "gtm", "rounded", "buyNow", "isBuying", "isAddingToCart", "setIsAddingToCart", "isAvailable", "isLogin", "getCouponCode", "discountData", "discounts", "now", "discount", "startsAt", "endsAt", "error", "productUrl", "localePrefix", "handleAddToCart", "lineItemAttributes", "handleShopNow", "MemberPriceItem_default"]
|
|
7
7
|
}
|
|
@@ -43,7 +43,6 @@ export type CreditsMemberPriceCopy = {
|
|
|
43
43
|
products: {
|
|
44
44
|
handle: string;
|
|
45
45
|
sku: string;
|
|
46
|
-
href?: string;
|
|
47
46
|
}[];
|
|
48
47
|
})[];
|
|
49
48
|
soldOut: string;
|
|
@@ -59,6 +58,5 @@ export type MemberPriceProduct = {
|
|
|
59
58
|
config?: MemberPriceItemConfig;
|
|
60
59
|
memberPrice: number;
|
|
61
60
|
originalPrice: number;
|
|
62
|
-
productHref?: string;
|
|
63
61
|
};
|
|
64
62
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Fragment as le,jsx as o,jsxs as A}from"react/jsx-runtime";import{Container as B,Heading as U,Tabs as V,TabsList as j,TabsTrigger as q}from"@anker-in/headless-ui";import v from"classnames";import{useCallback as J,useMemo as x,useState as y}from"react";import K from"./RedeemCouponModal";import Q from"./RedeemProductModal";import W from"./RedeemVirtualProductModal";import{useCreditsContext as X}from"../context/provider";import Y from"../context/hooks/useRedeemableList";import{AlpcConsumeType as E,AlpcErrorCode as Z,ConsumeType as l}from"../context/const";import{useHeadlessContext as ee,useProductsByHandles as te,gaTrack as re,classNames as M}from"@anker-in/lib";import{RedeemableItem as oe}from"./RedeemableItem";import{ROUNDED_BRANDS as ne}from"../../../constants";import ae from"../modal/RulesModal";import{useRegistration as
|
|
1
|
+
import{Fragment as le,jsx as o,jsxs as A}from"react/jsx-runtime";import{Container as B,Heading as U,Tabs as V,TabsList as j,TabsTrigger as q}from"@anker-in/headless-ui";import v from"classnames";import{useCallback as J,useMemo as x,useState as y}from"react";import K from"./RedeemCouponModal";import Q from"./RedeemProductModal";import W from"./RedeemVirtualProductModal";import{useCreditsContext as X}from"../context/provider";import Y from"../context/hooks/useRedeemableList";import{AlpcConsumeType as E,AlpcErrorCode as Z,ConsumeType as l}from"../context/const";import{useHeadlessContext as ee,useProductsByHandles as te,gaTrack as re,classNames as M}from"@anker-in/lib";import{RedeemableItem as oe}from"./RedeemableItem";import{ROUNDED_BRANDS as ne}from"../../../constants";import ae from"../modal/RulesModal";import{useRegistration as ie}from"../../../components/registration";import{numberFormat as se}from"../context/utils";import de from"../context/hooks/useMyRewards";const ke=({copy:t,id:P})=>{const{profile:R,openSignUpPopup:G,gtm:{pageGroup:D},pageCommon:u,creditInfo:F}=X(),{authCodeActivate:c}=ie(),{brand:h}=ee(),T=ne.includes(h),m=Object.keys(R||{}).length>0,[g,O]=y(t.list?.[0]?.label||""),[n,p]=y(void 0),[f,L]=y(),{listLoading:w,redeemableList:N,getRedeemableList:S}=Y(),{myRewards:_}=de({page:1,pageSize:100,consumeType:E.ExternalProduct}),s=x(()=>({...u?.redeemModal||{},...t.redeemModal||{}}),[t.redeemModal,u?.redeemModal]),d=x(()=>N.map(e=>({id:e.id.toString(),title:e.name,consumeCredits:e.consume_credits,remainingInventory:e.remaining_inventory,isLimited:!!e.is_limited,consumeType:e.consume_type,handle:e.sku_handle,sku:e.goods_sku,image:e.goods_url})),[t.list,g,N]),H=d.map(e=>e.handle),{data:k}=te({handles:H}),$=x(()=>(t.list?.find(r=>r.label===g)?.list||[]).filter(r=>d.some(i=>String(i.id)===String(r.id))).map(r=>{const i=d.find(a=>String(a.id)===String(r.id)),C=k?.find(a=>a.handle===i?.handle),I=C?.variants.find(a=>a.sku===i?.sku);if(i?.isLimited&&(!i?.remainingInventory||i.remainingInventory<=0)||i?.consumeType===E.Product&&(!C||!I))return null;const z=r.type===l.GoGift&&m&&_.some(a=>a.rule_id===Number(r.id));return{alpc:d.find(a=>String(a.id)===String(r.id)),config:r,product:C,variant:I,hasRedeemed:z}}).filter(r=>r!==null),[d,k,m,_]),b=J(e=>{e===Z.CodeLpcRuleInventoryNotEnough&&S()},[S]);return A(B,{id:P,className:v("relative bg-[#F5F5F7]"),children:[o(U,{as:"h2",size:"4",html:t.title}),m&&t.availableCredits&&o("p",{className:"mt-[12px] text-[20px] l-xxl:text-[18px] l:text-[16px] font-bold text-[#4A4C56]",children:t.availableCredits.includes("$credits")?A(le,{children:[t.availableCredits.split("$credits")[0],o("span",{className:M("text-brand-color-0",h==="ankersolix"&&"bg-gradient-to-r from-[#2c7ed0] via-[#00a9e1] via-[43%] to-[#00db84] bg-clip-text text-transparent"),children:se(F?.available_credit||0).toString()}),t.availableCredits.split("$credits")[1]||""]}):t.availableCredits}),o(V,{shape:T?"rounded":"square",align:"left",className:v("py-[24px] md:justify-center"),value:g.toString(),onValueChange:e=>{O(e),re({event:"ga4Event",event_name:"lp_navigation",event_parameters:{navigation:e,page_group:D}})},children:o(j,{children:(t.list||[]).map(e=>o(q,{value:e.label,children:e.label},e.label))})}),!!d?.length&&!w&&o("div",{className:v("relative grid grid-cols-4 gap-[16px] md:grid-cols-2 md:gap-[12px] md-xl:grid-cols-3"),children:$?.map(e=>o(oe,{copy:t,item:e,onRedeem:r=>{m?!R?.activated&&!c.isActivateSuccess?(c.setAutoSendEmail(!0),c.open()):p(r):G()},onRulesOpen:L},e?.alpc?.id))}),(n?.config?.type===l.Coupon||n?.config?.type===l.ShippingCoupon)&&s?.coupon&&n&&o(K,{item:n,copy:s,onError:b,onClose:()=>{p(void 0)}}),n?.config?.type===l.Product&&s?.product&&n&&o(Q,{item:n,copy:s,onError:b,onClose:()=>{p(void 0)}}),(n?.config?.type===l.GiftCard||n?.config?.type===l.GoGift)&&s?.virtualProduct&&n&&o(W,{item:n,copy:s,onError:b,onClose:()=>{p(void 0)}}),f&&o(ae,{overlayClassName:"md:px-[16px] md:items-center",className:M("md:h-fit md:rounded-b-[16px]",!T&&"md:rounded-none"),isOpen:f.length>0,onClose:()=>L([]),titleClassName:"border-b-transparent h-[56px]",rules:f,scrollClassName:"md:mt-[8px] md:mb-[24px] md:pt-0",title:u?.ruleLabel,ruleClassName:"text-[#1d1d1f] font-bold"})]})};export{ke as CreditsRedeemList};
|
|
2
2
|
//# sourceMappingURL=CreditsRedeemList.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/credits/creditsRedeemList/CreditsRedeemList.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Container, Heading, Tabs, TabsList, TabsTrigger } from '@anker-in/headless-ui'\nimport classNames from 'classnames'\nimport { useCallback, useMemo, useState } from 'react'\n\nimport RedeemCouponModal from './RedeemCouponModal'\nimport RedeemProductModal from './RedeemProductModal'\nimport RedeemVirtualProductModal from './RedeemVirtualProductModal'\nimport { useCreditsContext } from '../context/provider'\nimport useRedeemableList from '../context/hooks/useRedeemableList'\nimport { AlpcConsumeType, AlpcErrorCode, ConsumeType } from '../context/const'\nimport { useHeadlessContext, useProductsByHandles, gaTrack, classNames as cn } from '@anker-in/lib'\nimport type { RedeemableItem as RedeemableItemType } from '../type'\nimport { RedeemableItem } from './RedeemableItem'\nimport { ROUNDED_BRANDS } from '../../../constants'\nimport RulesModal from '../modal/RulesModal'\nimport { CreditsRedeemListCopy } from './type'\nimport { useRegistration } from '../../../components/registration'\nimport { numberFormat } from '../context/utils'\nimport useMyRewards from '../context/hooks/useMyRewards'\n\nexport const CreditsRedeemList = ({ copy, id }: { copy: CreditsRedeemListCopy; id?: string }) => {\n const {\n profile,\n openSignUpPopup,\n gtm: { pageGroup },\n pageCommon,\n creditInfo,\n } = useCreditsContext()\n const { authCodeActivate } = useRegistration()\n const { brand } = useHeadlessContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n const isLogin = Object.keys(profile || {}).length > 0\n\n const [activeTab, setActiveTab] = useState<string>(copy.list?.[0]?.label || '')\n\n const [popRedeemData, setPopRedeemData] = useState<RedeemableItemType | undefined>(undefined)\n\n const [rules, setRules] = useState<string | string[]>()\n\n const { listLoading, redeemableList, getRedeemableList } = useRedeemableList()\n\n // \u83B7\u53D6\u7528\u6237\u7684 ExternalProduct \u5151\u6362\u8BB0\u5F55\n const { myRewards } = useMyRewards({\n page: 1,\n pageSize: 100,\n consumeType: AlpcConsumeType.ExternalProduct,\n })\n\n // \u5408\u5E76 redeemModal \u6587\u6848\uFF0C\u4F18\u5148\u4F7F\u7528 copy.redeemModal\uFF0Cfallback \u5230 pageCommon.redeemModal\n const redeemModalCopy = useMemo(() => {\n return {\n ...(pageCommon?.redeemModal || {}),\n ...(copy.redeemModal || {}),\n }\n }, [copy.redeemModal, pageCommon?.redeemModal])\n\n const alpcList = useMemo(() => {\n return redeemableList.map(item => {\n return {\n id: item.id.toString(),\n title: item.name,\n consumeCredits: item.consume_credits,\n remainingInventory: item.remaining_inventory,\n isLimited: !!item.is_limited,\n consumeType: item.consume_type,\n handle: item.sku_handle,\n sku: item.goods_sku,\n image: item.goods_url,\n }\n })\n }, [copy.list, activeTab, redeemableList])\n\n const handles = alpcList.map(item => item.handle)\n const { data: products } = useProductsByHandles({ handles })\n\n const list = useMemo(() => {\n const currentList = copy.list?.find(item => item.label === activeTab)\n return (currentList?.list || [])\n .filter(item => alpcList.some(alpcItem => String(alpcItem.id) === String(item.id)))\n .map(item => {\n const alpcItem = alpcList.find(alpcItem => String(alpcItem.id) === String(item.id))\n const product = products?.find(product => product.handle === alpcItem?.handle)\n const variant = product?.variants.find(variant => variant.sku === alpcItem?.sku)\n // \u8FC7\u6EE4\u6389\u5E93\u5B58\u4E0D\u8DB3\u7684\u5546\u54C1\n if (alpcItem?.isLimited && (!alpcItem?.remainingInventory || alpcItem.remainingInventory <= 0)) return null\n if (alpcItem?.consumeType === AlpcConsumeType.Product && (!product || !variant)) return null\n\n // \u68C0\u67E5 GoGift \u662F\u5426\u5DF2\u7ECF\u5151\u6362\u8FC7\uFF08\u53EA\u6709 GoGift \u9650\u5236\u5151\u6362\u4E00\u6B21\uFF09\n const hasRedeemed = item.type === ConsumeType.GoGift &&\n isLogin &&\n myRewards.some(reward => reward.rule_id === Number(item.id))\n\n return {\n alpc: alpcList.find(alpcItem => String(alpcItem.id) === String(item.id)),\n config: item,\n product,\n variant,\n hasRedeemed,\n
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { Container, Heading, Tabs, TabsList, TabsTrigger } from '@anker-in/headless-ui'\nimport classNames from 'classnames'\nimport { useCallback, useMemo, useState } from 'react'\n\nimport RedeemCouponModal from './RedeemCouponModal'\nimport RedeemProductModal from './RedeemProductModal'\nimport RedeemVirtualProductModal from './RedeemVirtualProductModal'\nimport { useCreditsContext } from '../context/provider'\nimport useRedeemableList from '../context/hooks/useRedeemableList'\nimport { AlpcConsumeType, AlpcErrorCode, ConsumeType } from '../context/const'\nimport { useHeadlessContext, useProductsByHandles, gaTrack, classNames as cn } from '@anker-in/lib'\nimport type { RedeemableItem as RedeemableItemType } from '../type'\nimport { RedeemableItem } from './RedeemableItem'\nimport { ROUNDED_BRANDS } from '../../../constants'\nimport RulesModal from '../modal/RulesModal'\nimport { CreditsRedeemListCopy } from './type'\nimport { useRegistration } from '../../../components/registration'\nimport { numberFormat } from '../context/utils'\nimport useMyRewards from '../context/hooks/useMyRewards'\n\nexport const CreditsRedeemList = ({ copy, id }: { copy: CreditsRedeemListCopy; id?: string }) => {\n const {\n profile,\n openSignUpPopup,\n gtm: { pageGroup },\n pageCommon,\n creditInfo,\n } = useCreditsContext()\n const { authCodeActivate } = useRegistration()\n const { brand } = useHeadlessContext()\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n const isLogin = Object.keys(profile || {}).length > 0\n\n const [activeTab, setActiveTab] = useState<string>(copy.list?.[0]?.label || '')\n\n const [popRedeemData, setPopRedeemData] = useState<RedeemableItemType | undefined>(undefined)\n\n const [rules, setRules] = useState<string | string[]>()\n\n const { listLoading, redeemableList, getRedeemableList } = useRedeemableList()\n\n // \u83B7\u53D6\u7528\u6237\u7684 ExternalProduct \u5151\u6362\u8BB0\u5F55\n const { myRewards } = useMyRewards({\n page: 1,\n pageSize: 100,\n consumeType: AlpcConsumeType.ExternalProduct,\n })\n\n // \u5408\u5E76 redeemModal \u6587\u6848\uFF0C\u4F18\u5148\u4F7F\u7528 copy.redeemModal\uFF0Cfallback \u5230 pageCommon.redeemModal\n const redeemModalCopy = useMemo(() => {\n return {\n ...(pageCommon?.redeemModal || {}),\n ...(copy.redeemModal || {}),\n }\n }, [copy.redeemModal, pageCommon?.redeemModal])\n\n const alpcList = useMemo(() => {\n return redeemableList.map(item => {\n return {\n id: item.id.toString(),\n title: item.name,\n consumeCredits: item.consume_credits,\n remainingInventory: item.remaining_inventory,\n isLimited: !!item.is_limited,\n consumeType: item.consume_type,\n handle: item.sku_handle,\n sku: item.goods_sku,\n image: item.goods_url,\n }\n })\n }, [copy.list, activeTab, redeemableList])\n\n const handles = alpcList.map(item => item.handle)\n const { data: products } = useProductsByHandles({ handles })\n\n const list = useMemo(() => {\n const currentList = copy.list?.find(item => item.label === activeTab)\n return (currentList?.list || [])\n .filter(item => alpcList.some(alpcItem => String(alpcItem.id) === String(item.id)))\n .map(item => {\n const alpcItem = alpcList.find(alpcItem => String(alpcItem.id) === String(item.id))\n const product = products?.find(product => product.handle === alpcItem?.handle)\n const variant = product?.variants.find(variant => variant.sku === alpcItem?.sku)\n // \u8FC7\u6EE4\u6389\u5E93\u5B58\u4E0D\u8DB3\u7684\u5546\u54C1\n if (alpcItem?.isLimited && (!alpcItem?.remainingInventory || alpcItem.remainingInventory <= 0)) return null\n if (alpcItem?.consumeType === AlpcConsumeType.Product && (!product || !variant)) return null\n\n // \u68C0\u67E5 GoGift \u662F\u5426\u5DF2\u7ECF\u5151\u6362\u8FC7\uFF08\u53EA\u6709 GoGift \u9650\u5236\u5151\u6362\u4E00\u6B21\uFF09\n const hasRedeemed = item.type === ConsumeType.GoGift &&\n isLogin &&\n myRewards.some(reward => reward.rule_id === Number(item.id))\n\n return {\n alpc: alpcList.find(alpcItem => String(alpcItem.id) === String(item.id)),\n config: item,\n product,\n variant,\n hasRedeemed,\n }\n })\n .filter(item => item !== null) as unknown as RedeemableItemType[]\n }, [alpcList, products, isLogin, myRewards])\n\n const handleRedeemError = useCallback(\n (errorCode: AlpcErrorCode) => {\n if (errorCode === AlpcErrorCode.CodeLpcRuleInventoryNotEnough) {\n getRedeemableList()\n }\n },\n [getRedeemableList]\n )\n\n return (\n <Container id={id} className={classNames('relative bg-[#F5F5F7]')}>\n <Heading as=\"h2\" size=\"4\" html={copy.title} />\n\n {/* \u53EF\u7528\u79EF\u5206\u5C55\u793A */}\n {isLogin && copy.availableCredits && (\n <p className=\"mt-[12px] text-[20px] l-xxl:text-[18px] l:text-[16px] font-bold text-[#4A4C56]\">\n {copy.availableCredits.includes('$credits') ? (\n <>\n {copy.availableCredits.split('$credits')[0]}\n <span\n className={cn(\n 'text-brand-color-0',\n brand === 'ankersolix' &&\n 'bg-gradient-to-r from-[#2c7ed0] via-[#00a9e1] via-[43%] to-[#00db84] bg-clip-text text-transparent'\n )}\n >\n {numberFormat(creditInfo?.available_credit || 0).toString()}\n </span>\n {copy.availableCredits.split('$credits')[1] || ''}\n </>\n ) : (\n copy.availableCredits\n )}\n </p>\n )}\n\n <Tabs\n shape={rounded ? 'rounded' : 'square'}\n align=\"left\"\n className={classNames('py-[24px] md:justify-center')}\n value={activeTab.toString()}\n onValueChange={value => {\n setActiveTab(value)\n gaTrack({\n event: 'ga4Event',\n event_name: 'lp_navigation',\n event_parameters: {\n navigation: value,\n page_group: pageGroup,\n },\n })\n }}\n >\n <TabsList>\n {(copy.list || []).map(item => (\n <TabsTrigger key={item.label} value={item.label}>\n {item.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n {/* PC\u7AEF */}\n {!!alpcList?.length && !listLoading && (\n <div\n className={classNames('relative grid grid-cols-4 gap-[16px] md:grid-cols-2 md:gap-[12px] md-xl:grid-cols-3')}\n >\n {list?.map(item => (\n <RedeemableItem\n key={item?.alpc?.id}\n copy={copy}\n item={item}\n onRedeem={(item: RedeemableItemType) => {\n if (!isLogin) {\n openSignUpPopup()\n } else if (!profile?.activated && !authCodeActivate.isActivateSuccess) {\n authCodeActivate.setAutoSendEmail(true)\n authCodeActivate.open()\n } else {\n setPopRedeemData(item)\n }\n }}\n onRulesOpen={setRules}\n />\n ))}\n </div>\n )}\n\n {(popRedeemData?.config?.type === ConsumeType.Coupon ||\n popRedeemData?.config?.type === ConsumeType.ShippingCoupon) &&\n redeemModalCopy?.coupon &&\n popRedeemData && (\n <RedeemCouponModal\n item={popRedeemData}\n copy={redeemModalCopy}\n onError={handleRedeemError}\n onClose={() => {\n setPopRedeemData(undefined)\n }}\n />\n )}\n {popRedeemData?.config?.type === ConsumeType.Product && redeemModalCopy?.product && popRedeemData && (\n <RedeemProductModal\n item={popRedeemData}\n copy={redeemModalCopy}\n onError={handleRedeemError}\n onClose={() => {\n setPopRedeemData(undefined)\n }}\n />\n )}\n {(popRedeemData?.config?.type === ConsumeType.GiftCard || popRedeemData?.config?.type === ConsumeType.GoGift) &&\n redeemModalCopy?.virtualProduct &&\n popRedeemData && (\n <RedeemVirtualProductModal\n item={popRedeemData}\n copy={redeemModalCopy}\n onError={handleRedeemError}\n onClose={() => {\n setPopRedeemData(undefined)\n }}\n />\n )}\n {rules && (\n <RulesModal\n overlayClassName=\"md:px-[16px] md:items-center\"\n className={cn('md:h-fit md:rounded-b-[16px]', !rounded && 'md:rounded-none')}\n isOpen={rules.length > 0}\n onClose={() => setRules([])}\n titleClassName=\"border-b-transparent h-[56px]\"\n rules={rules}\n scrollClassName=\"md:mt-[8px] md:mb-[24px] md:pt-0\"\n title={pageCommon?.ruleLabel}\n ruleClassName=\"text-[#1d1d1f] font-bold\"\n />\n )}\n </Container>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "Container", "Heading", "Tabs", "TabsList", "TabsTrigger", "classNames", "useCallback", "useMemo", "useState", "RedeemCouponModal", "RedeemProductModal", "RedeemVirtualProductModal", "useCreditsContext", "useRedeemableList", "AlpcConsumeType", "AlpcErrorCode", "ConsumeType", "useHeadlessContext", "useProductsByHandles", "gaTrack", "cn", "RedeemableItem", "ROUNDED_BRANDS", "RulesModal", "useRegistration", "numberFormat", "useMyRewards", "CreditsRedeemList", "copy", "id", "profile", "openSignUpPopup", "pageGroup", "pageCommon", "creditInfo", "authCodeActivate", "brand", "rounded", "isLogin", "activeTab", "setActiveTab", "popRedeemData", "setPopRedeemData", "rules", "setRules", "listLoading", "redeemableList", "getRedeemableList", "myRewards", "redeemModalCopy", "alpcList", "item", "handles", "products", "list", "alpcItem", "product", "variant", "hasRedeemed", "reward", "handleRedeemError", "errorCode", "value"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as t,jsxs as
|
|
1
|
+
import{jsx as t,jsxs as i}from"react/jsx-runtime";import{Button as I,Text as v,Picture as d}from"@anker-in/headless-ui";import{useMemo as c}from"react";import u from"classnames";import{useCreditsContext as P}from"../context/provider";import{AlpcConsumeType as g,ConsumeType as b}from"../context/const";import{numberFormat as k,extractVariantId as h}from"../context/utils";import{gaTrack as y,useHeadlessContext as S}from"@anker-in/lib";import{NoneProductValue as z}from"./NonProductValue";import{ROUNDED_BRANDS as E}from"../../../constants";function U({copy:a,className:_,item:e,onRulesOpen:N,onRedeem:R}){const{creditInfo:m,profile:n,gtm:{pageGroup:x,pageHandle:r},pageCommon:o}=P(),{brand:C,locale:s}=S(),p=Object.keys(n||{}).length>0,T=E.includes(C),$=c(()=>!!(e.hasRedeemed||e.alpc?.remainingInventory<=0&&e.alpc?.isLimited||e.alpc?.consumeType===g.Product&&!e.variant?.availableForSale||p&&n?.activated&&e.alpc?.consumeCredits>Number(m?.available_credit||0)),[e.hasRedeemed,e.alpc?.remainingInventory,e.alpc?.isLimited,e.alpc?.consumeType,e.alpc?.consumeCredits,p,n?.activated,m?.available_credit,e.variant?.availableForSale]),f=c(()=>p?e.alpc?.consumeType===g.Product?e.variant?.availableForSale?a.btnRedeem:o?.soldOut||"Sold Out":a.btnRedeem:a.unlockRewards,[p,e.alpc?.consumeType,e.variant?.availableForSale,a.btnRedeem,a.unlockRewards,o?.soldOut]),w=c(()=>{if(e.config?.type!==b.Product||!e.product?.handle)return;const l=s==="us"?"":`/${s}`;return h(e.variant?.id)?`${l}/products/${e.product.handle}?variant=${h(e.variant?.id)}${r?`&ref=${r}`:""}`:`${l}/products/${e.product.handle}${r?`?ref=${r}`:""}`},[e.config?.type,e.product?.handle,e.variant?.id,r,s]);return i("div",{className:u("flex flex-col items-center rounded-[16px] bg-[#EAEAEC] p-[24px] md:rounded-[12px] md:px-[8px] xl:py-[16px] md-xl:px-[16px]",!T&&"rounded-none md:rounded-none",_),children:[e.config?.type===b.Product?t("a",{href:w,className:u("relative mx-auto h-[224px] w-fit md:my-[10px] l:h-[120px] l-xxl:h-[138px]"),children:t(d,{className:"h-full w-auto [&_img]:h-full [&_img]:object-contain",source:e.config?.image?.url||e.product?.images?.[0]?.url})}):i("div",{className:"relative mx-auto my-[30px] h-[164px] md:my-0 md:h-[66px] l-xxl:h-[138px] md-l:h-[80px]",children:[t(d,{source:o?.imageMapping?.[e.config?.type]?.url,className:"h-full [&_img]:h-full [&_img]:w-auto [&_img]:object-contain"}),t(z,{item:e})]}),i("div",{className:u("mt-[10px] xl:mt-[8px] flex w-full flex-1 flex-col justify-between"),children:[t(v,{html:e.config?.title||e.alpc?.title,title:e.config?.title||e.alpc?.title,size:2,className:"line-clamp-2 h-[58px] text-[24px] leading-[1.2] l:h-[40px] l:text-[16px] l-xxl:h-[48px] l-xxl:text-[20px]"}),e.config?.rules?.length>0&&t("button",{type:"button",onClick:()=>{N(e.config?.rules||[]),y({event:"ga4Event",event_name:"lp_button",member_active_status:n?.activated?"active":"not active",event_parameters:{page_group:x,position:a.title,button_name:o?.ruleLabel,info:e.alpc?.id?.toString()}})},className:"mt-[8px] w-fit text-[16px] font-bold underline md:text-[14px] l:mt-0",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&l.preventDefault()},children:o?.ruleLabel}),i("div",{children:[i("div",{className:"mt-[26px] flex items-center l:mt-[12px] l-xl:mt-[16px]",children:[t(d,{className:"size-[24px] l-xxl:size-[22px] md-l:size-[18px] md:size-[16px]",source:"https://cdn.shopify.com/s/files/1/0511/6346/3874/files/icon_hire_purchase.png?v=1757496783"}),t(v,{html:`${k(e.alpc?.consumeCredits)}`,size:2,as:"p",className:"ml-[4px] text-[24px] font-bold mt-[4px] leading-none l-xxl:text-[20px] l:text-[16px] "})]}),t(I,{disabled:$,variant:"primary",size:"lg",className:"mt-[8px] md:px-[8px] l:w-full",onClick:()=>{R(e),y({event:"ga4Event",event_name:"lp_button",member_active_status:n?.activated?"active":"not active",event_parameters:{page_group:x,position:a.title,button_name:f,info:e.alpc?.id?.toString()}})},children:f})]})]})]})}export{U as RedeemableItem};
|
|
2
2
|
//# sourceMappingURL=RedeemableItem.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/credits/creditsRedeemList/RedeemableItem.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Button, Text, Picture } from '@anker-in/headless-ui'\n\nimport { useMemo } from 'react'\n\nimport classNames from 'classnames'\nimport { useCreditsContext } from '../context/provider'\nimport type { RedeemableItem as RedeemableItemType } from '../type'\nimport { AlpcConsumeType, ConsumeType } from '../context/const'\nimport { numberFormat, extractVariantId } from '../context/utils'\nimport type { CreditsRedeemListCopy } from './type'\nimport { gaTrack, useHeadlessContext } from '@anker-in/lib'\nimport { NoneProductValue } from './NonProductValue'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nexport function RedeemableItem({\n copy,\n className,\n item,\n onRulesOpen,\n onRedeem,\n}: {\n copy: CreditsRedeemListCopy\n className?: string\n item: RedeemableItemType\n onRulesOpen: (rules: string[]) => void\n onRedeem: (item: RedeemableItemType) => void\n}) {\n const {\n creditInfo,\n profile,\n gtm: { pageGroup, pageHandle },\n pageCommon,\n } = useCreditsContext()\n const { brand } = useHeadlessContext()\n const isLogin = Object.keys(profile || {}).length > 0\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n const isDisabled = useMemo(() => {\n if (item.hasRedeemed) {\n return true\n }\n\n if (item.alpc?.remainingInventory <= 0 && item.alpc?.isLimited) {\n // \u6709\u5E93\u5B58\u9650\u5236\n return true\n }\n\n if (item.alpc?.consumeType === AlpcConsumeType.Product) {\n if (!item.variant?.availableForSale) {\n return true\n }\n }\n if (isLogin && profile?.activated && item.alpc?.consumeCredits > Number(creditInfo?.available_credit || 0)) {\n return true\n }\n return false\n }, [\n item.hasRedeemed,\n item.alpc?.remainingInventory,\n item.alpc?.isLimited,\n item.alpc?.consumeType,\n item.alpc?.consumeCredits,\n isLogin,\n profile?.activated,\n creditInfo?.available_credit,\n item.variant?.availableForSale,\n ])\n\n const redeemButtonText = useMemo(() => {\n if (!isLogin) {\n return copy.unlockRewards\n }\n\n // \u7F3A\u8D27\u6587\u6848\n if (item.alpc?.consumeType === AlpcConsumeType.Product) {\n return item.variant?.availableForSale ? copy.btnRedeem : pageCommon?.soldOut || 'Sold Out'\n }\n return copy.btnRedeem\n }, [\n isLogin,\n item.alpc?.consumeType,\n item.variant?.availableForSale,\n copy.btnRedeem,\n copy.unlockRewards,\n pageCommon?.soldOut,\n ])\n\n // \u751F\u6210\u4EA7\u54C1 listing \u9875\u9762\u94FE\u63A5\n const productUrl = useMemo(() => {\n if (item.
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "Button", "Text", "Picture", "useMemo", "classNames", "useCreditsContext", "AlpcConsumeType", "ConsumeType", "numberFormat", "extractVariantId", "gaTrack", "useHeadlessContext", "NoneProductValue", "ROUNDED_BRANDS", "RedeemableItem", "copy", "className", "item", "onRulesOpen", "onRedeem", "creditInfo", "profile", "pageGroup", "pageHandle", "pageCommon", "brand", "isLogin", "rounded", "isDisabled", "redeemButtonText", "productUrl", "e"]
|
|
4
|
+
"sourcesContent": ["import { Button, Text, Picture } from '@anker-in/headless-ui'\n\nimport { useMemo } from 'react'\n\nimport classNames from 'classnames'\nimport { useCreditsContext } from '../context/provider'\nimport type { RedeemableItem as RedeemableItemType } from '../type'\nimport { AlpcConsumeType, ConsumeType } from '../context/const'\nimport { numberFormat, extractVariantId } from '../context/utils'\nimport type { CreditsRedeemListCopy } from './type'\nimport { gaTrack, useHeadlessContext } from '@anker-in/lib'\nimport { NoneProductValue } from './NonProductValue'\nimport { ROUNDED_BRANDS } from '../../../constants'\n\nexport function RedeemableItem({\n copy,\n className,\n item,\n onRulesOpen,\n onRedeem,\n}: {\n copy: CreditsRedeemListCopy\n className?: string\n item: RedeemableItemType\n onRulesOpen: (rules: string[]) => void\n onRedeem: (item: RedeemableItemType) => void\n}) {\n const {\n creditInfo,\n profile,\n gtm: { pageGroup, pageHandle },\n pageCommon,\n } = useCreditsContext()\n const { brand, locale } = useHeadlessContext()\n const isLogin = Object.keys(profile || {}).length > 0\n const rounded = ROUNDED_BRANDS.includes(brand)\n\n const isDisabled = useMemo(() => {\n if (item.hasRedeemed) {\n return true\n }\n\n if (item.alpc?.remainingInventory <= 0 && item.alpc?.isLimited) {\n // \u6709\u5E93\u5B58\u9650\u5236\n return true\n }\n\n if (item.alpc?.consumeType === AlpcConsumeType.Product) {\n if (!item.variant?.availableForSale) {\n return true\n }\n }\n if (isLogin && profile?.activated && item.alpc?.consumeCredits > Number(creditInfo?.available_credit || 0)) {\n return true\n }\n return false\n }, [\n item.hasRedeemed,\n item.alpc?.remainingInventory,\n item.alpc?.isLimited,\n item.alpc?.consumeType,\n item.alpc?.consumeCredits,\n isLogin,\n profile?.activated,\n creditInfo?.available_credit,\n item.variant?.availableForSale,\n ])\n\n const redeemButtonText = useMemo(() => {\n if (!isLogin) {\n return copy.unlockRewards\n }\n\n // \u7F3A\u8D27\u6587\u6848\n if (item.alpc?.consumeType === AlpcConsumeType.Product) {\n return item.variant?.availableForSale ? copy.btnRedeem : pageCommon?.soldOut || 'Sold Out'\n }\n return copy.btnRedeem\n }, [\n isLogin,\n item.alpc?.consumeType,\n item.variant?.availableForSale,\n copy.btnRedeem,\n copy.unlockRewards,\n pageCommon?.soldOut,\n ])\n\n // \u751F\u6210\u4EA7\u54C1 listing \u9875\u9762\u94FE\u63A5\n const productUrl = useMemo(() => {\n if (item.config?.type !== ConsumeType.Product || !item.product?.handle) {\n return undefined\n }\n const localePrefix = locale === 'us' ? '' : `/${locale}`\n return extractVariantId(item.variant?.id)\n ? `${localePrefix}/products/${item.product.handle}?variant=${extractVariantId(item.variant?.id)}${pageHandle ? `&ref=${pageHandle}` : ''}`\n : `${localePrefix}/products/${item.product.handle}${pageHandle ? `?ref=${pageHandle}` : ''}`\n }, [item.config?.type, item.product?.handle, item.variant?.id, pageHandle, locale])\n\n return (\n <div\n className={classNames(\n 'flex flex-col items-center rounded-[16px] bg-[#EAEAEC] p-[24px] md:rounded-[12px] md:px-[8px] xl:py-[16px] md-xl:px-[16px]',\n !rounded && 'rounded-none md:rounded-none',\n className\n )}\n >\n {item.config?.type === ConsumeType.Product ? (\n <a\n href={productUrl}\n className={classNames('relative mx-auto h-[224px] w-fit md:my-[10px] l:h-[120px] l-xxl:h-[138px]')}\n >\n <Picture\n className=\"h-full w-auto [&_img]:h-full [&_img]:object-contain\"\n source={item.config?.image?.url || item.product?.images?.[0]?.url}\n ></Picture>\n </a>\n ) : (\n <div className=\"relative mx-auto my-[30px] h-[164px] md:my-0 md:h-[66px] l-xxl:h-[138px] md-l:h-[80px]\">\n <Picture\n source={pageCommon?.imageMapping?.[item.config?.type]?.url}\n className=\"h-full [&_img]:h-full [&_img]:w-auto [&_img]:object-contain\"\n ></Picture>\n\n <NoneProductValue item={item} />\n </div>\n )}\n <div className={classNames('mt-[10px] xl:mt-[8px] flex w-full flex-1 flex-col justify-between')}>\n <Text\n html={item.config?.title || item.alpc?.title}\n title={item.config?.title || item.alpc?.title}\n size={2}\n className=\"line-clamp-2 h-[58px] text-[24px] leading-[1.2] l:h-[40px] l:text-[16px] l-xxl:h-[48px] l-xxl:text-[20px]\"\n />\n {item.config?.rules?.length > 0 && (\n <button\n type=\"button\"\n onClick={() => {\n onRulesOpen(item.config?.rules || [])\n gaTrack({\n event: 'ga4Event',\n event_name: 'lp_button',\n member_active_status: profile?.activated ? 'active' : 'not active',\n event_parameters: {\n page_group: pageGroup,\n position: copy.title,\n button_name: pageCommon?.ruleLabel,\n info: item.alpc?.id?.toString(),\n },\n })\n }}\n className=\"mt-[8px] w-fit text-[16px] font-bold underline md:text-[14px] l:mt-0\"\n tabIndex={0}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n }\n }}\n >\n {pageCommon?.ruleLabel}\n </button>\n )}\n <div>\n <div className=\"mt-[26px] flex items-center l:mt-[12px] l-xl:mt-[16px]\">\n <Picture\n className=\"size-[24px] l-xxl:size-[22px] md-l:size-[18px] md:size-[16px]\"\n source=\"https://cdn.shopify.com/s/files/1/0511/6346/3874/files/icon_hire_purchase.png?v=1757496783\"\n />\n <Text\n html={`${numberFormat(item.alpc?.consumeCredits)}`}\n size={2}\n as=\"p\"\n className=\"ml-[4px] text-[24px] font-bold mt-[4px] leading-none l-xxl:text-[20px] l:text-[16px] \"\n />\n </div>\n\n <Button\n disabled={isDisabled}\n variant=\"primary\"\n size=\"lg\"\n className=\"mt-[8px] md:px-[8px] l:w-full\"\n onClick={() => {\n onRedeem(item)\n gaTrack({\n event: 'ga4Event',\n event_name: 'lp_button',\n member_active_status: profile?.activated ? 'active' : 'not active',\n event_parameters: {\n page_group: pageGroup,\n position: copy.title,\n button_name: redeemButtonText,\n info: item.alpc?.id?.toString(),\n },\n })\n }}\n >\n {redeemButtonText}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "Button", "Text", "Picture", "useMemo", "classNames", "useCreditsContext", "AlpcConsumeType", "ConsumeType", "numberFormat", "extractVariantId", "gaTrack", "useHeadlessContext", "NoneProductValue", "ROUNDED_BRANDS", "RedeemableItem", "copy", "className", "item", "onRulesOpen", "onRedeem", "creditInfo", "profile", "pageGroup", "pageHandle", "pageCommon", "brand", "locale", "isLogin", "rounded", "isDisabled", "redeemButtonText", "productUrl", "localePrefix", "e"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anker-in/campaign-ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4-beta.01",
|
|
4
4
|
"description": "Campaign UI components and utilities for Anker projects",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -36,20 +36,6 @@
|
|
|
36
36
|
"**/*.css",
|
|
37
37
|
"**/**/*.css"
|
|
38
38
|
],
|
|
39
|
-
"scripts": {
|
|
40
|
-
"dev": "pnpm run dev:css & tsup --watch",
|
|
41
|
-
"dev:css": "postcss src/styles/global.css -o style.css --watch",
|
|
42
|
-
"build": "pnpm run build:css & pnpm run build:js:esm & pnpm run build:js:cjs & pnpm run build:js:esm:types & pnpm run build:js:cjs:types",
|
|
43
|
-
"build:js:cjs": "node esbuild-cjs.mjs",
|
|
44
|
-
"build:js:cjs:types": "tsc --outdir dist/cjs",
|
|
45
|
-
"build:js:esm": "node esbuild-esm.mjs",
|
|
46
|
-
"build:js:esm:types": "tsc --outdir dist/esm",
|
|
47
|
-
"build:css": "postcss src/styles/global.css -o style.css",
|
|
48
|
-
"lint": "eslint \"src/**/*.ts*\"",
|
|
49
|
-
"test": "echo run @anker-in/campaign-ui tests",
|
|
50
|
-
"type-check": "tsc --noEmit",
|
|
51
|
-
"clean": "rm -rf .turbo node_modules dist style.css"
|
|
52
|
-
},
|
|
53
39
|
"keywords": [],
|
|
54
40
|
"author": "",
|
|
55
41
|
"license": "ISC",
|
|
@@ -79,7 +65,6 @@
|
|
|
79
65
|
"crypto-js": "^4.1.1"
|
|
80
66
|
},
|
|
81
67
|
"dependencies": {
|
|
82
|
-
"@anker-in/lib": "workspace:*",
|
|
83
68
|
"@copilotkit/react-core": "1.1.2",
|
|
84
69
|
"@copilotkit/react-ui": "1.1.2",
|
|
85
70
|
"@copilotkit/runtime-client-gql": "1.1.2",
|
|
@@ -109,7 +94,8 @@
|
|
|
109
94
|
"remark-gfm": "^4.0.1",
|
|
110
95
|
"swiper": "^11.1.3",
|
|
111
96
|
"tailwind-merge": "^2.3.0",
|
|
112
|
-
"tailwindcss": "^3.4.3"
|
|
97
|
+
"tailwindcss": "^3.4.3",
|
|
98
|
+
"@anker-in/lib": "1.1.3"
|
|
113
99
|
},
|
|
114
100
|
"publishConfig": {
|
|
115
101
|
"access": "public",
|
|
@@ -117,5 +103,19 @@
|
|
|
117
103
|
},
|
|
118
104
|
"exclude": [
|
|
119
105
|
"dist/**/*"
|
|
120
|
-
]
|
|
121
|
-
|
|
106
|
+
],
|
|
107
|
+
"scripts": {
|
|
108
|
+
"dev": "pnpm run dev:css & tsup --watch",
|
|
109
|
+
"dev:css": "postcss src/styles/global.css -o style.css --watch",
|
|
110
|
+
"build": "pnpm run build:css & pnpm run build:js:esm & pnpm run build:js:cjs & pnpm run build:js:esm:types & pnpm run build:js:cjs:types",
|
|
111
|
+
"build:js:cjs": "node esbuild-cjs.mjs",
|
|
112
|
+
"build:js:cjs:types": "tsc --outdir dist/cjs",
|
|
113
|
+
"build:js:esm": "node esbuild-esm.mjs",
|
|
114
|
+
"build:js:esm:types": "tsc --outdir dist/esm",
|
|
115
|
+
"build:css": "postcss src/styles/global.css -o style.css",
|
|
116
|
+
"lint": "eslint \"src/**/*.ts*\"",
|
|
117
|
+
"test": "echo run @anker-in/campaign-ui tests",
|
|
118
|
+
"type-check": "tsc --noEmit",
|
|
119
|
+
"clean": "rm -rf .turbo node_modules dist style.css"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -111,6 +111,13 @@ function RedeemableItem({
|
|
|
111
111
|
}
|
|
112
112
|
}, [isLogin, itemData.productVariant?.availableForSale, copy.btnRedeem, copy.unlockRewards, copy?.soldOut])
|
|
113
113
|
|
|
114
|
+
const productUrl = useMemo(() => {
|
|
115
|
+
const localePrefix = locale === 'us' ? '' : `/${locale}`
|
|
116
|
+
return extractVariantId(itemData.productVariant?.id)
|
|
117
|
+
? `${localePrefix}/products/${itemData.product.handle}?variant=${extractVariantId(itemData.productVariant?.id)}${pageHandle ? `&ref=${pageHandle}` : ''}`
|
|
118
|
+
: `${localePrefix}/products/${itemData.product.handle}${pageHandle ? `?ref=${pageHandle}` : ''}`
|
|
119
|
+
}, [itemData.productVariant?.id, itemData.product.handle, pageHandle, locale])
|
|
120
|
+
|
|
114
121
|
return (
|
|
115
122
|
<div
|
|
116
123
|
className={cn(
|
|
@@ -133,13 +140,7 @@ function RedeemableItem({
|
|
|
133
140
|
)}
|
|
134
141
|
|
|
135
142
|
<a
|
|
136
|
-
href={
|
|
137
|
-
itemData.productHref ?? (
|
|
138
|
-
extractVariantId(itemData.productVariant?.id)
|
|
139
|
-
? `/products/${itemData.product.handle}?variant=${extractVariantId(itemData.productVariant?.id)}${pageHandle ? `&ref=${pageHandle}` : ''}`
|
|
140
|
-
: `/products/${itemData.product.handle}${pageHandle ? `?ref=${pageHandle}` : ''}`
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
+
href={productUrl}
|
|
143
144
|
className={cn('relative mx-auto h-[196px] w-fit md:h-[120px] md-xxl:h-[138px]')}
|
|
144
145
|
>
|
|
145
146
|
<Picture
|