@anker-in/campaign-ui 0.4.4 → 0.4.5-beta.10

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.
@@ -1,2 +1,2 @@
1
- "use strict";var f=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var L=(s,n)=>{for(var l in n)f(s,l,{get:n[l],enumerable:!0})},E=(s,n,l,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let d of A(n))!S.call(s,d)&&d!==l&&f(s,d,{get:()=>n[d],enumerable:!(i=M(n,d))||i.enumerable});return s};var U=s=>E(f({},"__esModule",{value:!0}),s);var $={};L($,{ProductComparison:()=>h,ProductComparisonRenderer:()=>O});module.exports=U($);var t=require("react/jsx-runtime"),D=require("react"),g=require("../../constants");const m=(s,n="USD")=>`${g.CURRENCY_SYMBOLS[n]||n}${s}`,h=({data:s,onAddToCart:n,commonText:l})=>{const{products:i,dimensions:d}=s,N={...g.DEFAULT_COMMON_TEXT,...l},p=i?.filter(e=>e&&e.shopifyId)||[],x=2,k=p.slice(0,x),[C,P]=(0,D.useState)(k);if(p.length===0)return null;const w=(e,r)=>{const o=p.find(a=>a.shopifyId===r);if(o){const a=[...C];a[e]=o,P(a)}},b=C.slice(0,x),v=(e,r)=>!e||!e.values||!Array.isArray(e.values)?null:e.values.find(o=>o&&o.product_id===r),F=(e,r)=>r?(0,t.jsxs)("div",{className:"border-b border-[#DADCE0] pb-2",children:[(0,t.jsx)("div",{className:"mb-1",children:(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:e==="price"?"has member price":e})}),(0,t.jsx)("div",{className:"flex gap-4",style:{gap:"36px"},children:b.map((o,a)=>{if(!o||!o.shopifyId)return null;const u=v(r,o.shopifyId);return(0,t.jsx)("div",{className:"flex-1",children:R(u,r.label)},`comparison-${a}`)})})]}):null,R=(e,r)=>{if(!e)return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:"-"});if(r.toLowerCase().includes("price")){const o=e?.has_member_price,a=e?.available?e.min===e.max?m(e.min,e.currency):`${m(e.min,e.currency)} - ${m(e.max,e.currency)}`:"-";return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:o?"Yes":"No"})}if(r.toLowerCase().includes("variant"))return(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:[e.count||0," ",e.count===1?"variant":"variants"]});if(r.toLowerCase().includes("review")){const o=e.rating||0,a=e.count||0;return(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:["\u2B50 ",o.toFixed(1)]}),(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:["(",a,")"]})]})}return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:e.display||e.value||"-"})};return(0,t.jsxs)("div",{className:"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]",children:[(0,t.jsx)("div",{className:"flex p-4",style:{gap:"36px",paddingBottom:"0px"},children:b.map((e,r)=>{if(!e||!e.shopifyId)return null;const o=d.price?v(d.price,e.shopifyId):null,a=e.variants?.[0],u=a?.discount?.has_discount,y=u?a?.discount?.discount_price:null,T=y||o?.min||e.price.amount,_=e.price.amount,I=c=>{c.preventDefault(),c.stopPropagation(),n&&n(e)};return(0,t.jsxs)("div",{className:"flex flex-1 flex-col items-center",children:[(0,t.jsx)("div",{className:"mb-4 w-full",children:(0,t.jsx)("select",{value:e.shopifyId,onChange:c=>w(r,c.target.value),className:"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",style:{appearance:"none",backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")`,backgroundRepeat:"no-repeat",backgroundPosition:"right 12px center",paddingRight:"32px"},children:p.map(c=>(0,t.jsx)("option",{value:c.shopifyId,children:c.title.length>30?`${c.title.slice(0,30)}...`:c.title},c.shopifyId))})}),(0,t.jsx)("a",{href:e.productUrl,target:"_blank",rel:"noopener noreferrer",className:"mb-4 block w-full max-w-[160px]",children:(0,t.jsx)("div",{className:"aspect-square w-full overflow-hidden rounded-lg",children:e.imageUrl?(0,t.jsx)("img",{src:e.imageUrl,alt:e.title,className:"size-full object-contain",loading:"lazy"}):(0,t.jsx)("div",{className:"flex size-full items-center justify-center text-gray-400",children:(0,t.jsx)("svg",{className:"size-12",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})})})})}),(0,t.jsx)("div",{className:"mb-4 flex flex-col items-center gap-1",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]",children:m(T,o?.currency||e.price.currency)}),u&&y&&(0,t.jsx)("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through",children:m(_,e.price.currency)})]})}),n&&(0,t.jsx)("button",{type:"button",onClick:I,className:"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white",style:{backgroundColor:"#1D1D1F"},children:N.addToCart})]},`product-column-${r}`)})}),(0,t.jsx)("div",{className:"flex flex-col gap-4 p-4",children:Object.entries(d).map(([e,r])=>r?(0,t.jsx)("div",{children:F(r.label,r)},e):null)})]})},O={render:(s,n,l)=>{if(s.type!=="product_comparison"||!s.data)return null;const i=s.data;return i.productComparisonRender?(0,t.jsx)(t.Fragment,{children:i.productComparisonRender(i)}):(0,t.jsx)(h,{data:i,isUser:n,isSystem:l,onAddToCart:i.onAddToCart,commonText:i.commonText})}};
1
+ "use strict";var f=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var L=(s,n)=>{for(var l in n)f(s,l,{get:n[l],enumerable:!0})},E=(s,n,l,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let d of A(n))!S.call(s,d)&&d!==l&&f(s,d,{get:()=>n[d],enumerable:!(i=M(n,d))||i.enumerable});return s};var U=s=>E(f({},"__esModule",{value:!0}),s);var $={};L($,{ProductComparison:()=>h,ProductComparisonRenderer:()=>O});module.exports=U($);var t=require("react/jsx-runtime"),D=require("react"),g=require("../../constants");const m=(s,n="USD")=>`${g.CURRENCY_SYMBOLS[n]||n}${s}`,h=({data:s,onAddToCart:n,commonText:l})=>{const{products:i,dimensions:d}=s,N={...g.DEFAULT_COMMON_TEXT,...l},p=i?.filter(e=>e&&e.shopifyId)||[],x=2,k=p.slice(0,x),[C,P]=(0,D.useState)(k);if(p.length===0)return null;const w=(e,r)=>{const o=p.find(a=>a.shopifyId===r);if(o){const a=[...C];a[e]=o,P(a)}},b=C.slice(0,x),y=(e,r)=>!e||!e.values||!Array.isArray(e.values)?null:e.values.find(o=>o&&o.product_id===r),F=(e,r)=>r?(0,t.jsxs)("div",{className:"border-b border-[#DADCE0] pb-2",children:[(0,t.jsx)("div",{className:"mb-1",children:(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:e==="price"?"has member price":e})}),(0,t.jsx)("div",{className:"flex gap-4",style:{gap:"36px"},children:b.map((o,a)=>{if(!o||!o.shopifyId)return null;const u=y(r,o.shopifyId);return(0,t.jsx)("div",{className:"flex-1",children:R(u,r.label)},`comparison-${a}`)})})]}):null,R=(e,r)=>{if(!e)return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:"-"});if(r.toLowerCase().includes("price")){const o=e?.has_member_price,a=e?.available?e.min===e.max?m(e.min,e.currency):`${m(e.min,e.currency)} - ${m(e.max,e.currency)}`:"-";return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:o?"Yes":"No"})}if(r.toLowerCase().includes("variant"))return(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:[e.count||0," ",e.count===1?"variant":"variants"]});if(r.toLowerCase().includes("review")){const o=e.rating||0,a=e.count||0;return(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:["\u2B50 ",o.toFixed(1)]}),(0,t.jsxs)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:["(",a,")"]})]})}return(0,t.jsx)("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:e.display||e.value||"-"})};return(0,t.jsxs)("div",{className:"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]",children:[(0,t.jsx)("div",{className:"flex p-4",style:{gap:"36px",paddingBottom:"0px"},children:b.map((e,r)=>{if(!e||!e.shopifyId)return null;const o=d.price?y(d.price,e.shopifyId):null,a=e.variants?.[0],u=a?.discount?.has_discount,v=u?a?.discount?.discount_price:null,T=v||o?.min||e.price.amount,_=e.price.amount,I=c=>{c.preventDefault(),c.stopPropagation(),n&&n(e)};return(0,t.jsxs)("div",{className:"flex flex-1 flex-col items-center",children:[(0,t.jsx)("div",{className:"mb-4 w-full",children:(0,t.jsx)("select",{value:e.shopifyId,onChange:c=>w(r,c.target.value),className:"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",style:{appearance:"none",backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")`,backgroundRepeat:"no-repeat",backgroundPosition:"right 12px center",paddingRight:"32px"},children:p.map(c=>(0,t.jsx)("option",{value:c.shopifyId,children:c.title.length>30?`${c.title.slice(0,30)}...`:c.title},c.shopifyId))})}),(0,t.jsx)("a",{href:e.productUrl,target:"_blank",rel:"noopener noreferrer",className:"mb-4 block w-full max-w-[160px]",children:(0,t.jsx)("div",{className:"aspect-square w-full overflow-hidden rounded-lg",children:e.imageUrl?(0,t.jsx)("img",{src:e.imageUrl,alt:e.title,className:"size-full object-contain",loading:"lazy"}):(0,t.jsx)("div",{className:"flex size-full items-center justify-center text-gray-400",children:(0,t.jsx)("svg",{className:"size-12",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})})})})}),(0,t.jsx)("div",{className:"mb-4 flex flex-col items-center gap-1",children:(0,t.jsxs)("div",{className:"flex items-center gap-2 justify-center flex-wrap",children:[(0,t.jsx)("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]",children:m(T,o?.currency||e.price.currency)}),u&&v&&(0,t.jsx)("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through",children:m(_,e.price.currency)})]})}),n&&(0,t.jsx)("button",{type:"button",onClick:I,className:"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white",style:{backgroundColor:"#1D1D1F"},children:N.addToCart})]},`product-column-${r}`)})}),(0,t.jsx)("div",{className:"flex flex-col gap-4 p-4",children:Object.entries(d).map(([e,r])=>r?(0,t.jsx)("div",{children:F(r.label,r)},e):null)})]})},O={render:(s,n,l)=>{if(s.type!=="product_comparison"||!s.data)return null;const i=s.data;return i.productComparisonRender?(0,t.jsx)(t.Fragment,{children:i.productComparisonRender(i)}):(0,t.jsx)(h,{data:i,isUser:n,isSystem:l,onAddToCart:i.onAddToCart,commonText:i.commonText})}};
2
2
  //# sourceMappingURL=ProductComparison.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/ProductComparison.tsx"],
4
- "sourcesContent": ["/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n * \u663E\u793A\u591A\u4E2A\u4EA7\u54C1\u7684\u5BF9\u6BD4\u4FE1\u606F\uFF0C\u91C7\u7528\u8868\u683C\u5E03\u5C40\u5C55\u793A\u5404\u7EF4\u5EA6\u5DEE\u5F02\n * \u57FA\u4E8E\u53C2\u8003\u8BBE\u8BA1\uFF1A\u9876\u90E8\u4EA7\u54C1\u5C55\u793A + \u5E95\u90E8\u5BF9\u6BD4\u8868\u683C\n */\n\nimport React, { useState } from 'react'\nimport type { Product, MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT, CURRENCY_SYMBOLS } from '../../constants'\n\n/**\n * \u5BF9\u6BD4\u7EF4\u5EA6\u6570\u636E\u7ED3\u6784\n */\ninterface ComparisonDimension {\n label: string\n values: Array<{\n product_id: string\n [key: string]: any\n }>\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\n */\nexport interface ProductComparisonData {\n products: Product[]\n dimensions: {\n price?: ComparisonDimension\n variants?: ComparisonDimension\n member_price?: ComparisonDimension\n discount?: ComparisonDimension\n reviews?: ComparisonDimension\n [key: string]: ComparisonDimension | undefined\n }\n commonText?: CommonText\n productComparisonRender?: (data: ProductComparisonData) => React.ReactNode\n}\n\nexport interface ProductComparisonProps {\n /**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\n */\n data: ProductComparisonData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n\n /**\n * \u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: Product) => void\n\n /**\n * \u901A\u7528\u6587\u6848\u914D\u7F6E\n */\n commonText?: CommonText\n}\n\n/**\n * \u683C\u5F0F\u5316\u4EF7\u683C\u663E\u793A\n */\nconst formatPrice = (amount: number, currency: string = 'USD'): string => {\n const symbol = CURRENCY_SYMBOLS[currency] || currency\n return `${symbol}${amount}`\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 [\u4EA7\u54C11\u56FE\u7247] [\u4EA7\u54C12\u56FE\u7247] \u2502\n * \u2502 \u4EF7\u683C1 \u4EF7\u683C2 \u2502\n * \u2502 \u989C\u8272\u9009\u9879 \u989C\u8272\u9009\u9879 \u2502\n * \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n * \u2502 \u7EF4\u5EA61 \u2502 \u503C1-1 \u2502 \u503C1-2 \u2502\n * \u2502 \u7EF4\u5EA62 \u2502 \u503C2-1 \u2502 \u503C2-2 \u2502\n * \u2502 \u7EF4\u5EA63 \u2502 \u503C3-1 \u2502 \u503C3-2 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n */\nexport const ProductComparison: React.FC<ProductComparisonProps> = ({ data, onAddToCart, commonText }) => {\n const { products: rawProducts, dimensions } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n // \u8FC7\u6EE4\u6389 null \u6216\u65E0\u6548\u7684\u4EA7\u54C1\n const allProducts = rawProducts?.filter(p => p && p.shopifyId) || []\n\n // \u5BF9\u6BD4\u5217\u6570\uFF08\u56FA\u5B9A\u4E3A2\u5217\uFF09\n const COMPARISON_COLUMNS = 2\n\n // \u521D\u59CB\u5316\u6BCF\u4E2A\u5BF9\u6BD4\u4F4D\u7F6E\u7684\u9009\u4E2D\u4EA7\u54C1\uFF08\u9ED8\u8BA4\u53D6\u524D\u4E24\u4E2A\u4EA7\u54C1\uFF09\n const initialSelectedProducts = allProducts.slice(0, COMPARISON_COLUMNS)\n const [selectedProducts, setSelectedProducts] = useState<Product[]>(initialSelectedProducts)\n\n // Early return \u5FC5\u987B\u5728\u6240\u6709 hooks \u4E4B\u540E\n if (allProducts.length === 0) {\n return null\n }\n\n // \u5904\u7406\u4EA7\u54C1\u9009\u62E9\u53D8\u66F4\n const handleProductChange = (index: number, productId: string) => {\n const newProduct = allProducts.find(p => p.shopifyId === productId)\n if (newProduct) {\n const newSelectedProducts = [...selectedProducts]\n newSelectedProducts[index] = newProduct\n setSelectedProducts(newSelectedProducts)\n }\n }\n\n // \u5F53\u524D\u663E\u793A\u7684\u4EA7\u54C1\uFF08\u786E\u4FDD\u53EA\u663E\u793A\u6307\u5B9A\u5217\u6570\uFF09\n const products = selectedProducts.slice(0, COMPARISON_COLUMNS)\n\n /**\n * \u83B7\u53D6\u6307\u5B9A\u4EA7\u54C1\u5728\u67D0\u4E2A\u7EF4\u5EA6\u7684\u503C\n */\n const getDimensionValue = (dimension: ComparisonDimension, productId: string): any => {\n if (!dimension || !dimension.values || !Array.isArray(dimension.values)) {\n return null\n }\n return dimension.values.find(v => v && v.product_id === productId)\n }\n\n /**\n * \u6E32\u67D3\u901A\u7528\u5BF9\u6BD4\u884C\n */\n const renderComparisonRow = (label: string, dimension: ComparisonDimension | undefined) => {\n if (!dimension) return null\n\n return (\n <div className=\"border-b border-[#DADCE0] pb-2\">\n {/* \u7EF4\u5EA6\u6807\u7B7E\uFF08\u6807\u9898\uFF09 */}\n <div className=\"mb-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">{label==='price'?'has member price':label}</span>\n </div>\n\n {/* \u4EA7\u54C1\u503C\u5217\u8868\uFF08\u6A2A\u5411\u6392\u5217\uFF09 */}\n <div className=\"flex gap-4\" style={{ gap: '36px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n const value = getDimensionValue(dimension, product.shopifyId)\n\n return (\n <div key={`comparison-${index}`} className=\"flex-1\">\n {renderDimensionValue(value, dimension.label)}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n\n /**\n * \u6E32\u67D3\u7EF4\u5EA6\u503C\n */\n const renderDimensionValue = (value: any, dimensionLabel: string) => {\n if (!value) {\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">-</span>\n }\n\n // \u6839\u636E\u4E0D\u540C\u7EF4\u5EA6\u7C7B\u578B\u6E32\u67D3\u4E0D\u540C\u683C\u5F0F\n if (dimensionLabel.toLowerCase().includes('price')) {\n const hasMemberPrice = value?.has_member_price\n // \u4EF7\u683C\u7EF4\u5EA6\n const priceDisplay = value?.available?\n value.min === value.max\n ? formatPrice(value.min, value.currency)\n : `${formatPrice(value.min, value.currency)} - ${formatPrice(value.max, value.currency)}`:'-'\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">{hasMemberPrice?'Yes':'No'}</span>\n }\n\n if (dimensionLabel.toLowerCase().includes('variant')) {\n // \u53D8\u4F53\u6570\u91CF\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.count || 0} {value.count === 1 ? 'variant' : 'variants'}\n </span>\n )\n }\n\n if (dimensionLabel.toLowerCase().includes('review')) {\n // \u8BC4\u8BBA\u7EF4\u5EA6\uFF1A\u663E\u793A\u8BC4\u5206\u548C\u6570\u91CF\n const rating = value.rating || 0\n const count = value.count || 0\n return (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n \u2B50 {rating.toFixed(1)}\n </span>\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">\n ({count})\n </span>\n </div>\n )\n }\n\n // \u9ED8\u8BA4\u663E\u793A\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.display || value.value || '-'}\n </span>\n )\n }\n\n return (\n <div className=\"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* \u9876\u90E8\u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <div className=\"flex p-4\" style={{ gap: '36px', paddingBottom: '0px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n\n // \u83B7\u53D6\u4EF7\u683C\u4FE1\u606F\n const priceInfo = dimensions.price ? getDimensionValue(dimensions.price, product.shopifyId) : null\n\n // \u83B7\u53D6\u6298\u6263\u4FE1\u606F\n const firstVariant = product.variants?.[0]\n const hasDiscount = firstVariant?.discount?.has_discount\n const discountPrice = hasDiscount ? firstVariant?.discount?.discount_price : null\n\n // \u5F53\u524D\u663E\u793A\u4EF7\u683C\uFF1A\u6709\u6298\u6263\u65F6\u663E\u793A\u6298\u6263\u4EF7\uFF0C\u5426\u5219\u663E\u793A\u539F\u4EF7\n const currentPrice = discountPrice || priceInfo?.min || product.price.amount\n const originalPrice = product.price.amount\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB\u5904\u7406\n const handleAddToCart = (e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (onAddToCart) {\n onAddToCart(product)\n }\n }\n\n return (\n <div key={`product-column-${index}`} className=\"flex flex-1 flex-col items-center\">\n {/* \u4EA7\u54C1\u9009\u62E9\u4E0B\u62C9\u6846 */}\n <div className=\"mb-4 w-full\">\n <select\n value={product.shopifyId}\n onChange={e => handleProductChange(index, e.target.value)}\n className=\"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\"\n style={{\n appearance: 'none',\n backgroundImage:\n \"url(\\\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\")\",\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'right 12px center',\n paddingRight: '32px',\n }}\n >\n {allProducts.map(p => (\n <option key={p.shopifyId} value={p.shopifyId}>\n {p.title.length > 30 ? `${p.title.slice(0, 30)}...` : p.title}\n </option>\n ))}\n </select>\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <a\n href={product.productUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mb-4 block w-full max-w-[160px]\"\n >\n <div className=\"aspect-square w-full overflow-hidden rounded-lg\">\n {product.imageUrl ? (\n <img\n src={product.imageUrl}\n alt={product.title}\n className=\"size-full object-contain\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-gray-400\">\n <svg className=\"size-12\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n )}\n </div>\n </a>\n\n {/* \u4EF7\u683C\u5C55\u793A\uFF08\u5E26\u5212\u7EBF\u4EF7\uFF09 */}\n <div className=\"mb-4 flex flex-col items-center gap-1\">\n <div className=\"flex items-center gap-2\">\n {/* \u5F53\u524D\u4EF7\u683C\uFF08\u6298\u6263\u4EF7\u6216\u539F\u4EF7\uFF09 */}\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]\">\n {formatPrice(currentPrice, priceInfo?.currency || product.price.currency)}\n </span>\n {/* \u5212\u7EBF\u4EF7 - \u4EC5\u5728\u6709\u6298\u6263\u65F6\u663E\u793A */}\n {hasDiscount && discountPrice && (\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through\">\n {formatPrice(originalPrice, product.price.currency)}\n </span>\n )}\n </div>\n </div>\n\n {/* Add to Cart \u6309\u94AE */}\n {onAddToCart && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n className=\"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white\"\n style={{ backgroundColor: '#1D1D1F' }}\n >\n {mergedText.addToCart}\n </button>\n )}\n\n </div>\n )\n })}\n </div>\n\n {/* \u5BF9\u6BD4\u8868\u683C\u533A\u57DF */}\n <div className=\"flex flex-col gap-4 p-4\">\n {/* \u904D\u5386\u6240\u6709\u7EF4\u5EA6\u5E76\u6E32\u67D3 */}\n {Object.entries(dimensions).map(([key, dimension]) => {\n if (!dimension) return null // price \u5DF2\u5728\u9876\u90E8\u663E\u793A\n return <div key={key}>{renderComparisonRow(dimension.label, dimension)}</div>\n })}\n </div>\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4EA7\u54C1\u5BF9\u6BD4\u6E32\u67D3\u5668\n */\nexport const ProductComparisonRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'product_comparison' || !content.data) {\n return null\n }\n\n const comparisonData = content.data as ProductComparisonData & { onAddToCart?: (product: Product) => void }\n\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u6E32\u67D3\u51FD\u6570\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\n if (comparisonData.productComparisonRender) {\n return <>{comparisonData.productComparisonRender(comparisonData)}</>\n }\n\n return (\n <ProductComparison\n data={comparisonData}\n isUser={isUser}\n isSystem={isSystem}\n onAddToCart={comparisonData.onAddToCart}\n commonText={comparisonData.commonText}\n />\n )\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n * \u663E\u793A\u591A\u4E2A\u4EA7\u54C1\u7684\u5BF9\u6BD4\u4FE1\u606F\uFF0C\u91C7\u7528\u8868\u683C\u5E03\u5C40\u5C55\u793A\u5404\u7EF4\u5EA6\u5DEE\u5F02\n * \u57FA\u4E8E\u53C2\u8003\u8BBE\u8BA1\uFF1A\u9876\u90E8\u4EA7\u54C1\u5C55\u793A + \u5E95\u90E8\u5BF9\u6BD4\u8868\u683C\n */\n\nimport React, { useState } from 'react'\nimport type { Product, MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT, CURRENCY_SYMBOLS } from '../../constants'\n\n/**\n * \u5BF9\u6BD4\u7EF4\u5EA6\u6570\u636E\u7ED3\u6784\n */\ninterface ComparisonDimension {\n label: string\n values: Array<{\n product_id: string\n [key: string]: any\n }>\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\n */\nexport interface ProductComparisonData {\n products: Product[]\n dimensions: {\n price?: ComparisonDimension\n variants?: ComparisonDimension\n member_price?: ComparisonDimension\n discount?: ComparisonDimension\n reviews?: ComparisonDimension\n [key: string]: ComparisonDimension | undefined\n }\n commonText?: CommonText\n productComparisonRender?: (data: ProductComparisonData) => React.ReactNode\n}\n\nexport interface ProductComparisonProps {\n /**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\n */\n data: ProductComparisonData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n\n /**\n * \u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: Product) => void\n\n /**\n * \u901A\u7528\u6587\u6848\u914D\u7F6E\n */\n commonText?: CommonText\n}\n\n/**\n * \u683C\u5F0F\u5316\u4EF7\u683C\u663E\u793A\n */\nconst formatPrice = (amount: number, currency: string = 'USD'): string => {\n const symbol = CURRENCY_SYMBOLS[currency] || currency\n return `${symbol}${amount}`\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 [\u4EA7\u54C11\u56FE\u7247] [\u4EA7\u54C12\u56FE\u7247] \u2502\n * \u2502 \u4EF7\u683C1 \u4EF7\u683C2 \u2502\n * \u2502 \u989C\u8272\u9009\u9879 \u989C\u8272\u9009\u9879 \u2502\n * \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n * \u2502 \u7EF4\u5EA61 \u2502 \u503C1-1 \u2502 \u503C1-2 \u2502\n * \u2502 \u7EF4\u5EA62 \u2502 \u503C2-1 \u2502 \u503C2-2 \u2502\n * \u2502 \u7EF4\u5EA63 \u2502 \u503C3-1 \u2502 \u503C3-2 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n */\nexport const ProductComparison: React.FC<ProductComparisonProps> = ({ data, onAddToCart, commonText }) => {\n const { products: rawProducts, dimensions } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n // \u8FC7\u6EE4\u6389 null \u6216\u65E0\u6548\u7684\u4EA7\u54C1\n const allProducts = rawProducts?.filter(p => p && p.shopifyId) || []\n\n // \u5BF9\u6BD4\u5217\u6570\uFF08\u56FA\u5B9A\u4E3A2\u5217\uFF09\n const COMPARISON_COLUMNS = 2\n\n // \u521D\u59CB\u5316\u6BCF\u4E2A\u5BF9\u6BD4\u4F4D\u7F6E\u7684\u9009\u4E2D\u4EA7\u54C1\uFF08\u9ED8\u8BA4\u53D6\u524D\u4E24\u4E2A\u4EA7\u54C1\uFF09\n const initialSelectedProducts = allProducts.slice(0, COMPARISON_COLUMNS)\n const [selectedProducts, setSelectedProducts] = useState<Product[]>(initialSelectedProducts)\n\n // Early return \u5FC5\u987B\u5728\u6240\u6709 hooks \u4E4B\u540E\n if (allProducts.length === 0) {\n return null\n }\n\n // \u5904\u7406\u4EA7\u54C1\u9009\u62E9\u53D8\u66F4\n const handleProductChange = (index: number, productId: string) => {\n const newProduct = allProducts.find(p => p.shopifyId === productId)\n if (newProduct) {\n const newSelectedProducts = [...selectedProducts]\n newSelectedProducts[index] = newProduct\n setSelectedProducts(newSelectedProducts)\n }\n }\n\n // \u5F53\u524D\u663E\u793A\u7684\u4EA7\u54C1\uFF08\u786E\u4FDD\u53EA\u663E\u793A\u6307\u5B9A\u5217\u6570\uFF09\n const products = selectedProducts.slice(0, COMPARISON_COLUMNS)\n\n /**\n * \u83B7\u53D6\u6307\u5B9A\u4EA7\u54C1\u5728\u67D0\u4E2A\u7EF4\u5EA6\u7684\u503C\n */\n const getDimensionValue = (dimension: ComparisonDimension, productId: string): any => {\n if (!dimension || !dimension.values || !Array.isArray(dimension.values)) {\n return null\n }\n return dimension.values.find(v => v && v.product_id === productId)\n }\n\n /**\n * \u6E32\u67D3\u901A\u7528\u5BF9\u6BD4\u884C\n */\n const renderComparisonRow = (label: string, dimension: ComparisonDimension | undefined) => {\n if (!dimension) return null\n\n return (\n <div className=\"border-b border-[#DADCE0] pb-2\">\n {/* \u7EF4\u5EA6\u6807\u7B7E\uFF08\u6807\u9898\uFF09 */}\n <div className=\"mb-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">{label==='price'?'has member price':label}</span>\n </div>\n\n {/* \u4EA7\u54C1\u503C\u5217\u8868\uFF08\u6A2A\u5411\u6392\u5217\uFF09 */}\n <div className=\"flex gap-4\" style={{ gap: '36px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n const value = getDimensionValue(dimension, product.shopifyId)\n\n return (\n <div key={`comparison-${index}`} className=\"flex-1\">\n {renderDimensionValue(value, dimension.label)}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n\n /**\n * \u6E32\u67D3\u7EF4\u5EA6\u503C\n */\n const renderDimensionValue = (value: any, dimensionLabel: string) => {\n if (!value) {\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">-</span>\n }\n\n // \u6839\u636E\u4E0D\u540C\u7EF4\u5EA6\u7C7B\u578B\u6E32\u67D3\u4E0D\u540C\u683C\u5F0F\n if (dimensionLabel.toLowerCase().includes('price')) {\n const hasMemberPrice = value?.has_member_price\n // \u4EF7\u683C\u7EF4\u5EA6\n const priceDisplay = value?.available?\n value.min === value.max\n ? formatPrice(value.min, value.currency)\n : `${formatPrice(value.min, value.currency)} - ${formatPrice(value.max, value.currency)}`:'-'\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">{hasMemberPrice?'Yes':'No'}</span>\n }\n\n if (dimensionLabel.toLowerCase().includes('variant')) {\n // \u53D8\u4F53\u6570\u91CF\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.count || 0} {value.count === 1 ? 'variant' : 'variants'}\n </span>\n )\n }\n\n if (dimensionLabel.toLowerCase().includes('review')) {\n // \u8BC4\u8BBA\u7EF4\u5EA6\uFF1A\u663E\u793A\u8BC4\u5206\u548C\u6570\u91CF\n const rating = value.rating || 0\n const count = value.count || 0\n return (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n \u2B50 {rating.toFixed(1)}\n </span>\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">\n ({count})\n </span>\n </div>\n )\n }\n\n // \u9ED8\u8BA4\u663E\u793A\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.display || value.value || '-'}\n </span>\n )\n }\n\n return (\n <div className=\"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* \u9876\u90E8\u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <div className=\"flex p-4\" style={{ gap: '36px', paddingBottom: '0px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n\n // \u83B7\u53D6\u4EF7\u683C\u4FE1\u606F\n const priceInfo = dimensions.price ? getDimensionValue(dimensions.price, product.shopifyId) : null\n\n // \u83B7\u53D6\u6298\u6263\u4FE1\u606F\n const firstVariant = product.variants?.[0]\n const hasDiscount = firstVariant?.discount?.has_discount\n const discountPrice = hasDiscount ? firstVariant?.discount?.discount_price : null\n\n // \u5F53\u524D\u663E\u793A\u4EF7\u683C\uFF1A\u6709\u6298\u6263\u65F6\u663E\u793A\u6298\u6263\u4EF7\uFF0C\u5426\u5219\u663E\u793A\u539F\u4EF7\n const currentPrice = discountPrice || priceInfo?.min || product.price.amount\n const originalPrice = product.price.amount\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB\u5904\u7406\n const handleAddToCart = (e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (onAddToCart) {\n onAddToCart(product)\n }\n }\n\n return (\n <div key={`product-column-${index}`} className=\"flex flex-1 flex-col items-center\">\n {/* \u4EA7\u54C1\u9009\u62E9\u4E0B\u62C9\u6846 */}\n <div className=\"mb-4 w-full\">\n <select\n value={product.shopifyId}\n onChange={e => handleProductChange(index, e.target.value)}\n className=\"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\"\n style={{\n appearance: 'none',\n backgroundImage:\n \"url(\\\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\")\",\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'right 12px center',\n paddingRight: '32px',\n }}\n >\n {allProducts.map(p => (\n <option key={p.shopifyId} value={p.shopifyId}>\n {p.title.length > 30 ? `${p.title.slice(0, 30)}...` : p.title}\n </option>\n ))}\n </select>\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <a\n href={product.productUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mb-4 block w-full max-w-[160px]\"\n >\n <div className=\"aspect-square w-full overflow-hidden rounded-lg\">\n {product.imageUrl ? (\n <img\n src={product.imageUrl}\n alt={product.title}\n className=\"size-full object-contain\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-gray-400\">\n <svg className=\"size-12\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n )}\n </div>\n </a>\n\n {/* \u4EF7\u683C\u5C55\u793A\uFF08\u5E26\u5212\u7EBF\u4EF7\uFF09 */}\n <div className=\"mb-4 flex flex-col items-center gap-1\">\n <div className=\"flex items-center gap-2 justify-center flex-wrap\">\n {/* \u5F53\u524D\u4EF7\u683C\uFF08\u6298\u6263\u4EF7\u6216\u539F\u4EF7\uFF09 */}\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]\">\n {formatPrice(currentPrice, priceInfo?.currency || product.price.currency)}\n </span>\n {/* \u5212\u7EBF\u4EF7 - \u4EC5\u5728\u6709\u6298\u6263\u65F6\u663E\u793A */}\n {hasDiscount && discountPrice && (\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through\">\n {formatPrice(originalPrice, product.price.currency)}\n </span>\n )}\n </div>\n </div>\n\n {/* Add to Cart \u6309\u94AE */}\n {onAddToCart && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n className=\"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white\"\n style={{ backgroundColor: '#1D1D1F' }}\n >\n {mergedText.addToCart}\n </button>\n )}\n\n </div>\n )\n })}\n </div>\n\n {/* \u5BF9\u6BD4\u8868\u683C\u533A\u57DF */}\n <div className=\"flex flex-col gap-4 p-4\">\n {/* \u904D\u5386\u6240\u6709\u7EF4\u5EA6\u5E76\u6E32\u67D3 */}\n {Object.entries(dimensions).map(([key, dimension]) => {\n if (!dimension) return null // price \u5DF2\u5728\u9876\u90E8\u663E\u793A\n return <div key={key}>{renderComparisonRow(dimension.label, dimension)}</div>\n })}\n </div>\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4EA7\u54C1\u5BF9\u6BD4\u6E32\u67D3\u5668\n */\nexport const ProductComparisonRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'product_comparison' || !content.data) {\n return null\n }\n\n const comparisonData = content.data as ProductComparisonData & { onAddToCart?: (product: Product) => void }\n\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u6E32\u67D3\u51FD\u6570\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\n if (comparisonData.productComparisonRender) {\n return <>{comparisonData.productComparisonRender(comparisonData)}</>\n }\n\n return (\n <ProductComparison\n data={comparisonData}\n isUser={isUser}\n isSystem={isSystem}\n onAddToCart={comparisonData.onAddToCart}\n commonText={comparisonData.commonText}\n />\n )\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["ProductComparison_exports", "__export", "ProductComparison", "ProductComparisonRenderer", "__toCommonJS", "import_jsx_runtime", "import_react", "import_constants", "formatPrice", "amount", "currency", "data", "onAddToCart", "commonText", "rawProducts", "dimensions", "mergedText", "allProducts", "p", "COMPARISON_COLUMNS", "initialSelectedProducts", "selectedProducts", "setSelectedProducts", "handleProductChange", "index", "productId", "newProduct", "newSelectedProducts", "products", "getDimensionValue", "dimension", "v", "renderComparisonRow", "label", "product", "value", "renderDimensionValue", "dimensionLabel", "hasMemberPrice", "priceDisplay", "rating", "count", "priceInfo", "firstVariant", "hasDiscount", "discountPrice", "currentPrice", "originalPrice", "handleAddToCart", "e", "key", "content", "isUser", "isSystem", "comparisonData"]
7
7
  }
@@ -1,5 +1,5 @@
1
- export { default as Chat } from './chat/index';
2
- export { Role, ActionExecutionMessage, TextMessage, useCopilotChat, useCopilotAction, useCopilotReadable, } from './chat/utils';
1
+ export { default as Chat } from './chat/index.js';
2
+ export { Role, ActionExecutionMessage, TextMessage, useCopilotChat, useCopilotAction, useCopilotReadable, } from './chat/utils.js';
3
3
  export * from './credits/index.js';
4
4
  export * from './registration/index.js';
5
5
  export { LiveChatWidget } from './LiveChatWidget/index.js';
@@ -1,2 +1,2 @@
1
- "use strict";var l=Object.create;var C=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty;var f=(e,t)=>{for(var s in t)C(e,s,{get:t[s],enumerable:!0})},i=(e,t,s,p)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of x(t))!c.call(e,r)&&r!==s&&C(e,r,{get:()=>t[r],enumerable:!(p=u(t,r))||p.enumerable});return e},a=(e,t,s)=>(i(e,t,"default"),s&&i(s,t,"default")),h=(e,t,s)=>(s=e!=null?l(M(e)):{},i(t||!e||!e.__esModule?C(s,"default",{value:e,enumerable:!0}):s,e)),m=e=>i(C({},"__esModule",{value:!0}),e);var n={};f(n,{ActionExecutionMessage:()=>o.ActionExecutionMessage,Chat:()=>g.default,LiveChatWidget:()=>d.LiveChatWidget,Role:()=>o.Role,TextMessage:()=>o.TextMessage,useCopilotAction:()=>o.useCopilotAction,useCopilotChat:()=>o.useCopilotChat,useCopilotReadable:()=>o.useCopilotReadable});module.exports=m(n);var g=h(require("./chat/index")),o=require("./chat/utils");a(n,require("./credits/index.js"),module.exports);a(n,require("./registration/index.js"),module.exports);var d=require("./LiveChatWidget/index.js");
1
+ "use strict";var l=Object.create;var C=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty;var f=(e,t)=>{for(var s in t)C(e,s,{get:t[s],enumerable:!0})},i=(e,t,s,p)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of x(t))!c.call(e,r)&&r!==s&&C(e,r,{get:()=>t[r],enumerable:!(p=u(t,r))||p.enumerable});return e},a=(e,t,s)=>(i(e,t,"default"),s&&i(s,t,"default")),h=(e,t,s)=>(s=e!=null?l(M(e)):{},i(t||!e||!e.__esModule?C(s,"default",{value:e,enumerable:!0}):s,e)),m=e=>i(C({},"__esModule",{value:!0}),e);var n={};f(n,{ActionExecutionMessage:()=>o.ActionExecutionMessage,Chat:()=>g.default,LiveChatWidget:()=>d.LiveChatWidget,Role:()=>o.Role,TextMessage:()=>o.TextMessage,useCopilotAction:()=>o.useCopilotAction,useCopilotChat:()=>o.useCopilotChat,useCopilotReadable:()=>o.useCopilotReadable});module.exports=m(n);var g=h(require("./chat/index.js")),o=require("./chat/utils.js");a(n,require("./credits/index.js"),module.exports);a(n,require("./registration/index.js"),module.exports);var d=require("./LiveChatWidget/index.js");
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/index.ts"],
4
- "sourcesContent": ["export { default as Chat } from './chat/index'\n\nexport {\n Role,\n ActionExecutionMessage,\n TextMessage,\n useCopilotChat,\n useCopilotAction,\n useCopilotReadable,\n} from './chat/utils'\n\nexport * from './credits/index.js'\n\nexport * from './registration/index.js'\n\n\n\n// LiveChatWidget \u5BFC\u51FA\nexport { LiveChatWidget } from './LiveChatWidget/index.js'\nexport type {\n LiveChatWidgetProps,\n Message,\n MessageContent,\n MessageRole,\n MessageContentType,\n MessageMetadata,\n MessageRenderer,\n QuickReply,\n ProductCardContent,\n ProductListContent,\n PolicyContent,\n QuickRepliesContent,\n ThinkingContent,\n ErrorContent,\n SSEEvent,\n ChatStreamRequest,\n} from './LiveChatWidget/index.js'\n"],
5
- "mappings": "wmBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mSAAAE,EAAAF,GAAA,IAAAG,EAAgC,2BAEhCC,EAOO,wBAEPC,EAAAL,EAAc,8BAXd,gBAaAK,EAAAL,EAAc,mCAbd,gBAkBA,IAAAM,EAA+B",
4
+ "sourcesContent": ["export { default as Chat } from './chat/index.js'\n\nexport {\n Role,\n ActionExecutionMessage,\n TextMessage,\n useCopilotChat,\n useCopilotAction,\n useCopilotReadable,\n} from './chat/utils.js'\n\nexport * from './credits/index.js'\n\nexport * from './registration/index.js'\n\n\n\n// LiveChatWidget \u5BFC\u51FA\nexport { LiveChatWidget } from './LiveChatWidget/index.js'\nexport type {\n LiveChatWidgetProps,\n Message,\n MessageContent,\n MessageRole,\n MessageContentType,\n MessageMetadata,\n MessageRenderer,\n QuickReply,\n ProductCardContent,\n ProductListContent,\n PolicyContent,\n QuickRepliesContent,\n ThinkingContent,\n ErrorContent,\n SSEEvent,\n ChatStreamRequest,\n} from './LiveChatWidget/index.js'\n"],
5
+ "mappings": "wmBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mSAAAE,EAAAF,GAAA,IAAAG,EAAgC,8BAEhCC,EAOO,2BAEPC,EAAAL,EAAc,8BAXd,gBAaAK,EAAAL,EAAc,mCAbd,gBAkBA,IAAAM,EAA+B",
6
6
  "names": ["components_exports", "__export", "__toCommonJS", "import_chat", "import_utils", "__reExport", "import_LiveChatWidget"]
7
7
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * CartCard Storybook Stories
3
+ * 展示购物车卡片组件的各种状态
4
+ */
5
+ import type { Meta, StoryObj } from '@storybook/react';
6
+ import React from 'react';
7
+ import type { CartContent } from '../components/LiveChatWidget/types';
8
+ declare const CartCardWrapper: React.FC<{
9
+ content: CartContent;
10
+ }>;
11
+ declare const meta: Meta<typeof CartCardWrapper>;
12
+ export default meta;
13
+ type Story = StoryObj<typeof CartCardWrapper>;
14
+ /**
15
+ * 空购物车状态
16
+ */
17
+ export declare const Empty: Story;
18
+ /**
19
+ * 单件商品
20
+ */
21
+ export declare const SingleItem: Story;
22
+ /**
23
+ * 多件商品
24
+ */
25
+ export declare const MultipleItems: Story;
26
+ /**
27
+ * 有折扣码的购物车
28
+ */
29
+ export declare const WithDiscount: Story;
30
+ /**
31
+ * 多个折扣码(部分失效)
32
+ */
33
+ export declare const WithMultipleDiscounts: Story;
@@ -0,0 +1,21 @@
1
+ "use strict";var c=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var p=(t,e)=>{for(var a in e)c(t,a,{get:e[a],enumerable:!0})},m=(t,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of d(e))!s.call(t,o)&&o!==a&&c(t,o,{get:()=>e[o],enumerable:!(n=i(e,o))||n.enumerable});return t};var y=t=>m(c({},"__esModule",{value:!0}),t);var A={};p(A,{Empty:()=>S,MultipleItems:()=>g,SingleItem:()=>f,WithDiscount:()=>U,WithMultipleDiscounts:()=>D,default:()=>C});module.exports=y(A);var r=require("react/jsx-runtime"),u=require("../components/LiveChatWidget/components/MessageContent/CartCard.js");const l=({content:t})=>(0,r.jsx)("div",{className:"flex min-h-screen items-center justify-center bg-gray-100 p-4",children:(0,r.jsx)("div",{className:"w-full max-w-md",children:u.CartCard.render(t,!1,!1)})}),h={title:"Campaign/LiveChatWidget/MessageContent/CartCard",component:l,parameters:{layout:"fullscreen",docs:{description:{component:`
2
+ # \u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6
3
+
4
+ \u663E\u793A\u7528\u6237\u8D2D\u7269\u8F66\u5185\u5BB9\uFF0C\u5305\u62EC\u5546\u54C1\u5217\u8868\u3001\u4EF7\u683C\u6C47\u603B\u548C\u7ED3\u8D26\u6309\u94AE\u3002
5
+
6
+ ## \u529F\u80FD\u7279\u6027
7
+
8
+ - \u{1F4E6} **\u5546\u54C1\u5217\u8868**: \u5C55\u793A\u8D2D\u7269\u8F66\u4E2D\u7684\u6240\u6709\u5546\u54C1
9
+ - \u{1F4B0} **\u4EF7\u683C\u6C47\u603B**: \u663E\u793A\u5C0F\u8BA1\u3001\u6298\u6263\u548C\u603B\u8BA1
10
+ - \u{1F39F}\uFE0F **\u6298\u6263\u7801**: \u663E\u793A\u5DF2\u5E94\u7528\u7684\u6298\u6263\u7801\u53CA\u5176\u72B6\u6001
11
+ - \u{1F6D2} **\u7ED3\u8D26\u6309\u94AE**: \u4E00\u952E\u8DF3\u8F6C\u5230 Shopify \u7ED3\u8D26\u9875\u9762
12
+ - \u{1F233} **\u7A7A\u72B6\u6001**: \u4F18\u96C5\u7684\u7A7A\u8D2D\u7269\u8F66\u63D0\u793A
13
+
14
+ ## \u4F7F\u7528\u573A\u666F
15
+
16
+ - \u7528\u6237\u6DFB\u52A0\u5546\u54C1\u5230\u8D2D\u7269\u8F66\u540E (add_to_cart)
17
+ - \u7528\u6237\u67E5\u8BE2\u8D2D\u7269\u8F66\u5185\u5BB9 (get_cart)
18
+ - \u7528\u6237\u4FEE\u6539\u8D2D\u7269\u8F66\u6570\u91CF (update_cart_item)
19
+ - \u7528\u6237\u5E94\u7528\u6298\u6263\u7801 (update_discount_codes)
20
+ `}}},tags:["autodocs"]};var C=h;const S={args:{content:{type:"cart",data:{isEmpty:!0,cartId:"gid://shopify/Cart/empty",totalQuantity:0,lines:[],cost:{totalAmount:{amount:"0.00",currencyCode:"USD"},subtotalAmount:{amount:"0.00",currencyCode:"USD"}}}}}},f={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:1,lines:[{id:"gid://shopify/CartLine/12345",quantity:1,cost:{totalAmount:{amount:"99.99",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"99.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}}],cost:{totalAmount:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"99.99",currencyCode:"USD"}},checkoutUrl:"https://checkout.shopify.com/example"}}}},g={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:5,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}},{id:"gid://shopify/CartLine/12346",quantity:1,cost:{totalAmount:{amount:"129.99",currencyCode:"USD"},amountPerQuantity:{amount:"129.99",currencyCode:"USD"},subtotalAmount:{amount:"129.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567891",title:"White",price:{amount:"129.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop",altText:"eufy Security Camera"},product:{id:"gid://shopify/Product/8179159826619",title:"eufy Security Camera",handle:"eufy-security-camera"}}},{id:"gid://shopify/CartLine/12347",quantity:2,cost:{totalAmount:{amount:"79.98",currencyCode:"USD"},amountPerQuantity:{amount:"39.99",currencyCode:"USD"},subtotalAmount:{amount:"79.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567892",title:"USB-C Cable",price:{amount:"39.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1583863788434-e58a36330cf0?w=400&h=400&fit=crop",altText:"Anker USB-C Cable"},product:{id:"gid://shopify/Product/8179159826620",title:"Anker USB-C Cable 6ft",handle:"anker-usb-c-cable"}}}],cost:{totalAmount:{amount:"409.95",currencyCode:"USD"},subtotalAmount:{amount:"409.95",currencyCode:"USD"}},checkoutUrl:"https://checkout.shopify.com/example"}}}},U={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:3,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}},{id:"gid://shopify/CartLine/12346",quantity:1,cost:{totalAmount:{amount:"129.99",currencyCode:"USD"},amountPerQuantity:{amount:"129.99",currencyCode:"USD"},subtotalAmount:{amount:"129.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567891",title:"White",price:{amount:"129.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop",altText:"eufy Security Camera"},product:{id:"gid://shopify/Product/8179159826619",title:"eufy Security Camera",handle:"eufy-security-camera"}}}],cost:{totalAmount:{amount:"296.97",currencyCode:"USD"},subtotalAmount:{amount:"329.97",currencyCode:"USD"}},discountCodes:[{code:"SPRING20",applicable:!0}],checkoutUrl:"https://checkout.shopify.com/example"}}}},D={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:2,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}}],cost:{totalAmount:{amount:"179.98",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},discountCodes:[{code:"WELCOME10",applicable:!0},{code:"EXPIRED20",applicable:!1}],checkoutUrl:"https://checkout.shopify.com/example"}}}};
21
+ //# sourceMappingURL=CartCard.stories.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/stories/CartCard.stories.tsx"],
4
+ "sourcesContent": ["/**\n * CartCard Storybook Stories\n * \u5C55\u793A\u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6\u7684\u5404\u79CD\u72B6\u6001\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport React from 'react'\nimport { CartCard } from '../components/LiveChatWidget/components/MessageContent/CartCard.js'\nimport type { CartContent } from '../components/LiveChatWidget/types'\n\n// Story \u5305\u88C5\u7EC4\u4EF6\nconst CartCardWrapper: React.FC<{ content: CartContent }> = ({ content }) => {\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-gray-100 p-4\">\n <div className=\"w-full max-w-md\">{CartCard.render(content, false, false)}</div>\n </div>\n )\n}\n\nconst meta: Meta<typeof CartCardWrapper> = {\n title: 'Campaign/LiveChatWidget/MessageContent/CartCard',\n component: CartCardWrapper,\n parameters: {\n layout: 'fullscreen',\n docs: {\n description: {\n component: `\n# \u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6\n\n\u663E\u793A\u7528\u6237\u8D2D\u7269\u8F66\u5185\u5BB9\uFF0C\u5305\u62EC\u5546\u54C1\u5217\u8868\u3001\u4EF7\u683C\u6C47\u603B\u548C\u7ED3\u8D26\u6309\u94AE\u3002\n\n## \u529F\u80FD\u7279\u6027\n\n- \uD83D\uDCE6 **\u5546\u54C1\u5217\u8868**: \u5C55\u793A\u8D2D\u7269\u8F66\u4E2D\u7684\u6240\u6709\u5546\u54C1\n- \uD83D\uDCB0 **\u4EF7\u683C\u6C47\u603B**: \u663E\u793A\u5C0F\u8BA1\u3001\u6298\u6263\u548C\u603B\u8BA1\n- \uD83C\uDF9F\uFE0F **\u6298\u6263\u7801**: \u663E\u793A\u5DF2\u5E94\u7528\u7684\u6298\u6263\u7801\u53CA\u5176\u72B6\u6001\n- \uD83D\uDED2 **\u7ED3\u8D26\u6309\u94AE**: \u4E00\u952E\u8DF3\u8F6C\u5230 Shopify \u7ED3\u8D26\u9875\u9762\n- \uD83C\uDE33 **\u7A7A\u72B6\u6001**: \u4F18\u96C5\u7684\u7A7A\u8D2D\u7269\u8F66\u63D0\u793A\n\n## \u4F7F\u7528\u573A\u666F\n\n- \u7528\u6237\u6DFB\u52A0\u5546\u54C1\u5230\u8D2D\u7269\u8F66\u540E (add_to_cart)\n- \u7528\u6237\u67E5\u8BE2\u8D2D\u7269\u8F66\u5185\u5BB9 (get_cart)\n- \u7528\u6237\u4FEE\u6539\u8D2D\u7269\u8F66\u6570\u91CF (update_cart_item)\n- \u7528\u6237\u5E94\u7528\u6298\u6263\u7801 (update_discount_codes)\n `,\n },\n },\n },\n tags: ['autodocs'],\n}\n\nexport default meta\n\ntype Story = StoryObj<typeof CartCardWrapper>\n\n/**\n * \u7A7A\u8D2D\u7269\u8F66\u72B6\u6001\n */\nexport const Empty: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: true,\n cartId: 'gid://shopify/Cart/empty',\n totalQuantity: 0,\n lines: [],\n cost: {\n totalAmount: {\n amount: '0.00',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '0.00',\n currencyCode: 'USD',\n },\n },\n },\n },\n },\n}\n\n/**\n * \u5355\u4EF6\u5546\u54C1\n */\nexport const SingleItem: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 1,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n },\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u591A\u4EF6\u5546\u54C1\n */\nexport const MultipleItems: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 5,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12346',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567891',\n title: 'White',\n price: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',\n altText: 'eufy Security Camera',\n },\n product: {\n id: 'gid://shopify/Product/8179159826619',\n title: 'eufy Security Camera',\n handle: 'eufy-security-camera',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12347',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '79.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '39.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '79.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567892',\n title: 'USB-C Cable',\n price: {\n amount: '39.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1583863788434-e58a36330cf0?w=400&h=400&fit=crop',\n altText: 'Anker USB-C Cable',\n },\n product: {\n id: 'gid://shopify/Product/8179159826620',\n title: 'Anker USB-C Cable 6ft',\n handle: 'anker-usb-c-cable',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '409.95',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '409.95',\n currencyCode: 'USD',\n },\n },\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u6709\u6298\u6263\u7801\u7684\u8D2D\u7269\u8F66\n */\nexport const WithDiscount: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 3,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12346',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567891',\n title: 'White',\n price: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',\n altText: 'eufy Security Camera',\n },\n product: {\n id: 'gid://shopify/Product/8179159826619',\n title: 'eufy Security Camera',\n handle: 'eufy-security-camera',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '296.97',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '329.97',\n currencyCode: 'USD',\n },\n },\n discountCodes: [\n {\n code: 'SPRING20',\n applicable: true,\n },\n ],\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u591A\u4E2A\u6298\u6263\u7801\uFF08\u90E8\u5206\u5931\u6548\uFF09\n */\nexport const WithMultipleDiscounts: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 2,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '179.98',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n discountCodes: [\n {\n code: 'WELCOME10',\n applicable: true,\n },\n {\n code: 'EXPIRED20',\n applicable: false,\n },\n ],\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["CartCard_stories_exports", "__export", "Empty", "MultipleItems", "SingleItem", "WithDiscount", "WithMultipleDiscounts", "CartCard_stories_default", "__toCommonJS", "import_jsx_runtime", "import_CartCard", "CartCardWrapper", "content", "meta"]
7
+ }
@@ -1,2 +1,2 @@
1
- import{Fragment as A,jsx as t,jsxs as c}from"react/jsx-runtime";import{useState as T}from"react";import{DEFAULT_COMMON_TEXT as _,CURRENCY_SYMBOLS as I}from"../../constants";const d=(l,a="USD")=>`${I[a]||a}${l}`,M=({data:l,onAddToCart:a,commonText:m})=>{const{products:i,dimensions:g}=l,y={..._,...m},p=i?.filter(e=>e&&e.shopifyId)||[],f=2,D=p.slice(0,f),[x,h]=T(D);if(p.length===0)return null;const N=(e,n)=>{const r=p.find(o=>o.shopifyId===n);if(r){const o=[...x];o[e]=r,h(o)}},C=x.slice(0,f),b=(e,n)=>!e||!e.values||!Array.isArray(e.values)?null:e.values.find(r=>r&&r.product_id===n),k=(e,n)=>n?c("div",{className:"border-b border-[#DADCE0] pb-2",children:[t("div",{className:"mb-1",children:t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:e==="price"?"has member price":e})}),t("div",{className:"flex gap-4",style:{gap:"36px"},children:C.map((r,o)=>{if(!r||!r.shopifyId)return null;const u=b(n,r.shopifyId);return t("div",{className:"flex-1",children:P(u,n.label)},`comparison-${o}`)})})]}):null,P=(e,n)=>{if(!e)return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:"-"});if(n.toLowerCase().includes("price")){const r=e?.has_member_price,o=e?.available?e.min===e.max?d(e.min,e.currency):`${d(e.min,e.currency)} - ${d(e.max,e.currency)}`:"-";return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:r?"Yes":"No"})}if(n.toLowerCase().includes("variant"))return c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:[e.count||0," ",e.count===1?"variant":"variants"]});if(n.toLowerCase().includes("review")){const r=e.rating||0,o=e.count||0;return c("div",{className:"flex items-center gap-1",children:[c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:["\u2B50 ",r.toFixed(1)]}),c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:["(",o,")"]})]})}return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:e.display||e.value||"-"})};return c("div",{className:"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]",children:[t("div",{className:"flex p-4",style:{gap:"36px",paddingBottom:"0px"},children:C.map((e,n)=>{if(!e||!e.shopifyId)return null;const r=g.price?b(g.price,e.shopifyId):null,o=e.variants?.[0],u=o?.discount?.has_discount,v=u?o?.discount?.discount_price:null,w=v||r?.min||e.price.amount,F=e.price.amount,R=s=>{s.preventDefault(),s.stopPropagation(),a&&a(e)};return c("div",{className:"flex flex-1 flex-col items-center",children:[t("div",{className:"mb-4 w-full",children:t("select",{value:e.shopifyId,onChange:s=>N(n,s.target.value),className:"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",style:{appearance:"none",backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")`,backgroundRepeat:"no-repeat",backgroundPosition:"right 12px center",paddingRight:"32px"},children:p.map(s=>t("option",{value:s.shopifyId,children:s.title.length>30?`${s.title.slice(0,30)}...`:s.title},s.shopifyId))})}),t("a",{href:e.productUrl,target:"_blank",rel:"noopener noreferrer",className:"mb-4 block w-full max-w-[160px]",children:t("div",{className:"aspect-square w-full overflow-hidden rounded-lg",children:e.imageUrl?t("img",{src:e.imageUrl,alt:e.title,className:"size-full object-contain",loading:"lazy"}):t("div",{className:"flex size-full items-center justify-center text-gray-400",children:t("svg",{className:"size-12",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:t("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})})})})}),t("div",{className:"mb-4 flex flex-col items-center gap-1",children:c("div",{className:"flex items-center gap-2",children:[t("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]",children:d(w,r?.currency||e.price.currency)}),u&&v&&t("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through",children:d(F,e.price.currency)})]})}),a&&t("button",{type:"button",onClick:R,className:"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white",style:{backgroundColor:"#1D1D1F"},children:y.addToCart})]},`product-column-${n}`)})}),t("div",{className:"flex flex-col gap-4 p-4",children:Object.entries(g).map(([e,n])=>n?t("div",{children:k(n.label,n)},e):null)})]})},U={render:(l,a,m)=>{if(l.type!=="product_comparison"||!l.data)return null;const i=l.data;return i.productComparisonRender?t(A,{children:i.productComparisonRender(i)}):t(M,{data:i,isUser:a,isSystem:m,onAddToCart:i.onAddToCart,commonText:i.commonText})}};export{M as ProductComparison,U as ProductComparisonRenderer};
1
+ import{Fragment as A,jsx as t,jsxs as c}from"react/jsx-runtime";import{useState as T}from"react";import{DEFAULT_COMMON_TEXT as _,CURRENCY_SYMBOLS as I}from"../../constants";const d=(l,a="USD")=>`${I[a]||a}${l}`,M=({data:l,onAddToCart:a,commonText:m})=>{const{products:i,dimensions:g}=l,v={..._,...m},p=i?.filter(e=>e&&e.shopifyId)||[],f=2,D=p.slice(0,f),[x,h]=T(D);if(p.length===0)return null;const N=(e,n)=>{const r=p.find(o=>o.shopifyId===n);if(r){const o=[...x];o[e]=r,h(o)}},C=x.slice(0,f),b=(e,n)=>!e||!e.values||!Array.isArray(e.values)?null:e.values.find(r=>r&&r.product_id===n),k=(e,n)=>n?c("div",{className:"border-b border-[#DADCE0] pb-2",children:[t("div",{className:"mb-1",children:t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:e==="price"?"has member price":e})}),t("div",{className:"flex gap-4",style:{gap:"36px"},children:C.map((r,o)=>{if(!r||!r.shopifyId)return null;const u=b(n,r.shopifyId);return t("div",{className:"flex-1",children:P(u,n.label)},`comparison-${o}`)})})]}):null,P=(e,n)=>{if(!e)return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:"-"});if(n.toLowerCase().includes("price")){const r=e?.has_member_price,o=e?.available?e.min===e.max?d(e.min,e.currency):`${d(e.min,e.currency)} - ${d(e.max,e.currency)}`:"-";return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:r?"Yes":"No"})}if(n.toLowerCase().includes("variant"))return c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:[e.count||0," ",e.count===1?"variant":"variants"]});if(n.toLowerCase().includes("review")){const r=e.rating||0,o=e.count||0;return c("div",{className:"flex items-center gap-1",children:[c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:["\u2B50 ",r.toFixed(1)]}),c("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]",children:["(",o,")"]})]})}return t("span",{className:"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",children:e.display||e.value||"-"})};return c("div",{className:"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]",children:[t("div",{className:"flex p-4",style:{gap:"36px",paddingBottom:"0px"},children:C.map((e,n)=>{if(!e||!e.shopifyId)return null;const r=g.price?b(g.price,e.shopifyId):null,o=e.variants?.[0],u=o?.discount?.has_discount,y=u?o?.discount?.discount_price:null,w=y||r?.min||e.price.amount,F=e.price.amount,R=s=>{s.preventDefault(),s.stopPropagation(),a&&a(e)};return c("div",{className:"flex flex-1 flex-col items-center",children:[t("div",{className:"mb-4 w-full",children:t("select",{value:e.shopifyId,onChange:s=>N(n,s.target.value),className:"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]",style:{appearance:"none",backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")`,backgroundRepeat:"no-repeat",backgroundPosition:"right 12px center",paddingRight:"32px"},children:p.map(s=>t("option",{value:s.shopifyId,children:s.title.length>30?`${s.title.slice(0,30)}...`:s.title},s.shopifyId))})}),t("a",{href:e.productUrl,target:"_blank",rel:"noopener noreferrer",className:"mb-4 block w-full max-w-[160px]",children:t("div",{className:"aspect-square w-full overflow-hidden rounded-lg",children:e.imageUrl?t("img",{src:e.imageUrl,alt:e.title,className:"size-full object-contain",loading:"lazy"}):t("div",{className:"flex size-full items-center justify-center text-gray-400",children:t("svg",{className:"size-12",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:t("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})})})})}),t("div",{className:"mb-4 flex flex-col items-center gap-1",children:c("div",{className:"flex items-center gap-2 justify-center flex-wrap",children:[t("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]",children:d(w,r?.currency||e.price.currency)}),u&&y&&t("span",{className:"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through",children:d(F,e.price.currency)})]})}),a&&t("button",{type:"button",onClick:R,className:"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white",style:{backgroundColor:"#1D1D1F"},children:v.addToCart})]},`product-column-${n}`)})}),t("div",{className:"flex flex-col gap-4 p-4",children:Object.entries(g).map(([e,n])=>n?t("div",{children:k(n.label,n)},e):null)})]})},U={render:(l,a,m)=>{if(l.type!=="product_comparison"||!l.data)return null;const i=l.data;return i.productComparisonRender?t(A,{children:i.productComparisonRender(i)}):t(M,{data:i,isUser:a,isSystem:m,onAddToCart:i.onAddToCart,commonText:i.commonText})}};export{M as ProductComparison,U as ProductComparisonRenderer};
2
2
  //# sourceMappingURL=ProductComparison.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/components/LiveChatWidget/components/MessageContent/ProductComparison.tsx"],
4
- "sourcesContent": ["/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n * \u663E\u793A\u591A\u4E2A\u4EA7\u54C1\u7684\u5BF9\u6BD4\u4FE1\u606F\uFF0C\u91C7\u7528\u8868\u683C\u5E03\u5C40\u5C55\u793A\u5404\u7EF4\u5EA6\u5DEE\u5F02\n * \u57FA\u4E8E\u53C2\u8003\u8BBE\u8BA1\uFF1A\u9876\u90E8\u4EA7\u54C1\u5C55\u793A + \u5E95\u90E8\u5BF9\u6BD4\u8868\u683C\n */\n\nimport React, { useState } from 'react'\nimport type { Product, MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT, CURRENCY_SYMBOLS } from '../../constants'\n\n/**\n * \u5BF9\u6BD4\u7EF4\u5EA6\u6570\u636E\u7ED3\u6784\n */\ninterface ComparisonDimension {\n label: string\n values: Array<{\n product_id: string\n [key: string]: any\n }>\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\n */\nexport interface ProductComparisonData {\n products: Product[]\n dimensions: {\n price?: ComparisonDimension\n variants?: ComparisonDimension\n member_price?: ComparisonDimension\n discount?: ComparisonDimension\n reviews?: ComparisonDimension\n [key: string]: ComparisonDimension | undefined\n }\n commonText?: CommonText\n productComparisonRender?: (data: ProductComparisonData) => React.ReactNode\n}\n\nexport interface ProductComparisonProps {\n /**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\n */\n data: ProductComparisonData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n\n /**\n * \u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: Product) => void\n\n /**\n * \u901A\u7528\u6587\u6848\u914D\u7F6E\n */\n commonText?: CommonText\n}\n\n/**\n * \u683C\u5F0F\u5316\u4EF7\u683C\u663E\u793A\n */\nconst formatPrice = (amount: number, currency: string = 'USD'): string => {\n const symbol = CURRENCY_SYMBOLS[currency] || currency\n return `${symbol}${amount}`\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 [\u4EA7\u54C11\u56FE\u7247] [\u4EA7\u54C12\u56FE\u7247] \u2502\n * \u2502 \u4EF7\u683C1 \u4EF7\u683C2 \u2502\n * \u2502 \u989C\u8272\u9009\u9879 \u989C\u8272\u9009\u9879 \u2502\n * \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n * \u2502 \u7EF4\u5EA61 \u2502 \u503C1-1 \u2502 \u503C1-2 \u2502\n * \u2502 \u7EF4\u5EA62 \u2502 \u503C2-1 \u2502 \u503C2-2 \u2502\n * \u2502 \u7EF4\u5EA63 \u2502 \u503C3-1 \u2502 \u503C3-2 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n */\nexport const ProductComparison: React.FC<ProductComparisonProps> = ({ data, onAddToCart, commonText }) => {\n const { products: rawProducts, dimensions } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n // \u8FC7\u6EE4\u6389 null \u6216\u65E0\u6548\u7684\u4EA7\u54C1\n const allProducts = rawProducts?.filter(p => p && p.shopifyId) || []\n\n // \u5BF9\u6BD4\u5217\u6570\uFF08\u56FA\u5B9A\u4E3A2\u5217\uFF09\n const COMPARISON_COLUMNS = 2\n\n // \u521D\u59CB\u5316\u6BCF\u4E2A\u5BF9\u6BD4\u4F4D\u7F6E\u7684\u9009\u4E2D\u4EA7\u54C1\uFF08\u9ED8\u8BA4\u53D6\u524D\u4E24\u4E2A\u4EA7\u54C1\uFF09\n const initialSelectedProducts = allProducts.slice(0, COMPARISON_COLUMNS)\n const [selectedProducts, setSelectedProducts] = useState<Product[]>(initialSelectedProducts)\n\n // Early return \u5FC5\u987B\u5728\u6240\u6709 hooks \u4E4B\u540E\n if (allProducts.length === 0) {\n return null\n }\n\n // \u5904\u7406\u4EA7\u54C1\u9009\u62E9\u53D8\u66F4\n const handleProductChange = (index: number, productId: string) => {\n const newProduct = allProducts.find(p => p.shopifyId === productId)\n if (newProduct) {\n const newSelectedProducts = [...selectedProducts]\n newSelectedProducts[index] = newProduct\n setSelectedProducts(newSelectedProducts)\n }\n }\n\n // \u5F53\u524D\u663E\u793A\u7684\u4EA7\u54C1\uFF08\u786E\u4FDD\u53EA\u663E\u793A\u6307\u5B9A\u5217\u6570\uFF09\n const products = selectedProducts.slice(0, COMPARISON_COLUMNS)\n\n /**\n * \u83B7\u53D6\u6307\u5B9A\u4EA7\u54C1\u5728\u67D0\u4E2A\u7EF4\u5EA6\u7684\u503C\n */\n const getDimensionValue = (dimension: ComparisonDimension, productId: string): any => {\n if (!dimension || !dimension.values || !Array.isArray(dimension.values)) {\n return null\n }\n return dimension.values.find(v => v && v.product_id === productId)\n }\n\n /**\n * \u6E32\u67D3\u901A\u7528\u5BF9\u6BD4\u884C\n */\n const renderComparisonRow = (label: string, dimension: ComparisonDimension | undefined) => {\n if (!dimension) return null\n\n return (\n <div className=\"border-b border-[#DADCE0] pb-2\">\n {/* \u7EF4\u5EA6\u6807\u7B7E\uFF08\u6807\u9898\uFF09 */}\n <div className=\"mb-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">{label==='price'?'has member price':label}</span>\n </div>\n\n {/* \u4EA7\u54C1\u503C\u5217\u8868\uFF08\u6A2A\u5411\u6392\u5217\uFF09 */}\n <div className=\"flex gap-4\" style={{ gap: '36px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n const value = getDimensionValue(dimension, product.shopifyId)\n\n return (\n <div key={`comparison-${index}`} className=\"flex-1\">\n {renderDimensionValue(value, dimension.label)}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n\n /**\n * \u6E32\u67D3\u7EF4\u5EA6\u503C\n */\n const renderDimensionValue = (value: any, dimensionLabel: string) => {\n if (!value) {\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">-</span>\n }\n\n // \u6839\u636E\u4E0D\u540C\u7EF4\u5EA6\u7C7B\u578B\u6E32\u67D3\u4E0D\u540C\u683C\u5F0F\n if (dimensionLabel.toLowerCase().includes('price')) {\n const hasMemberPrice = value?.has_member_price\n // \u4EF7\u683C\u7EF4\u5EA6\n const priceDisplay = value?.available?\n value.min === value.max\n ? formatPrice(value.min, value.currency)\n : `${formatPrice(value.min, value.currency)} - ${formatPrice(value.max, value.currency)}`:'-'\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">{hasMemberPrice?'Yes':'No'}</span>\n }\n\n if (dimensionLabel.toLowerCase().includes('variant')) {\n // \u53D8\u4F53\u6570\u91CF\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.count || 0} {value.count === 1 ? 'variant' : 'variants'}\n </span>\n )\n }\n\n if (dimensionLabel.toLowerCase().includes('review')) {\n // \u8BC4\u8BBA\u7EF4\u5EA6\uFF1A\u663E\u793A\u8BC4\u5206\u548C\u6570\u91CF\n const rating = value.rating || 0\n const count = value.count || 0\n return (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n \u2B50 {rating.toFixed(1)}\n </span>\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">\n ({count})\n </span>\n </div>\n )\n }\n\n // \u9ED8\u8BA4\u663E\u793A\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.display || value.value || '-'}\n </span>\n )\n }\n\n return (\n <div className=\"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* \u9876\u90E8\u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <div className=\"flex p-4\" style={{ gap: '36px', paddingBottom: '0px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n\n // \u83B7\u53D6\u4EF7\u683C\u4FE1\u606F\n const priceInfo = dimensions.price ? getDimensionValue(dimensions.price, product.shopifyId) : null\n\n // \u83B7\u53D6\u6298\u6263\u4FE1\u606F\n const firstVariant = product.variants?.[0]\n const hasDiscount = firstVariant?.discount?.has_discount\n const discountPrice = hasDiscount ? firstVariant?.discount?.discount_price : null\n\n // \u5F53\u524D\u663E\u793A\u4EF7\u683C\uFF1A\u6709\u6298\u6263\u65F6\u663E\u793A\u6298\u6263\u4EF7\uFF0C\u5426\u5219\u663E\u793A\u539F\u4EF7\n const currentPrice = discountPrice || priceInfo?.min || product.price.amount\n const originalPrice = product.price.amount\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB\u5904\u7406\n const handleAddToCart = (e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (onAddToCart) {\n onAddToCart(product)\n }\n }\n\n return (\n <div key={`product-column-${index}`} className=\"flex flex-1 flex-col items-center\">\n {/* \u4EA7\u54C1\u9009\u62E9\u4E0B\u62C9\u6846 */}\n <div className=\"mb-4 w-full\">\n <select\n value={product.shopifyId}\n onChange={e => handleProductChange(index, e.target.value)}\n className=\"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\"\n style={{\n appearance: 'none',\n backgroundImage:\n \"url(\\\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\")\",\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'right 12px center',\n paddingRight: '32px',\n }}\n >\n {allProducts.map(p => (\n <option key={p.shopifyId} value={p.shopifyId}>\n {p.title.length > 30 ? `${p.title.slice(0, 30)}...` : p.title}\n </option>\n ))}\n </select>\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <a\n href={product.productUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mb-4 block w-full max-w-[160px]\"\n >\n <div className=\"aspect-square w-full overflow-hidden rounded-lg\">\n {product.imageUrl ? (\n <img\n src={product.imageUrl}\n alt={product.title}\n className=\"size-full object-contain\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-gray-400\">\n <svg className=\"size-12\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n )}\n </div>\n </a>\n\n {/* \u4EF7\u683C\u5C55\u793A\uFF08\u5E26\u5212\u7EBF\u4EF7\uFF09 */}\n <div className=\"mb-4 flex flex-col items-center gap-1\">\n <div className=\"flex items-center gap-2\">\n {/* \u5F53\u524D\u4EF7\u683C\uFF08\u6298\u6263\u4EF7\u6216\u539F\u4EF7\uFF09 */}\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]\">\n {formatPrice(currentPrice, priceInfo?.currency || product.price.currency)}\n </span>\n {/* \u5212\u7EBF\u4EF7 - \u4EC5\u5728\u6709\u6298\u6263\u65F6\u663E\u793A */}\n {hasDiscount && discountPrice && (\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through\">\n {formatPrice(originalPrice, product.price.currency)}\n </span>\n )}\n </div>\n </div>\n\n {/* Add to Cart \u6309\u94AE */}\n {onAddToCart && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n className=\"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white\"\n style={{ backgroundColor: '#1D1D1F' }}\n >\n {mergedText.addToCart}\n </button>\n )}\n\n </div>\n )\n })}\n </div>\n\n {/* \u5BF9\u6BD4\u8868\u683C\u533A\u57DF */}\n <div className=\"flex flex-col gap-4 p-4\">\n {/* \u904D\u5386\u6240\u6709\u7EF4\u5EA6\u5E76\u6E32\u67D3 */}\n {Object.entries(dimensions).map(([key, dimension]) => {\n if (!dimension) return null // price \u5DF2\u5728\u9876\u90E8\u663E\u793A\n return <div key={key}>{renderComparisonRow(dimension.label, dimension)}</div>\n })}\n </div>\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4EA7\u54C1\u5BF9\u6BD4\u6E32\u67D3\u5668\n */\nexport const ProductComparisonRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'product_comparison' || !content.data) {\n return null\n }\n\n const comparisonData = content.data as ProductComparisonData & { onAddToCart?: (product: Product) => void }\n\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u6E32\u67D3\u51FD\u6570\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\n if (comparisonData.productComparisonRender) {\n return <>{comparisonData.productComparisonRender(comparisonData)}</>\n }\n\n return (\n <ProductComparison\n data={comparisonData}\n isUser={isUser}\n isSystem={isSystem}\n onAddToCart={comparisonData.onAddToCart}\n commonText={comparisonData.commonText}\n />\n )\n },\n}\n"],
5
- "mappings": "AA4IM,OAwNO,YAAAA,EArNH,OAAAC,EAHJ,QAAAC,MAAA,oBAtIN,OAAgB,YAAAC,MAAgB,QAEhC,OAAS,uBAAAC,EAAqB,oBAAAC,MAAwB,kBA4DtD,MAAMC,EAAc,CAACC,EAAgBC,EAAmB,QAE/C,GADQH,EAAiBG,CAAQ,GAAKA,CAC7B,GAAGD,CAAM,GAmBdE,EAAsD,CAAC,CAAE,KAAAC,EAAM,YAAAC,EAAa,WAAAC,CAAW,IAAM,CACxG,KAAM,CAAE,SAAUC,EAAa,WAAAC,CAAW,EAAIJ,EAGxCK,EAAa,CAAE,GAAGX,EAAqB,GAAGQ,CAAW,EAGrDI,EAAcH,GAAa,OAAOI,GAAKA,GAAKA,EAAE,SAAS,GAAK,CAAC,EAG7DC,EAAqB,EAGrBC,EAA0BH,EAAY,MAAM,EAAGE,CAAkB,EACjE,CAACE,EAAkBC,CAAmB,EAAIlB,EAAoBgB,CAAuB,EAG3F,GAAIH,EAAY,SAAW,EACzB,OAAO,KAIT,MAAMM,EAAsB,CAACC,EAAeC,IAAsB,CAChE,MAAMC,EAAaT,EAAY,KAAKC,GAAKA,EAAE,YAAcO,CAAS,EAClE,GAAIC,EAAY,CACd,MAAMC,EAAsB,CAAC,GAAGN,CAAgB,EAChDM,EAAoBH,CAAK,EAAIE,EAC7BJ,EAAoBK,CAAmB,CACzC,CACF,EAGMC,EAAWP,EAAiB,MAAM,EAAGF,CAAkB,EAKvDU,EAAoB,CAACC,EAAgCL,IACrD,CAACK,GAAa,CAACA,EAAU,QAAU,CAAC,MAAM,QAAQA,EAAU,MAAM,EAC7D,KAEFA,EAAU,OAAO,KAAKC,GAAKA,GAAKA,EAAE,aAAeN,CAAS,EAM7DO,EAAsB,CAACC,EAAeH,IACrCA,EAGH3B,EAAC,OAAI,UAAU,iCAEb,UAAAD,EAAC,OAAI,UAAU,OACb,SAAAA,EAAC,QAAK,UAAU,oEAAqE,SAAA+B,IAAQ,QAAQ,mBAAmBA,EAAM,EAChI,EAGA/B,EAAC,OAAI,UAAU,aAAa,MAAO,CAAE,IAAK,MAAO,EAC9C,SAAA0B,EAAS,IAAI,CAACM,EAASV,IAAU,CAChC,GAAI,CAACU,GAAW,CAACA,EAAQ,UAAW,OAAO,KAC3C,MAAMC,EAAQN,EAAkBC,EAAWI,EAAQ,SAAS,EAE5D,OACEhC,EAAC,OAAgC,UAAU,SACxC,SAAAkC,EAAqBD,EAAOL,EAAU,KAAK,GADpC,cAAcN,CAAK,EAE7B,CAEJ,CAAC,EACH,GACF,EAtBqB,KA6BnBY,EAAuB,CAACD,EAAYE,IAA2B,CACnE,GAAI,CAACF,EACH,OAAOjC,EAAC,QAAK,UAAU,oEAAoE,aAAC,EAI9F,GAAImC,EAAe,YAAY,EAAE,SAAS,OAAO,EAAG,CAClD,MAAMC,EAAiBH,GAAO,iBAExBI,EAAeJ,GAAO,UAC1BA,EAAM,MAAQA,EAAM,IAChB5B,EAAY4B,EAAM,IAAKA,EAAM,QAAQ,EACrC,GAAG5B,EAAY4B,EAAM,IAAKA,EAAM,QAAQ,CAAC,MAAM5B,EAAY4B,EAAM,IAAKA,EAAM,QAAQ,CAAC,GAAG,IAC9F,OAAOjC,EAAC,QAAK,UAAU,oEAAqE,SAAAoC,EAAe,MAAM,KAAK,CACxH,CAEA,GAAID,EAAe,YAAY,EAAE,SAAS,SAAS,EAEjD,OACElC,EAAC,QAAK,UAAU,oEACb,UAAAgC,EAAM,OAAS,EAAE,IAAEA,EAAM,QAAU,EAAI,UAAY,YACtD,EAIJ,GAAIE,EAAe,YAAY,EAAE,SAAS,QAAQ,EAAG,CAEnD,MAAMG,EAASL,EAAM,QAAU,EACzBM,EAAQN,EAAM,OAAS,EAC7B,OACEhC,EAAC,OAAI,UAAU,0BACb,UAAAA,EAAC,QAAK,UAAU,oEAAoE,oBAC/EqC,EAAO,QAAQ,CAAC,GACrB,EACArC,EAAC,QAAK,UAAU,oEAAoE,cAChFsC,EAAM,KACV,GACF,CAEJ,CAGA,OACEvC,EAAC,QAAK,UAAU,oEACb,SAAAiC,EAAM,SAAWA,EAAM,OAAS,IACnC,CAEJ,EAEA,OACEhC,EAAC,OAAI,UAAU,kDAEb,UAAAD,EAAC,OAAI,UAAU,YAAY,MAAO,CAAE,IAAK,OAAQ,cAAe,KAAM,EACnE,SAAA0B,EAAS,IAAI,CAACM,EAASV,IAAU,CAChC,GAAI,CAACU,GAAW,CAACA,EAAQ,UAAW,OAAO,KAG3C,MAAMQ,EAAY3B,EAAW,MAAQc,EAAkBd,EAAW,MAAOmB,EAAQ,SAAS,EAAI,KAGxFS,EAAeT,EAAQ,WAAW,CAAC,EACnCU,EAAcD,GAAc,UAAU,aACtCE,EAAgBD,EAAcD,GAAc,UAAU,eAAiB,KAGvEG,EAAeD,GAAiBH,GAAW,KAAOR,EAAQ,MAAM,OAChEa,EAAgBb,EAAQ,MAAM,OAG9Bc,EAAmBC,GAAwB,CAC/CA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EACdrC,GACFA,EAAYsB,CAAO,CAEvB,EAEA,OACE/B,EAAC,OAAoC,UAAU,oCAE7C,UAAAD,EAAC,OAAI,UAAU,cACb,SAAAA,EAAC,UACC,MAAOgC,EAAQ,UACf,SAAUe,GAAK1B,EAAoBC,EAAOyB,EAAE,OAAO,KAAK,EACxD,UAAU,qIACV,MAAO,CACL,WAAY,OACZ,gBACE,8PACF,iBAAkB,YAClB,mBAAoB,oBACpB,aAAc,MAChB,EAEC,SAAAhC,EAAY,IAAIC,GACfhB,EAAC,UAAyB,MAAOgB,EAAE,UAChC,SAAAA,EAAE,MAAM,OAAS,GAAK,GAAGA,EAAE,MAAM,MAAM,EAAG,EAAE,CAAC,MAAQA,EAAE,OAD7CA,EAAE,SAEf,CACD,EACH,EACF,EAGAhB,EAAC,KACC,KAAMgC,EAAQ,WACd,OAAO,SACP,IAAI,sBACJ,UAAU,kCAEV,SAAAhC,EAAC,OAAI,UAAU,kDACZ,SAAAgC,EAAQ,SACPhC,EAAC,OACC,IAAKgC,EAAQ,SACb,IAAKA,EAAQ,MACb,UAAU,2BACV,QAAQ,OACV,EAEAhC,EAAC,OAAI,UAAU,2DACb,SAAAA,EAAC,OAAI,UAAU,UAAU,KAAK,OAAO,OAAO,eAAe,QAAQ,YACjE,SAAAA,EAAC,QACC,cAAc,QACd,eAAe,QACf,YAAa,EACb,EAAE,4JACJ,EACF,EACF,EAEJ,EACF,EAGAA,EAAC,OAAI,UAAU,wCACb,SAAAC,EAAC,OAAI,UAAU,0BAEb,UAAAD,EAAC,QAAK,UAAU,sEACb,SAAAK,EAAYuC,EAAcJ,GAAW,UAAYR,EAAQ,MAAM,QAAQ,EAC1E,EAECU,GAAeC,GACd3C,EAAC,QAAK,UAAU,mFACb,SAAAK,EAAYwC,EAAeb,EAAQ,MAAM,QAAQ,EACpD,GAEJ,EACF,EAGCtB,GACCV,EAAC,UACC,KAAK,SACL,QAAS8C,EACT,UAAU,6IACV,MAAO,CAAE,gBAAiB,SAAU,EAEnC,SAAAhC,EAAW,UACd,IA/EM,kBAAkBQ,CAAK,EAkFjC,CAEJ,CAAC,EACH,EAGAtB,EAAC,OAAI,UAAU,0BAEZ,gBAAO,QAAQa,CAAU,EAAE,IAAI,CAAC,CAACmC,EAAKpB,CAAS,IACzCA,EACE5B,EAAC,OAAe,SAAA8B,EAAoBF,EAAU,MAAOA,CAAS,GAApDoB,CAAsD,EADhD,IAExB,EACH,GACF,CAEJ,EAKaC,EAA6C,CACxD,OAAQ,CAACC,EAASC,EAAQC,IAAa,CACrC,GAAIF,EAAQ,OAAS,sBAAwB,CAACA,EAAQ,KACpD,OAAO,KAGT,MAAMG,EAAiBH,EAAQ,KAG/B,OAAIG,EAAe,wBACVrD,EAAAD,EAAA,CAAG,SAAAsD,EAAe,wBAAwBA,CAAc,EAAE,EAIjErD,EAACQ,EAAA,CACC,KAAM6C,EACN,OAAQF,EACR,SAAUC,EACV,YAAaC,EAAe,YAC5B,WAAYA,EAAe,WAC7B,CAEJ,CACF",
4
+ "sourcesContent": ["/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n * \u663E\u793A\u591A\u4E2A\u4EA7\u54C1\u7684\u5BF9\u6BD4\u4FE1\u606F\uFF0C\u91C7\u7528\u8868\u683C\u5E03\u5C40\u5C55\u793A\u5404\u7EF4\u5EA6\u5DEE\u5F02\n * \u57FA\u4E8E\u53C2\u8003\u8BBE\u8BA1\uFF1A\u9876\u90E8\u4EA7\u54C1\u5C55\u793A + \u5E95\u90E8\u5BF9\u6BD4\u8868\u683C\n */\n\nimport React, { useState } from 'react'\nimport type { Product, MessageRenderer, CommonText } from '../../types'\nimport { DEFAULT_COMMON_TEXT, CURRENCY_SYMBOLS } from '../../constants'\n\n/**\n * \u5BF9\u6BD4\u7EF4\u5EA6\u6570\u636E\u7ED3\u6784\n */\ninterface ComparisonDimension {\n label: string\n values: Array<{\n product_id: string\n [key: string]: any\n }>\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\u7ED3\u6784\n */\nexport interface ProductComparisonData {\n products: Product[]\n dimensions: {\n price?: ComparisonDimension\n variants?: ComparisonDimension\n member_price?: ComparisonDimension\n discount?: ComparisonDimension\n reviews?: ComparisonDimension\n [key: string]: ComparisonDimension | undefined\n }\n commonText?: CommonText\n productComparisonRender?: (data: ProductComparisonData) => React.ReactNode\n}\n\nexport interface ProductComparisonProps {\n /**\n * \u4EA7\u54C1\u5BF9\u6BD4\u6570\u636E\n */\n data: ProductComparisonData\n\n /**\n * \u662F\u5426\u4E3A\u7528\u6237\u6D88\u606F\n */\n isUser?: boolean\n\n /**\n * \u662F\u5426\u4E3A\u7CFB\u7EDF\u6D88\u606F\n */\n isSystem?: boolean\n\n /**\n * \u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u56DE\u8C03\n */\n onAddToCart?: (product: Product) => void\n\n /**\n * \u901A\u7528\u6587\u6848\u914D\u7F6E\n */\n commonText?: CommonText\n}\n\n/**\n * \u683C\u5F0F\u5316\u4EF7\u683C\u663E\u793A\n */\nconst formatPrice = (amount: number, currency: string = 'USD'): string => {\n const symbol = CURRENCY_SYMBOLS[currency] || currency\n return `${symbol}${amount}`\n}\n\n/**\n * \u4EA7\u54C1\u5BF9\u6BD4\u7EC4\u4EF6\n *\n * \u5E03\u5C40\uFF1A\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 [\u4EA7\u54C11\u56FE\u7247] [\u4EA7\u54C12\u56FE\u7247] \u2502\n * \u2502 \u4EF7\u683C1 \u4EF7\u683C2 \u2502\n * \u2502 \u989C\u8272\u9009\u9879 \u989C\u8272\u9009\u9879 \u2502\n * \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n * \u2502 \u7EF4\u5EA61 \u2502 \u503C1-1 \u2502 \u503C1-2 \u2502\n * \u2502 \u7EF4\u5EA62 \u2502 \u503C2-1 \u2502 \u503C2-2 \u2502\n * \u2502 \u7EF4\u5EA63 \u2502 \u503C3-1 \u2502 \u503C3-2 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * ```\n */\nexport const ProductComparison: React.FC<ProductComparisonProps> = ({ data, onAddToCart, commonText }) => {\n const { products: rawProducts, dimensions } = data\n\n // \u5408\u5E76\u9ED8\u8BA4\u6587\u6848\u548C\u81EA\u5B9A\u4E49\u6587\u6848\n const mergedText = { ...DEFAULT_COMMON_TEXT, ...commonText }\n\n // \u8FC7\u6EE4\u6389 null \u6216\u65E0\u6548\u7684\u4EA7\u54C1\n const allProducts = rawProducts?.filter(p => p && p.shopifyId) || []\n\n // \u5BF9\u6BD4\u5217\u6570\uFF08\u56FA\u5B9A\u4E3A2\u5217\uFF09\n const COMPARISON_COLUMNS = 2\n\n // \u521D\u59CB\u5316\u6BCF\u4E2A\u5BF9\u6BD4\u4F4D\u7F6E\u7684\u9009\u4E2D\u4EA7\u54C1\uFF08\u9ED8\u8BA4\u53D6\u524D\u4E24\u4E2A\u4EA7\u54C1\uFF09\n const initialSelectedProducts = allProducts.slice(0, COMPARISON_COLUMNS)\n const [selectedProducts, setSelectedProducts] = useState<Product[]>(initialSelectedProducts)\n\n // Early return \u5FC5\u987B\u5728\u6240\u6709 hooks \u4E4B\u540E\n if (allProducts.length === 0) {\n return null\n }\n\n // \u5904\u7406\u4EA7\u54C1\u9009\u62E9\u53D8\u66F4\n const handleProductChange = (index: number, productId: string) => {\n const newProduct = allProducts.find(p => p.shopifyId === productId)\n if (newProduct) {\n const newSelectedProducts = [...selectedProducts]\n newSelectedProducts[index] = newProduct\n setSelectedProducts(newSelectedProducts)\n }\n }\n\n // \u5F53\u524D\u663E\u793A\u7684\u4EA7\u54C1\uFF08\u786E\u4FDD\u53EA\u663E\u793A\u6307\u5B9A\u5217\u6570\uFF09\n const products = selectedProducts.slice(0, COMPARISON_COLUMNS)\n\n /**\n * \u83B7\u53D6\u6307\u5B9A\u4EA7\u54C1\u5728\u67D0\u4E2A\u7EF4\u5EA6\u7684\u503C\n */\n const getDimensionValue = (dimension: ComparisonDimension, productId: string): any => {\n if (!dimension || !dimension.values || !Array.isArray(dimension.values)) {\n return null\n }\n return dimension.values.find(v => v && v.product_id === productId)\n }\n\n /**\n * \u6E32\u67D3\u901A\u7528\u5BF9\u6BD4\u884C\n */\n const renderComparisonRow = (label: string, dimension: ComparisonDimension | undefined) => {\n if (!dimension) return null\n\n return (\n <div className=\"border-b border-[#DADCE0] pb-2\">\n {/* \u7EF4\u5EA6\u6807\u7B7E\uFF08\u6807\u9898\uFF09 */}\n <div className=\"mb-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">{label==='price'?'has member price':label}</span>\n </div>\n\n {/* \u4EA7\u54C1\u503C\u5217\u8868\uFF08\u6A2A\u5411\u6392\u5217\uFF09 */}\n <div className=\"flex gap-4\" style={{ gap: '36px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n const value = getDimensionValue(dimension, product.shopifyId)\n\n return (\n <div key={`comparison-${index}`} className=\"flex-1\">\n {renderDimensionValue(value, dimension.label)}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n\n /**\n * \u6E32\u67D3\u7EF4\u5EA6\u503C\n */\n const renderDimensionValue = (value: any, dimensionLabel: string) => {\n if (!value) {\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">-</span>\n }\n\n // \u6839\u636E\u4E0D\u540C\u7EF4\u5EA6\u7C7B\u578B\u6E32\u67D3\u4E0D\u540C\u683C\u5F0F\n if (dimensionLabel.toLowerCase().includes('price')) {\n const hasMemberPrice = value?.has_member_price\n // \u4EF7\u683C\u7EF4\u5EA6\n const priceDisplay = value?.available?\n value.min === value.max\n ? formatPrice(value.min, value.currency)\n : `${formatPrice(value.min, value.currency)} - ${formatPrice(value.max, value.currency)}`:'-'\n return <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">{hasMemberPrice?'Yes':'No'}</span>\n }\n\n if (dimensionLabel.toLowerCase().includes('variant')) {\n // \u53D8\u4F53\u6570\u91CF\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.count || 0} {value.count === 1 ? 'variant' : 'variants'}\n </span>\n )\n }\n\n if (dimensionLabel.toLowerCase().includes('review')) {\n // \u8BC4\u8BBA\u7EF4\u5EA6\uFF1A\u663E\u793A\u8BC4\u5206\u548C\u6570\u91CF\n const rating = value.rating || 0\n const count = value.count || 0\n return (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n \u2B50 {rating.toFixed(1)}\n </span>\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#86868C]\">\n ({count})\n </span>\n </div>\n )\n }\n\n // \u9ED8\u8BA4\u663E\u793A\n return (\n <span className=\"text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\">\n {value.display || value.value || '-'}\n </span>\n )\n }\n\n return (\n <div className=\"w-full overflow-hidden rounded-2xl bg-[#F5F6F7]\">\n {/* \u9876\u90E8\u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <div className=\"flex p-4\" style={{ gap: '36px', paddingBottom: '0px' }}>\n {products.map((product, index) => {\n if (!product || !product.shopifyId) return null\n\n // \u83B7\u53D6\u4EF7\u683C\u4FE1\u606F\n const priceInfo = dimensions.price ? getDimensionValue(dimensions.price, product.shopifyId) : null\n\n // \u83B7\u53D6\u6298\u6263\u4FE1\u606F\n const firstVariant = product.variants?.[0]\n const hasDiscount = firstVariant?.discount?.has_discount\n const discountPrice = hasDiscount ? firstVariant?.discount?.discount_price : null\n\n // \u5F53\u524D\u663E\u793A\u4EF7\u683C\uFF1A\u6709\u6298\u6263\u65F6\u663E\u793A\u6298\u6263\u4EF7\uFF0C\u5426\u5219\u663E\u793A\u539F\u4EF7\n const currentPrice = discountPrice || priceInfo?.min || product.price.amount\n const originalPrice = product.price.amount\n\n // Add to Cart \u6309\u94AE\u70B9\u51FB\u5904\u7406\n const handleAddToCart = (e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (onAddToCart) {\n onAddToCart(product)\n }\n }\n\n return (\n <div key={`product-column-${index}`} className=\"flex flex-1 flex-col items-center\">\n {/* \u4EA7\u54C1\u9009\u62E9\u4E0B\u62C9\u6846 */}\n <div className=\"mb-4 w-full\">\n <select\n value={product.shopifyId}\n onChange={e => handleProductChange(index, e.target.value)}\n className=\"w-full rounded-lg border border-[#DADCE0] bg-[#F5F6F7] px-3 py-2 text-sm font-bold leading-[1.4] tracking-[-0.02em] text-[#1D1D1F]\"\n style={{\n appearance: 'none',\n backgroundImage:\n \"url(\\\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%231D1D1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\")\",\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'right 12px center',\n paddingRight: '32px',\n }}\n >\n {allProducts.map(p => (\n <option key={p.shopifyId} value={p.shopifyId}>\n {p.title.length > 30 ? `${p.title.slice(0, 30)}...` : p.title}\n </option>\n ))}\n </select>\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <a\n href={product.productUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mb-4 block w-full max-w-[160px]\"\n >\n <div className=\"aspect-square w-full overflow-hidden rounded-lg\">\n {product.imageUrl ? (\n <img\n src={product.imageUrl}\n alt={product.title}\n className=\"size-full object-contain\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-gray-400\">\n <svg className=\"size-12\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n )}\n </div>\n </a>\n\n {/* \u4EF7\u683C\u5C55\u793A\uFF08\u5E26\u5212\u7EBF\u4EF7\uFF09 */}\n <div className=\"mb-4 flex flex-col items-center gap-1\">\n <div className=\"flex items-center gap-2 justify-center flex-wrap\">\n {/* \u5F53\u524D\u4EF7\u683C\uFF08\u6298\u6263\u4EF7\u6216\u539F\u4EF7\uFF09 */}\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]\">\n {formatPrice(currentPrice, priceInfo?.currency || product.price.currency)}\n </span>\n {/* \u5212\u7EBF\u4EF7 - \u4EC5\u5728\u6709\u6298\u6263\u65F6\u663E\u793A */}\n {hasDiscount && discountPrice && (\n <span className=\"text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#4A4C56] line-through\">\n {formatPrice(originalPrice, product.price.currency)}\n </span>\n )}\n </div>\n </div>\n\n {/* Add to Cart \u6309\u94AE */}\n {onAddToCart && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n className=\"livechat-btn-primary mb-3 w-fit rounded-full px-[20px] py-[10px] text-center text-sm font-bold leading-[1.2] tracking-[-0.04em] text-white\"\n style={{ backgroundColor: '#1D1D1F' }}\n >\n {mergedText.addToCart}\n </button>\n )}\n\n </div>\n )\n })}\n </div>\n\n {/* \u5BF9\u6BD4\u8868\u683C\u533A\u57DF */}\n <div className=\"flex flex-col gap-4 p-4\">\n {/* \u904D\u5386\u6240\u6709\u7EF4\u5EA6\u5E76\u6E32\u67D3 */}\n {Object.entries(dimensions).map(([key, dimension]) => {\n if (!dimension) return null // price \u5DF2\u5728\u9876\u90E8\u663E\u793A\n return <div key={key}>{renderComparisonRow(dimension.label, dimension)}</div>\n })}\n </div>\n </div>\n )\n}\n\n/**\n * \u521B\u5EFA\u4EA7\u54C1\u5BF9\u6BD4\u6E32\u67D3\u5668\n */\nexport const ProductComparisonRenderer: MessageRenderer = {\n render: (content, isUser, isSystem) => {\n if (content.type !== 'product_comparison' || !content.data) {\n return null\n }\n\n const comparisonData = content.data as ProductComparisonData & { onAddToCart?: (product: Product) => void }\n\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u6E32\u67D3\u51FD\u6570\uFF0C\u4F7F\u7528\u81EA\u5B9A\u4E49\u6E32\u67D3\n if (comparisonData.productComparisonRender) {\n return <>{comparisonData.productComparisonRender(comparisonData)}</>\n }\n\n return (\n <ProductComparison\n data={comparisonData}\n isUser={isUser}\n isSystem={isSystem}\n onAddToCart={comparisonData.onAddToCart}\n commonText={comparisonData.commonText}\n />\n )\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["Fragment", "jsx", "jsxs", "useState", "DEFAULT_COMMON_TEXT", "CURRENCY_SYMBOLS", "formatPrice", "amount", "currency", "ProductComparison", "data", "onAddToCart", "commonText", "rawProducts", "dimensions", "mergedText", "allProducts", "p", "COMPARISON_COLUMNS", "initialSelectedProducts", "selectedProducts", "setSelectedProducts", "handleProductChange", "index", "productId", "newProduct", "newSelectedProducts", "products", "getDimensionValue", "dimension", "v", "renderComparisonRow", "label", "product", "value", "renderDimensionValue", "dimensionLabel", "hasMemberPrice", "priceDisplay", "rating", "count", "priceInfo", "firstVariant", "hasDiscount", "discountPrice", "currentPrice", "originalPrice", "handleAddToCart", "e", "key", "ProductComparisonRenderer", "content", "isUser", "isSystem", "comparisonData"]
7
7
  }
@@ -1,5 +1,5 @@
1
- export { default as Chat } from './chat/index';
2
- export { Role, ActionExecutionMessage, TextMessage, useCopilotChat, useCopilotAction, useCopilotReadable, } from './chat/utils';
1
+ export { default as Chat } from './chat/index.js';
2
+ export { Role, ActionExecutionMessage, TextMessage, useCopilotChat, useCopilotAction, useCopilotReadable, } from './chat/utils.js';
3
3
  export * from './credits/index.js';
4
4
  export * from './registration/index.js';
5
5
  export { LiveChatWidget } from './LiveChatWidget/index.js';
@@ -1,2 +1,2 @@
1
- import{default as o}from"./chat/index";import{Role as n,ActionExecutionMessage as a,TextMessage as r,useCopilotChat as i,useCopilotAction as C,useCopilotReadable as p}from"./chat/utils";export*from"./credits/index.js";export*from"./registration/index.js";import{LiveChatWidget as u}from"./LiveChatWidget/index.js";export{a as ActionExecutionMessage,o as Chat,u as LiveChatWidget,n as Role,r as TextMessage,C as useCopilotAction,i as useCopilotChat,p as useCopilotReadable};
1
+ import{default as o}from"./chat/index.js";import{Role as n,ActionExecutionMessage as a,TextMessage as r,useCopilotChat as i,useCopilotAction as C,useCopilotReadable as p}from"./chat/utils.js";export*from"./credits/index.js";export*from"./registration/index.js";import{LiveChatWidget as u}from"./LiveChatWidget/index.js";export{a as ActionExecutionMessage,o as Chat,u as LiveChatWidget,n as Role,r as TextMessage,C as useCopilotAction,i as useCopilotChat,p as useCopilotReadable};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/index.ts"],
4
- "sourcesContent": ["export { default as Chat } from './chat/index'\n\nexport {\n Role,\n ActionExecutionMessage,\n TextMessage,\n useCopilotChat,\n useCopilotAction,\n useCopilotReadable,\n} from './chat/utils'\n\nexport * from './credits/index.js'\n\nexport * from './registration/index.js'\n\n\n\n// LiveChatWidget \u5BFC\u51FA\nexport { LiveChatWidget } from './LiveChatWidget/index.js'\nexport type {\n LiveChatWidgetProps,\n Message,\n MessageContent,\n MessageRole,\n MessageContentType,\n MessageMetadata,\n MessageRenderer,\n QuickReply,\n ProductCardContent,\n ProductListContent,\n PolicyContent,\n QuickRepliesContent,\n ThinkingContent,\n ErrorContent,\n SSEEvent,\n ChatStreamRequest,\n} from './LiveChatWidget/index.js'\n"],
5
- "mappings": "AAAA,OAAoB,WAAXA,MAAuB,eAEhC,OACE,QAAAC,EACA,0BAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,oBAAAC,EACA,sBAAAC,MACK,eAEP,WAAc,qBAEd,WAAc,0BAKd,OAAS,kBAAAC,MAAsB",
4
+ "sourcesContent": ["export { default as Chat } from './chat/index.js'\n\nexport {\n Role,\n ActionExecutionMessage,\n TextMessage,\n useCopilotChat,\n useCopilotAction,\n useCopilotReadable,\n} from './chat/utils.js'\n\nexport * from './credits/index.js'\n\nexport * from './registration/index.js'\n\n\n\n// LiveChatWidget \u5BFC\u51FA\nexport { LiveChatWidget } from './LiveChatWidget/index.js'\nexport type {\n LiveChatWidgetProps,\n Message,\n MessageContent,\n MessageRole,\n MessageContentType,\n MessageMetadata,\n MessageRenderer,\n QuickReply,\n ProductCardContent,\n ProductListContent,\n PolicyContent,\n QuickRepliesContent,\n ThinkingContent,\n ErrorContent,\n SSEEvent,\n ChatStreamRequest,\n} from './LiveChatWidget/index.js'\n"],
5
+ "mappings": "AAAA,OAAoB,WAAXA,MAAuB,kBAEhC,OACE,QAAAC,EACA,0BAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,oBAAAC,EACA,sBAAAC,MACK,kBAEP,WAAc,qBAEd,WAAc,0BAKd,OAAS,kBAAAC,MAAsB",
6
6
  "names": ["default", "Role", "ActionExecutionMessage", "TextMessage", "useCopilotChat", "useCopilotAction", "useCopilotReadable", "LiveChatWidget"]
7
7
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * CartCard Storybook Stories
3
+ * 展示购物车卡片组件的各种状态
4
+ */
5
+ import type { Meta, StoryObj } from '@storybook/react';
6
+ import React from 'react';
7
+ import type { CartContent } from '../components/LiveChatWidget/types';
8
+ declare const CartCardWrapper: React.FC<{
9
+ content: CartContent;
10
+ }>;
11
+ declare const meta: Meta<typeof CartCardWrapper>;
12
+ export default meta;
13
+ type Story = StoryObj<typeof CartCardWrapper>;
14
+ /**
15
+ * 空购物车状态
16
+ */
17
+ export declare const Empty: Story;
18
+ /**
19
+ * 单件商品
20
+ */
21
+ export declare const SingleItem: Story;
22
+ /**
23
+ * 多件商品
24
+ */
25
+ export declare const MultipleItems: Story;
26
+ /**
27
+ * 有折扣码的购物车
28
+ */
29
+ export declare const WithDiscount: Story;
30
+ /**
31
+ * 多个折扣码(部分失效)
32
+ */
33
+ export declare const WithMultipleDiscounts: Story;
@@ -0,0 +1,21 @@
1
+ import{jsx as t}from"react/jsx-runtime";import{CartCard as o}from"../components/LiveChatWidget/components/MessageContent/CartCard.js";const a=({content:e})=>t("div",{className:"flex min-h-screen items-center justify-center bg-gray-100 p-4",children:t("div",{className:"w-full max-w-md",children:o.render(e,!1,!1)})}),c={title:"Campaign/LiveChatWidget/MessageContent/CartCard",component:a,parameters:{layout:"fullscreen",docs:{description:{component:`
2
+ # \u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6
3
+
4
+ \u663E\u793A\u7528\u6237\u8D2D\u7269\u8F66\u5185\u5BB9\uFF0C\u5305\u62EC\u5546\u54C1\u5217\u8868\u3001\u4EF7\u683C\u6C47\u603B\u548C\u7ED3\u8D26\u6309\u94AE\u3002
5
+
6
+ ## \u529F\u80FD\u7279\u6027
7
+
8
+ - \u{1F4E6} **\u5546\u54C1\u5217\u8868**: \u5C55\u793A\u8D2D\u7269\u8F66\u4E2D\u7684\u6240\u6709\u5546\u54C1
9
+ - \u{1F4B0} **\u4EF7\u683C\u6C47\u603B**: \u663E\u793A\u5C0F\u8BA1\u3001\u6298\u6263\u548C\u603B\u8BA1
10
+ - \u{1F39F}\uFE0F **\u6298\u6263\u7801**: \u663E\u793A\u5DF2\u5E94\u7528\u7684\u6298\u6263\u7801\u53CA\u5176\u72B6\u6001
11
+ - \u{1F6D2} **\u7ED3\u8D26\u6309\u94AE**: \u4E00\u952E\u8DF3\u8F6C\u5230 Shopify \u7ED3\u8D26\u9875\u9762
12
+ - \u{1F233} **\u7A7A\u72B6\u6001**: \u4F18\u96C5\u7684\u7A7A\u8D2D\u7269\u8F66\u63D0\u793A
13
+
14
+ ## \u4F7F\u7528\u573A\u666F
15
+
16
+ - \u7528\u6237\u6DFB\u52A0\u5546\u54C1\u5230\u8D2D\u7269\u8F66\u540E (add_to_cart)
17
+ - \u7528\u6237\u67E5\u8BE2\u8D2D\u7269\u8F66\u5185\u5BB9 (get_cart)
18
+ - \u7528\u6237\u4FEE\u6539\u8D2D\u7269\u8F66\u6570\u91CF (update_cart_item)
19
+ - \u7528\u6237\u5E94\u7528\u6298\u6263\u7801 (update_discount_codes)
20
+ `}}},tags:["autodocs"]};var i=c;const d={args:{content:{type:"cart",data:{isEmpty:!0,cartId:"gid://shopify/Cart/empty",totalQuantity:0,lines:[],cost:{totalAmount:{amount:"0.00",currencyCode:"USD"},subtotalAmount:{amount:"0.00",currencyCode:"USD"}}}}}},s={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:1,lines:[{id:"gid://shopify/CartLine/12345",quantity:1,cost:{totalAmount:{amount:"99.99",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"99.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}}],cost:{totalAmount:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"99.99",currencyCode:"USD"}},checkoutUrl:"https://checkout.shopify.com/example"}}}},p={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:5,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}},{id:"gid://shopify/CartLine/12346",quantity:1,cost:{totalAmount:{amount:"129.99",currencyCode:"USD"},amountPerQuantity:{amount:"129.99",currencyCode:"USD"},subtotalAmount:{amount:"129.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567891",title:"White",price:{amount:"129.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop",altText:"eufy Security Camera"},product:{id:"gid://shopify/Product/8179159826619",title:"eufy Security Camera",handle:"eufy-security-camera"}}},{id:"gid://shopify/CartLine/12347",quantity:2,cost:{totalAmount:{amount:"79.98",currencyCode:"USD"},amountPerQuantity:{amount:"39.99",currencyCode:"USD"},subtotalAmount:{amount:"79.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567892",title:"USB-C Cable",price:{amount:"39.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1583863788434-e58a36330cf0?w=400&h=400&fit=crop",altText:"Anker USB-C Cable"},product:{id:"gid://shopify/Product/8179159826620",title:"Anker USB-C Cable 6ft",handle:"anker-usb-c-cable"}}}],cost:{totalAmount:{amount:"409.95",currencyCode:"USD"},subtotalAmount:{amount:"409.95",currencyCode:"USD"}},checkoutUrl:"https://checkout.shopify.com/example"}}}},m={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:3,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}},{id:"gid://shopify/CartLine/12346",quantity:1,cost:{totalAmount:{amount:"129.99",currencyCode:"USD"},amountPerQuantity:{amount:"129.99",currencyCode:"USD"},subtotalAmount:{amount:"129.99",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567891",title:"White",price:{amount:"129.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop",altText:"eufy Security Camera"},product:{id:"gid://shopify/Product/8179159826619",title:"eufy Security Camera",handle:"eufy-security-camera"}}}],cost:{totalAmount:{amount:"296.97",currencyCode:"USD"},subtotalAmount:{amount:"329.97",currencyCode:"USD"}},discountCodes:[{code:"SPRING20",applicable:!0}],checkoutUrl:"https://checkout.shopify.com/example"}}}},y={args:{content:{type:"cart",data:{isEmpty:!1,cartId:"gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH",totalQuantity:2,lines:[{id:"gid://shopify/CartLine/12345",quantity:2,cost:{totalAmount:{amount:"199.98",currencyCode:"USD"},amountPerQuantity:{amount:"99.99",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},merchandise:{id:"gid://shopify/ProductVariant/43234567890",title:"Black",price:{amount:"99.99",currencyCode:"USD"},image:{url:"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop",altText:"Soundcore Space One"},product:{id:"gid://shopify/Product/8179159826618",title:"Soundcore Space One",handle:"soundcore-space-one"}}}],cost:{totalAmount:{amount:"179.98",currencyCode:"USD"},subtotalAmount:{amount:"199.98",currencyCode:"USD"}},discountCodes:[{code:"WELCOME10",applicable:!0},{code:"EXPIRED20",applicable:!1}],checkoutUrl:"https://checkout.shopify.com/example"}}}};export{d as Empty,p as MultipleItems,s as SingleItem,m as WithDiscount,y as WithMultipleDiscounts,i as default};
21
+ //# sourceMappingURL=CartCard.stories.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/stories/CartCard.stories.tsx"],
4
+ "sourcesContent": ["/**\n * CartCard Storybook Stories\n * \u5C55\u793A\u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6\u7684\u5404\u79CD\u72B6\u6001\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport React from 'react'\nimport { CartCard } from '../components/LiveChatWidget/components/MessageContent/CartCard.js'\nimport type { CartContent } from '../components/LiveChatWidget/types'\n\n// Story \u5305\u88C5\u7EC4\u4EF6\nconst CartCardWrapper: React.FC<{ content: CartContent }> = ({ content }) => {\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-gray-100 p-4\">\n <div className=\"w-full max-w-md\">{CartCard.render(content, false, false)}</div>\n </div>\n )\n}\n\nconst meta: Meta<typeof CartCardWrapper> = {\n title: 'Campaign/LiveChatWidget/MessageContent/CartCard',\n component: CartCardWrapper,\n parameters: {\n layout: 'fullscreen',\n docs: {\n description: {\n component: `\n# \u8D2D\u7269\u8F66\u5361\u7247\u7EC4\u4EF6\n\n\u663E\u793A\u7528\u6237\u8D2D\u7269\u8F66\u5185\u5BB9\uFF0C\u5305\u62EC\u5546\u54C1\u5217\u8868\u3001\u4EF7\u683C\u6C47\u603B\u548C\u7ED3\u8D26\u6309\u94AE\u3002\n\n## \u529F\u80FD\u7279\u6027\n\n- \uD83D\uDCE6 **\u5546\u54C1\u5217\u8868**: \u5C55\u793A\u8D2D\u7269\u8F66\u4E2D\u7684\u6240\u6709\u5546\u54C1\n- \uD83D\uDCB0 **\u4EF7\u683C\u6C47\u603B**: \u663E\u793A\u5C0F\u8BA1\u3001\u6298\u6263\u548C\u603B\u8BA1\n- \uD83C\uDF9F\uFE0F **\u6298\u6263\u7801**: \u663E\u793A\u5DF2\u5E94\u7528\u7684\u6298\u6263\u7801\u53CA\u5176\u72B6\u6001\n- \uD83D\uDED2 **\u7ED3\u8D26\u6309\u94AE**: \u4E00\u952E\u8DF3\u8F6C\u5230 Shopify \u7ED3\u8D26\u9875\u9762\n- \uD83C\uDE33 **\u7A7A\u72B6\u6001**: \u4F18\u96C5\u7684\u7A7A\u8D2D\u7269\u8F66\u63D0\u793A\n\n## \u4F7F\u7528\u573A\u666F\n\n- \u7528\u6237\u6DFB\u52A0\u5546\u54C1\u5230\u8D2D\u7269\u8F66\u540E (add_to_cart)\n- \u7528\u6237\u67E5\u8BE2\u8D2D\u7269\u8F66\u5185\u5BB9 (get_cart)\n- \u7528\u6237\u4FEE\u6539\u8D2D\u7269\u8F66\u6570\u91CF (update_cart_item)\n- \u7528\u6237\u5E94\u7528\u6298\u6263\u7801 (update_discount_codes)\n `,\n },\n },\n },\n tags: ['autodocs'],\n}\n\nexport default meta\n\ntype Story = StoryObj<typeof CartCardWrapper>\n\n/**\n * \u7A7A\u8D2D\u7269\u8F66\u72B6\u6001\n */\nexport const Empty: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: true,\n cartId: 'gid://shopify/Cart/empty',\n totalQuantity: 0,\n lines: [],\n cost: {\n totalAmount: {\n amount: '0.00',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '0.00',\n currencyCode: 'USD',\n },\n },\n },\n },\n },\n}\n\n/**\n * \u5355\u4EF6\u5546\u54C1\n */\nexport const SingleItem: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 1,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n },\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u591A\u4EF6\u5546\u54C1\n */\nexport const MultipleItems: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 5,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12346',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567891',\n title: 'White',\n price: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',\n altText: 'eufy Security Camera',\n },\n product: {\n id: 'gid://shopify/Product/8179159826619',\n title: 'eufy Security Camera',\n handle: 'eufy-security-camera',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12347',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '79.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '39.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '79.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567892',\n title: 'USB-C Cable',\n price: {\n amount: '39.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1583863788434-e58a36330cf0?w=400&h=400&fit=crop',\n altText: 'Anker USB-C Cable',\n },\n product: {\n id: 'gid://shopify/Product/8179159826620',\n title: 'Anker USB-C Cable 6ft',\n handle: 'anker-usb-c-cable',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '409.95',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '409.95',\n currencyCode: 'USD',\n },\n },\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u6709\u6298\u6263\u7801\u7684\u8D2D\u7269\u8F66\n */\nexport const WithDiscount: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 3,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n {\n id: 'gid://shopify/CartLine/12346',\n quantity: 1,\n cost: {\n totalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567891',\n title: 'White',\n price: {\n amount: '129.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',\n altText: 'eufy Security Camera',\n },\n product: {\n id: 'gid://shopify/Product/8179159826619',\n title: 'eufy Security Camera',\n handle: 'eufy-security-camera',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '296.97',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '329.97',\n currencyCode: 'USD',\n },\n },\n discountCodes: [\n {\n code: 'SPRING20',\n applicable: true,\n },\n ],\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n\n/**\n * \u591A\u4E2A\u6298\u6263\u7801\uFF08\u90E8\u5206\u5931\u6548\uFF09\n */\nexport const WithMultipleDiscounts: Story = {\n args: {\n content: {\n type: 'cart',\n data: {\n isEmpty: false,\n cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',\n totalQuantity: 2,\n lines: [\n {\n id: 'gid://shopify/CartLine/12345',\n quantity: 2,\n cost: {\n totalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n amountPerQuantity: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n merchandise: {\n id: 'gid://shopify/ProductVariant/43234567890',\n title: 'Black',\n price: {\n amount: '99.99',\n currencyCode: 'USD',\n },\n image: {\n url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',\n altText: 'Soundcore Space One',\n },\n product: {\n id: 'gid://shopify/Product/8179159826618',\n title: 'Soundcore Space One',\n handle: 'soundcore-space-one',\n },\n },\n },\n ],\n cost: {\n totalAmount: {\n amount: '179.98',\n currencyCode: 'USD',\n },\n subtotalAmount: {\n amount: '199.98',\n currencyCode: 'USD',\n },\n },\n discountCodes: [\n {\n code: 'WELCOME10',\n applicable: true,\n },\n {\n code: 'EXPIRED20',\n applicable: false,\n },\n ],\n checkoutUrl: 'https://checkout.shopify.com/example',\n },\n },\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["jsx", "CartCard", "CartCardWrapper", "content", "meta", "CartCard_stories_default", "Empty", "SingleItem", "MultipleItems", "WithDiscount", "WithMultipleDiscounts"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anker-in/campaign-ui",
3
- "version": "0.4.4",
3
+ "version": "0.4.5-beta.10",
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",
@@ -95,6 +95,7 @@
95
95
  "swiper": "^11.1.3",
96
96
  "tailwind-merge": "^2.3.0",
97
97
  "tailwindcss": "^3.4.3",
98
+ "@anker-in/headless-ui": "1.1.25-alpha.1767516866003",
98
99
  "@anker-in/lib": "1.1.3"
99
100
  },
100
101
  "publishConfig": {
@@ -298,7 +298,7 @@ export const ProductComparison: React.FC<ProductComparisonProps> = ({ data, onAd
298
298
 
299
299
  {/* 价格展示(带划线价) */}
300
300
  <div className="mb-4 flex flex-col items-center gap-1">
301
- <div className="flex items-center gap-2">
301
+ <div className="flex items-center gap-2 justify-center flex-wrap">
302
302
  {/* 当前价格(折扣价或原价) */}
303
303
  <span className="text-base font-bold leading-[1.2] tracking-[-0.02em] text-[#1D1D1F]">
304
304
  {formatPrice(currentPrice, priceInfo?.currency || product.price.currency)}
@@ -1,4 +1,4 @@
1
- export { default as Chat } from './chat/index'
1
+ export { default as Chat } from './chat/index.js'
2
2
 
3
3
  export {
4
4
  Role,
@@ -7,7 +7,7 @@ export {
7
7
  useCopilotChat,
8
8
  useCopilotAction,
9
9
  useCopilotReadable,
10
- } from './chat/utils'
10
+ } from './chat/utils.js'
11
11
 
12
12
  export * from './credits/index.js'
13
13
 
@@ -0,0 +1,459 @@
1
+ /**
2
+ * CartCard Storybook Stories
3
+ * 展示购物车卡片组件的各种状态
4
+ */
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react'
7
+ import React from 'react'
8
+ import { CartCard } from '../components/LiveChatWidget/components/MessageContent/CartCard.js'
9
+ import type { CartContent } from '../components/LiveChatWidget/types'
10
+
11
+ // Story 包装组件
12
+ const CartCardWrapper: React.FC<{ content: CartContent }> = ({ content }) => {
13
+ return (
14
+ <div className="flex min-h-screen items-center justify-center bg-gray-100 p-4">
15
+ <div className="w-full max-w-md">{CartCard.render(content, false, false)}</div>
16
+ </div>
17
+ )
18
+ }
19
+
20
+ const meta: Meta<typeof CartCardWrapper> = {
21
+ title: 'Campaign/LiveChatWidget/MessageContent/CartCard',
22
+ component: CartCardWrapper,
23
+ parameters: {
24
+ layout: 'fullscreen',
25
+ docs: {
26
+ description: {
27
+ component: `
28
+ # 购物车卡片组件
29
+
30
+ 显示用户购物车内容,包括商品列表、价格汇总和结账按钮。
31
+
32
+ ## 功能特性
33
+
34
+ - 📦 **商品列表**: 展示购物车中的所有商品
35
+ - 💰 **价格汇总**: 显示小计、折扣和总计
36
+ - 🎟️ **折扣码**: 显示已应用的折扣码及其状态
37
+ - 🛒 **结账按钮**: 一键跳转到 Shopify 结账页面
38
+ - 🈳 **空状态**: 优雅的空购物车提示
39
+
40
+ ## 使用场景
41
+
42
+ - 用户添加商品到购物车后 (add_to_cart)
43
+ - 用户查询购物车内容 (get_cart)
44
+ - 用户修改购物车数量 (update_cart_item)
45
+ - 用户应用折扣码 (update_discount_codes)
46
+ `,
47
+ },
48
+ },
49
+ },
50
+ tags: ['autodocs'],
51
+ }
52
+
53
+ export default meta
54
+
55
+ type Story = StoryObj<typeof CartCardWrapper>
56
+
57
+ /**
58
+ * 空购物车状态
59
+ */
60
+ export const Empty: Story = {
61
+ args: {
62
+ content: {
63
+ type: 'cart',
64
+ data: {
65
+ isEmpty: true,
66
+ cartId: 'gid://shopify/Cart/empty',
67
+ totalQuantity: 0,
68
+ lines: [],
69
+ cost: {
70
+ totalAmount: {
71
+ amount: '0.00',
72
+ currencyCode: 'USD',
73
+ },
74
+ subtotalAmount: {
75
+ amount: '0.00',
76
+ currencyCode: 'USD',
77
+ },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ }
83
+
84
+ /**
85
+ * 单件商品
86
+ */
87
+ export const SingleItem: Story = {
88
+ args: {
89
+ content: {
90
+ type: 'cart',
91
+ data: {
92
+ isEmpty: false,
93
+ cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',
94
+ totalQuantity: 1,
95
+ lines: [
96
+ {
97
+ id: 'gid://shopify/CartLine/12345',
98
+ quantity: 1,
99
+ cost: {
100
+ totalAmount: {
101
+ amount: '99.99',
102
+ currencyCode: 'USD',
103
+ },
104
+ amountPerQuantity: {
105
+ amount: '99.99',
106
+ currencyCode: 'USD',
107
+ },
108
+ subtotalAmount: {
109
+ amount: '99.99',
110
+ currencyCode: 'USD',
111
+ },
112
+ },
113
+ merchandise: {
114
+ id: 'gid://shopify/ProductVariant/43234567890',
115
+ title: 'Black',
116
+ price: {
117
+ amount: '99.99',
118
+ currencyCode: 'USD',
119
+ },
120
+ image: {
121
+ url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',
122
+ altText: 'Soundcore Space One',
123
+ },
124
+ product: {
125
+ id: 'gid://shopify/Product/8179159826618',
126
+ title: 'Soundcore Space One',
127
+ handle: 'soundcore-space-one',
128
+ },
129
+ },
130
+ },
131
+ ],
132
+ cost: {
133
+ totalAmount: {
134
+ amount: '99.99',
135
+ currencyCode: 'USD',
136
+ },
137
+ subtotalAmount: {
138
+ amount: '99.99',
139
+ currencyCode: 'USD',
140
+ },
141
+ },
142
+ checkoutUrl: 'https://checkout.shopify.com/example',
143
+ },
144
+ },
145
+ },
146
+ }
147
+
148
+ /**
149
+ * 多件商品
150
+ */
151
+ export const MultipleItems: Story = {
152
+ args: {
153
+ content: {
154
+ type: 'cart',
155
+ data: {
156
+ isEmpty: false,
157
+ cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',
158
+ totalQuantity: 5,
159
+ lines: [
160
+ {
161
+ id: 'gid://shopify/CartLine/12345',
162
+ quantity: 2,
163
+ cost: {
164
+ totalAmount: {
165
+ amount: '199.98',
166
+ currencyCode: 'USD',
167
+ },
168
+ amountPerQuantity: {
169
+ amount: '99.99',
170
+ currencyCode: 'USD',
171
+ },
172
+ subtotalAmount: {
173
+ amount: '199.98',
174
+ currencyCode: 'USD',
175
+ },
176
+ },
177
+ merchandise: {
178
+ id: 'gid://shopify/ProductVariant/43234567890',
179
+ title: 'Black',
180
+ price: {
181
+ amount: '99.99',
182
+ currencyCode: 'USD',
183
+ },
184
+ image: {
185
+ url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',
186
+ altText: 'Soundcore Space One',
187
+ },
188
+ product: {
189
+ id: 'gid://shopify/Product/8179159826618',
190
+ title: 'Soundcore Space One',
191
+ handle: 'soundcore-space-one',
192
+ },
193
+ },
194
+ },
195
+ {
196
+ id: 'gid://shopify/CartLine/12346',
197
+ quantity: 1,
198
+ cost: {
199
+ totalAmount: {
200
+ amount: '129.99',
201
+ currencyCode: 'USD',
202
+ },
203
+ amountPerQuantity: {
204
+ amount: '129.99',
205
+ currencyCode: 'USD',
206
+ },
207
+ subtotalAmount: {
208
+ amount: '129.99',
209
+ currencyCode: 'USD',
210
+ },
211
+ },
212
+ merchandise: {
213
+ id: 'gid://shopify/ProductVariant/43234567891',
214
+ title: 'White',
215
+ price: {
216
+ amount: '129.99',
217
+ currencyCode: 'USD',
218
+ },
219
+ image: {
220
+ url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',
221
+ altText: 'eufy Security Camera',
222
+ },
223
+ product: {
224
+ id: 'gid://shopify/Product/8179159826619',
225
+ title: 'eufy Security Camera',
226
+ handle: 'eufy-security-camera',
227
+ },
228
+ },
229
+ },
230
+ {
231
+ id: 'gid://shopify/CartLine/12347',
232
+ quantity: 2,
233
+ cost: {
234
+ totalAmount: {
235
+ amount: '79.98',
236
+ currencyCode: 'USD',
237
+ },
238
+ amountPerQuantity: {
239
+ amount: '39.99',
240
+ currencyCode: 'USD',
241
+ },
242
+ subtotalAmount: {
243
+ amount: '79.98',
244
+ currencyCode: 'USD',
245
+ },
246
+ },
247
+ merchandise: {
248
+ id: 'gid://shopify/ProductVariant/43234567892',
249
+ title: 'USB-C Cable',
250
+ price: {
251
+ amount: '39.99',
252
+ currencyCode: 'USD',
253
+ },
254
+ image: {
255
+ url: 'https://images.unsplash.com/photo-1583863788434-e58a36330cf0?w=400&h=400&fit=crop',
256
+ altText: 'Anker USB-C Cable',
257
+ },
258
+ product: {
259
+ id: 'gid://shopify/Product/8179159826620',
260
+ title: 'Anker USB-C Cable 6ft',
261
+ handle: 'anker-usb-c-cable',
262
+ },
263
+ },
264
+ },
265
+ ],
266
+ cost: {
267
+ totalAmount: {
268
+ amount: '409.95',
269
+ currencyCode: 'USD',
270
+ },
271
+ subtotalAmount: {
272
+ amount: '409.95',
273
+ currencyCode: 'USD',
274
+ },
275
+ },
276
+ checkoutUrl: 'https://checkout.shopify.com/example',
277
+ },
278
+ },
279
+ },
280
+ }
281
+
282
+ /**
283
+ * 有折扣码的购物车
284
+ */
285
+ export const WithDiscount: Story = {
286
+ args: {
287
+ content: {
288
+ type: 'cart',
289
+ data: {
290
+ isEmpty: false,
291
+ cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',
292
+ totalQuantity: 3,
293
+ lines: [
294
+ {
295
+ id: 'gid://shopify/CartLine/12345',
296
+ quantity: 2,
297
+ cost: {
298
+ totalAmount: {
299
+ amount: '199.98',
300
+ currencyCode: 'USD',
301
+ },
302
+ amountPerQuantity: {
303
+ amount: '99.99',
304
+ currencyCode: 'USD',
305
+ },
306
+ subtotalAmount: {
307
+ amount: '199.98',
308
+ currencyCode: 'USD',
309
+ },
310
+ },
311
+ merchandise: {
312
+ id: 'gid://shopify/ProductVariant/43234567890',
313
+ title: 'Black',
314
+ price: {
315
+ amount: '99.99',
316
+ currencyCode: 'USD',
317
+ },
318
+ image: {
319
+ url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',
320
+ altText: 'Soundcore Space One',
321
+ },
322
+ product: {
323
+ id: 'gid://shopify/Product/8179159826618',
324
+ title: 'Soundcore Space One',
325
+ handle: 'soundcore-space-one',
326
+ },
327
+ },
328
+ },
329
+ {
330
+ id: 'gid://shopify/CartLine/12346',
331
+ quantity: 1,
332
+ cost: {
333
+ totalAmount: {
334
+ amount: '129.99',
335
+ currencyCode: 'USD',
336
+ },
337
+ amountPerQuantity: {
338
+ amount: '129.99',
339
+ currencyCode: 'USD',
340
+ },
341
+ subtotalAmount: {
342
+ amount: '129.99',
343
+ currencyCode: 'USD',
344
+ },
345
+ },
346
+ merchandise: {
347
+ id: 'gid://shopify/ProductVariant/43234567891',
348
+ title: 'White',
349
+ price: {
350
+ amount: '129.99',
351
+ currencyCode: 'USD',
352
+ },
353
+ image: {
354
+ url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=400&h=400&fit=crop',
355
+ altText: 'eufy Security Camera',
356
+ },
357
+ product: {
358
+ id: 'gid://shopify/Product/8179159826619',
359
+ title: 'eufy Security Camera',
360
+ handle: 'eufy-security-camera',
361
+ },
362
+ },
363
+ },
364
+ ],
365
+ cost: {
366
+ totalAmount: {
367
+ amount: '296.97',
368
+ currencyCode: 'USD',
369
+ },
370
+ subtotalAmount: {
371
+ amount: '329.97',
372
+ currencyCode: 'USD',
373
+ },
374
+ },
375
+ discountCodes: [
376
+ {
377
+ code: 'SPRING20',
378
+ applicable: true,
379
+ },
380
+ ],
381
+ checkoutUrl: 'https://checkout.shopify.com/example',
382
+ },
383
+ },
384
+ },
385
+ }
386
+
387
+ /**
388
+ * 多个折扣码(部分失效)
389
+ */
390
+ export const WithMultipleDiscounts: Story = {
391
+ args: {
392
+ content: {
393
+ type: 'cart',
394
+ data: {
395
+ isEmpty: false,
396
+ cartId: 'gid://shopify/Cart/Z2NwLXVzLWVhc3QxOjAxSkZHRjA4VkFRQkhON1dBMTNLREZEVEZH',
397
+ totalQuantity: 2,
398
+ lines: [
399
+ {
400
+ id: 'gid://shopify/CartLine/12345',
401
+ quantity: 2,
402
+ cost: {
403
+ totalAmount: {
404
+ amount: '199.98',
405
+ currencyCode: 'USD',
406
+ },
407
+ amountPerQuantity: {
408
+ amount: '99.99',
409
+ currencyCode: 'USD',
410
+ },
411
+ subtotalAmount: {
412
+ amount: '199.98',
413
+ currencyCode: 'USD',
414
+ },
415
+ },
416
+ merchandise: {
417
+ id: 'gid://shopify/ProductVariant/43234567890',
418
+ title: 'Black',
419
+ price: {
420
+ amount: '99.99',
421
+ currencyCode: 'USD',
422
+ },
423
+ image: {
424
+ url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=400&fit=crop',
425
+ altText: 'Soundcore Space One',
426
+ },
427
+ product: {
428
+ id: 'gid://shopify/Product/8179159826618',
429
+ title: 'Soundcore Space One',
430
+ handle: 'soundcore-space-one',
431
+ },
432
+ },
433
+ },
434
+ ],
435
+ cost: {
436
+ totalAmount: {
437
+ amount: '179.98',
438
+ currencyCode: 'USD',
439
+ },
440
+ subtotalAmount: {
441
+ amount: '199.98',
442
+ currencyCode: 'USD',
443
+ },
444
+ },
445
+ discountCodes: [
446
+ {
447
+ code: 'WELCOME10',
448
+ applicable: true,
449
+ },
450
+ {
451
+ code: 'EXPIRED20',
452
+ applicable: false,
453
+ },
454
+ ],
455
+ checkoutUrl: 'https://checkout.shopify.com/example',
456
+ },
457
+ },
458
+ },
459
+ }