shopify-chatbot-widget 1.0.8 → 1.0.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.
- package/.env.development +2 -0
- package/dist/jaweb-chatbot.css +1 -1
- package/dist/jaweb-chatbot.iife.js +192 -599
- package/home.html +1 -1
- package/jawebDirect.js +1 -1
- package/package.json +1 -1
- package/src/App.tsx +9 -0
- package/src/Chatbot/Chatbot.css +193 -113
- package/src/Chatbot/Chatbot.tsx +26 -19
- package/src/Chatbot/components/Cart/Index.tsx +10 -8
- package/src/Chatbot/components/ChatInput.tsx +11 -11
- package/src/Chatbot/components/Home/Home.css +456 -0
- package/src/Chatbot/components/Home/Home.tsx +293 -0
- package/src/Chatbot/components/Messages/Addcart.tsx +1 -1
- package/src/Chatbot/components/Messages/AssistantMesage.tsx +78 -37
- package/src/Chatbot/components/Messages/CardSwiper.tsx +1 -1
- package/src/Chatbot/components/Messages/Carousel/CardSwiper.tsx +87 -92
- package/src/Chatbot/components/Messages/Carousel/ProductSwiper.css +361 -0
- package/src/Chatbot/components/Messages/Carousel/TryOn.tsx +2 -2
- package/src/Chatbot/components/Messages/ChatMessages.css +32 -1
- package/src/Chatbot/components/Messages/ChatMessages.tsx +21 -38
- package/src/Chatbot/components/Messages/OrderCard.css +177 -0
- package/src/Chatbot/components/Messages/OrderCard.tsx +120 -0
- package/src/Chatbot/components/Messages/ProductCard.css +1 -1
- package/src/Chatbot/components/Messages/Support.tsx +311 -118
- package/src/Chatbot/components/Messages/Typing.css +31 -35
- package/src/Chatbot/components/Messages/Typing.tsx +19 -18
- package/src/Chatbot/components/Messenger/Messenger.tsx +67 -14
- package/src/Chatbot/components/Powered.css +26 -28
- package/src/Chatbot/components/Powered.tsx +1 -1
- package/src/Chatbot/components/Sessions/CreateSession.tsx +12 -10
- package/src/Chatbot/components/TryOn/View.tsx +2 -2
- package/src/Chatbot/components/VoiceMode.css +247 -0
- package/src/Chatbot/components/VoiceMode.tsx +613 -0
- package/src/hooks/config.tsx +9 -10
- package/src/hooks/useChatbotAPI.tsx +146 -61
- package/src/hooks/useChatbotData.tsx +8 -5
- package/src/hooks/useSessionMessages.tsx +0 -1
- package/src/hooks/useWebsocke.tsx +40 -18
- package/src/i18n.tsx +384 -10
- package/src/Chatbot/components/Messages/Carousel/CardSwiperSalla.tsx +0 -187
- package/src/Chatbot/components/Messages/Carousel/CardSwiperZid.tsx +0 -208
- package/src/Chatbot/components/Messages/Carousel/SallaSwiper.css +0 -245
- package/src/Chatbot/components/Messages/SallaAssistantMessage.tsx +0 -202
- package/src/Chatbot/components/Messages/ZidAssistantMesage.tsx +0 -203
- package/src/Chatbot/components/Sessions/RenderList.tsx +0 -519
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import React, { useState, useMemo, type FC } from 'react';
|
|
2
|
-
import './ProductCard.css';
|
|
3
|
-
import ZidProductCarousel from './Carousel/CardSwiperZid';
|
|
4
|
-
import { ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons';
|
|
5
|
-
import { Button } from 'antd';
|
|
6
|
-
import { useKeenSlider } from 'keen-slider/react';
|
|
7
|
-
import 'keen-slider/keen-slider.min.css';
|
|
8
|
-
|
|
9
|
-
interface ProductVariant {
|
|
10
|
-
name: string;
|
|
11
|
-
price: string;
|
|
12
|
-
link: string;
|
|
13
|
-
image: string;
|
|
14
|
-
variant_id: string;
|
|
15
|
-
variant_tag_name: string;
|
|
16
|
-
option?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface AssistantMessageProps {
|
|
20
|
-
message: string;
|
|
21
|
-
colorCode: string;
|
|
22
|
-
isBusiness?: boolean;
|
|
23
|
-
handleAddToCart: (variantId: string, name: string,variantImage:string,price:string, qty?: number) => Promise<void>;
|
|
24
|
-
handleRemoveFromCart: (variantId: string, qty?: number) => Promise<void>;
|
|
25
|
-
onTryOnSelect: (product: any) => void; // Add this
|
|
26
|
-
enableTry:boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const SallaAsssiatnt: FC<AssistantMessageProps> = ({
|
|
30
|
-
message,
|
|
31
|
-
colorCode,
|
|
32
|
-
handleAddToCart,
|
|
33
|
-
handleRemoveFromCart,
|
|
34
|
-
onTryOnSelect,
|
|
35
|
-
enableTry
|
|
36
|
-
|
|
37
|
-
}) => {
|
|
38
|
-
const [counts, setCounts] = useState<Record<string, number>>({});
|
|
39
|
-
const [selectedVariants, setSelectedVariants] = useState<Record<string, string>>({});
|
|
40
|
-
|
|
41
|
-
const formatTextWithLinks = (text: string): React.ReactNode[] => {
|
|
42
|
-
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
43
|
-
return text.split(urlRegex).map((part, i) =>
|
|
44
|
-
urlRegex.test(part) ? (
|
|
45
|
-
<a
|
|
46
|
-
key={i}
|
|
47
|
-
href={part.trim()}
|
|
48
|
-
style={{ color: '#00b3bc' }}
|
|
49
|
-
target="_blank"
|
|
50
|
-
rel="noopener noreferrer"
|
|
51
|
-
className="underline break-words"
|
|
52
|
-
>
|
|
53
|
-
{part}
|
|
54
|
-
</a>
|
|
55
|
-
) : (
|
|
56
|
-
<span key={i}>{part}</span>
|
|
57
|
-
)
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const extractProductDetails = (text: string): ProductVariant | null => {
|
|
62
|
-
const normalized = text.trim();
|
|
63
|
-
if (!normalized.includes('Name:') || !normalized.includes('VariantId')) return null;
|
|
64
|
-
const nameMatch = normalized.match(/Name\s*[:\-]\s*(.+)/i);
|
|
65
|
-
const priceMatch = normalized.match(/Price\s*[:\-]\s*(.+)/i);
|
|
66
|
-
const linkMatch = normalized.match(/Link\s*[:\-]\s*(https?:\/\/[^\s]+)/i);
|
|
67
|
-
const variantMatch = normalized.match(/VariantId\s*[:\-]\s*(.+)/i);
|
|
68
|
-
const tagNameMatch = normalized.match(/variant_tag_name\s*[:\-]\s*(.+)/i);
|
|
69
|
-
const OptionMatch = normalized.match(/options\s*[:\-]\s*([^|\r\n]+)/i);
|
|
70
|
-
if (!nameMatch || !priceMatch || !linkMatch || !variantMatch || !tagNameMatch) return null;
|
|
71
|
-
return {
|
|
72
|
-
name: nameMatch[1].trim(),
|
|
73
|
-
price: priceMatch[1].trim(),
|
|
74
|
-
link: linkMatch[1].trim(),
|
|
75
|
-
image: '',
|
|
76
|
-
variant_id: variantMatch[1].trim(),
|
|
77
|
-
variant_tag_name: tagNameMatch[1].trim(),
|
|
78
|
-
option: OptionMatch?.[1]?.trim(),
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const parsedSegments = useMemo(() => {
|
|
83
|
-
const parts = message.split('|||').map(p => p.trim()).filter(Boolean);
|
|
84
|
-
const segments: { type: 'text' | 'product'; data: any }[] = [];
|
|
85
|
-
let lastProduct: ProductVariant | null = null;
|
|
86
|
-
|
|
87
|
-
parts.forEach(part => {
|
|
88
|
-
if (part.startsWith('img - ')) {
|
|
89
|
-
const url = part.replace(/^img\s*[-:]\s*/, '').trim();
|
|
90
|
-
if (lastProduct) lastProduct.image = url;
|
|
91
|
-
else {
|
|
92
|
-
const lastSeg = [...segments].reverse().find(s => s.type === 'product');
|
|
93
|
-
if (lastSeg) (lastSeg.data as ProductVariant).image = url;
|
|
94
|
-
}
|
|
95
|
-
} else if (part.includes('Name:') && part.includes('VariantId')) {
|
|
96
|
-
const product = extractProductDetails(part);
|
|
97
|
-
if (product) {
|
|
98
|
-
segments.push({ type: 'product', data: product });
|
|
99
|
-
lastProduct = product;
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
segments.push({ type: 'text', data: part });
|
|
103
|
-
lastProduct = null;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return segments;
|
|
108
|
-
}, [message]);
|
|
109
|
-
|
|
110
|
-
const groupedProducts = useMemo(() => {
|
|
111
|
-
const groups: Record<string, ProductVariant[]> = {};
|
|
112
|
-
parsedSegments.forEach(seg => {
|
|
113
|
-
if (seg.type === 'product') {
|
|
114
|
-
const p = seg.data as ProductVariant;
|
|
115
|
-
groups[p.variant_tag_name] = groups[p.variant_tag_name] || [];
|
|
116
|
-
groups[p.variant_tag_name].push(p);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
return groups;
|
|
120
|
-
}, [parsedSegments]);
|
|
121
|
-
|
|
122
|
-
const shortenName = (name: string, maxLength = 22) =>
|
|
123
|
-
name.length > maxLength ? name.slice(0, maxLength) + '...' : name;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const [currentSlide, setCurrentSlide] = useState(0);
|
|
128
|
-
const totalSlides =Object.keys(groupedProducts).length ;
|
|
129
|
-
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
|
|
130
|
-
loop: false,
|
|
131
|
-
mode: 'free',
|
|
132
|
-
slides: { perView: 1, spacing: 16 },
|
|
133
|
-
slideChanged(s) {
|
|
134
|
-
setCurrentSlide(s.track.details.rel);
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return (
|
|
140
|
-
<div className="space-y-6 mt-4 h-fit">
|
|
141
|
-
{parsedSegments
|
|
142
|
-
.filter(seg => seg.type === 'text')
|
|
143
|
-
.map((seg, i) => (
|
|
144
|
-
<p key={i} className="whitespace-pre-wrap break-words">
|
|
145
|
-
{formatTextWithLinks(seg.data)}
|
|
146
|
-
</p>
|
|
147
|
-
))}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{Object.keys(groupedProducts).length > 0 && (
|
|
152
|
-
<>
|
|
153
|
-
{Object.keys(groupedProducts).length > 1 && (
|
|
154
|
-
<div
|
|
155
|
-
style={{
|
|
156
|
-
display: 'flex',
|
|
157
|
-
margin: 0,
|
|
158
|
-
marginBottom: '6px',
|
|
159
|
-
justifyContent: 'space-between',
|
|
160
|
-
paddingInline: '4px',
|
|
161
|
-
}}
|
|
162
|
-
>
|
|
163
|
-
<Button
|
|
164
|
-
shape="circle"
|
|
165
|
-
icon={<ArrowLeftOutlined />}
|
|
166
|
-
onClick={() => slider.current?.prev()}
|
|
167
|
-
disabled={currentSlide === 0}
|
|
168
|
-
/>
|
|
169
|
-
<Button
|
|
170
|
-
shape="circle"
|
|
171
|
-
icon={<ArrowRightOutlined />}
|
|
172
|
-
onClick={() => slider.current?.next()}
|
|
173
|
-
disabled={currentSlide === totalSlides - 1}
|
|
174
|
-
/>
|
|
175
|
-
</div>
|
|
176
|
-
)}
|
|
177
|
-
<div ref={sliderRef} className="keen-slider">
|
|
178
|
-
<ZidProductCarousel
|
|
179
|
-
groupedProducts={groupedProducts}
|
|
180
|
-
selectedVariants={selectedVariants}
|
|
181
|
-
setSelectedVariants={setSelectedVariants}
|
|
182
|
-
counts={counts}
|
|
183
|
-
setCounts={setCounts}
|
|
184
|
-
handleAddToCart={handleAddToCart}
|
|
185
|
-
handleRemoveFromCart={handleRemoveFromCart}
|
|
186
|
-
colorCode={colorCode}
|
|
187
|
-
shortenName={shortenName}
|
|
188
|
-
sliderInstance={slider} // pass it down if needed
|
|
189
|
-
currentSlide={currentSlide}
|
|
190
|
-
totalSlides={totalSlides}
|
|
191
|
-
sliderRef={sliderRef}
|
|
192
|
-
onTryOnSelect={onTryOnSelect}
|
|
193
|
-
enableTry={enableTry}
|
|
194
|
-
|
|
195
|
-
/>
|
|
196
|
-
</div>
|
|
197
|
-
</>
|
|
198
|
-
)}
|
|
199
|
-
</div>
|
|
200
|
-
);
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export default SallaAsssiatnt;
|