shopify-chatbot-widget 0.7.9 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jaweb-chatbot.css +1 -1
- package/dist/jaweb-chatbot.iife.js +3 -3
- package/package.json +1 -1
- package/src/App.css +42 -0
- package/src/App.tsx +13 -0
- package/src/Chatbot/Chatbot.css +270 -0
- package/src/Chatbot/Chatbot.tsx +214 -0
- package/src/Chatbot/ChatbotTransition.css +19 -0
- package/src/Chatbot/OLDCHAT.tsx +259 -0
- package/src/Chatbot/components/ChatInput.css +127 -0
- package/src/Chatbot/components/ChatInput.tsx +354 -0
- package/src/Chatbot/components/Messages/Addcart.tsx +70 -0
- package/src/Chatbot/components/Messages/AgentStatus.tsx +37 -0
- package/src/Chatbot/components/Messages/AssistantMesage.tsx +206 -0
- package/src/Chatbot/components/Messages/AudioMessage.tsx +123 -0
- package/src/Chatbot/components/Messages/CalendlyEmbeds.tsx +66 -0
- package/src/Chatbot/components/Messages/CardSwiper.tsx +194 -0
- package/src/Chatbot/components/Messages/Carousel/CardSwiper.tsx +264 -0
- package/src/Chatbot/components/Messages/Carousel/CardSwiperSalla.tsx +208 -0
- package/src/Chatbot/components/Messages/Carousel/CardSwiperZid.tsx +208 -0
- package/src/Chatbot/components/Messages/Carousel/SallaSwiper.css +245 -0
- package/src/Chatbot/components/Messages/Carousel/TryOn.tsx +111 -0
- package/src/Chatbot/components/Messages/CartWidget.tsx +151 -0
- package/src/Chatbot/components/Messages/ChatImage.tsx +46 -0
- package/src/Chatbot/components/Messages/ChatImageText.tsx +74 -0
- package/src/Chatbot/components/Messages/ChatImageTextAssis.tsx +72 -0
- package/src/Chatbot/components/Messages/ChatMessages.css +31 -0
- package/src/Chatbot/components/Messages/ChatMessages.tsx +334 -0
- package/src/Chatbot/components/Messages/ProductCard.css +149 -0
- package/src/Chatbot/components/Messages/SallaAssistantMessage.tsx +196 -0
- package/src/Chatbot/components/Messages/Support.tsx +177 -0
- package/src/Chatbot/components/Messages/Typing.css +31 -0
- package/src/Chatbot/components/Messages/Typing.tsx +19 -0
- package/src/Chatbot/components/Messages/ZidAssistantMesage.tsx +196 -0
- package/src/Chatbot/components/Messages/cartwidget.css +123 -0
- package/src/Chatbot/components/Messenger/Messenger.tsx +531 -0
- package/src/Chatbot/components/Notification.tsx +28 -0
- package/src/Chatbot/components/Powered.css +29 -0
- package/src/Chatbot/components/Powered.tsx +12 -0
- package/src/Chatbot/components/Sessions/CreateSession.tsx +201 -0
- package/src/Chatbot/components/Sessions/RenderList.tsx +212 -0
- package/src/Chatbot/components/Suggestions.css +35 -0
- package/src/Chatbot/components/Suggestions.tsx +57 -0
- package/src/Chatbot/notification.css +17 -0
- package/src/assets/react.svg +1 -0
- package/src/chatbot-widget/index.tsx +14 -0
- package/src/hooks/config.tsx +13 -0
- package/src/hooks/useCart.tsx +107 -0
- package/src/hooks/useChatbotAPI.tsx +167 -0
- package/src/hooks/useChatbotData.tsx +132 -0
- package/src/hooks/useSessionMessages.tsx +50 -0
- package/src/hooks/useWebsocke.tsx +45 -0
- package/src/i18n.tsx +30 -0
- package/src/index.css +2 -0
- package/src/main.tsx +10 -0
- package/src/types/chatbot.ts +40 -0
- package/src/utils/cookies.tsx +14 -0
- package/src/vite-env.d.ts +1 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import config from './config';
|
|
3
|
+
|
|
4
|
+
interface Params {
|
|
5
|
+
disableChatbot: boolean;
|
|
6
|
+
disableChatbotGlobally: boolean;
|
|
7
|
+
isChatlogCreated: boolean;
|
|
8
|
+
createNew: boolean;
|
|
9
|
+
disableForm: boolean;
|
|
10
|
+
calendlyLink: string | null;
|
|
11
|
+
socket: WebSocket | null;
|
|
12
|
+
newSession:Boolean;
|
|
13
|
+
setNewSession: (v: boolean) => void;
|
|
14
|
+
setMessages: React.Dispatch<React.SetStateAction<any[]>>;
|
|
15
|
+
setIsChatlogCreated: (v: boolean) => void;
|
|
16
|
+
setChatLogWaiting: (v: boolean) => void;
|
|
17
|
+
setNewUser: (v: boolean) => void;
|
|
18
|
+
setCreateNew: (v: boolean) => void;
|
|
19
|
+
setSessionCreated: (v: boolean) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const useChatbotAPI = (params: Params) => {
|
|
23
|
+
const {
|
|
24
|
+
disableChatbot,
|
|
25
|
+
disableChatbotGlobally,
|
|
26
|
+
isChatlogCreated,
|
|
27
|
+
createNew,
|
|
28
|
+
disableForm,
|
|
29
|
+
calendlyLink,
|
|
30
|
+
socket,
|
|
31
|
+
newSession,
|
|
32
|
+
setNewSession,
|
|
33
|
+
setMessages,
|
|
34
|
+
} = params;
|
|
35
|
+
|
|
36
|
+
const apiCall = useCallback(
|
|
37
|
+
async (
|
|
38
|
+
userMessage: string,
|
|
39
|
+
newSession:boolean,
|
|
40
|
+
sessionId: string,
|
|
41
|
+
finalImageUrl?: string,
|
|
42
|
+
isImage?: boolean
|
|
43
|
+
) => {
|
|
44
|
+
if (newSession) {
|
|
45
|
+
setMessages((prev) => [
|
|
46
|
+
...prev,
|
|
47
|
+
{ role: 'assistant', content: 'typing', typing: true },
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
await fetch(`${config.apiUrl}chatlog-create/`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: { 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify({ visitor_id: localStorage.getItem('visitor_id') , company_username: localStorage.getItem('company_username'),session_id:sessionId}),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
setNewSession(false)
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!disableChatbot && !disableChatbotGlobally) {
|
|
61
|
+
setMessages((prev) => {
|
|
62
|
+
const withoutTyping = prev.filter((msg) => !msg.typing);
|
|
63
|
+
return [...withoutTyping, { role: 'assistant', content: 'typing', typing: true }];
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const res = await fetch(`${config.apiUrl}message-create/`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: { 'Content-Type': 'application/json' },
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
message: userMessage,
|
|
74
|
+
isBusiness: true,
|
|
75
|
+
session_id: sessionId,
|
|
76
|
+
organization: localStorage.getItem('company_username'),
|
|
77
|
+
isImage,
|
|
78
|
+
image_url: finalImageUrl,
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (res.ok) {
|
|
83
|
+
const data = await res.json();
|
|
84
|
+
|
|
85
|
+
if (data.message_history) {
|
|
86
|
+
const assistantMessage = data.isConnect
|
|
87
|
+
? {
|
|
88
|
+
role: 'assistant',
|
|
89
|
+
content: 'Your support request is on its way—please stand by!',
|
|
90
|
+
isConnect: true,
|
|
91
|
+
sender: 'Ai Agent',
|
|
92
|
+
isBusiness: false,
|
|
93
|
+
isHtml: data.isHtml,
|
|
94
|
+
}
|
|
95
|
+
: {
|
|
96
|
+
role: 'assistant',
|
|
97
|
+
content: data.message,
|
|
98
|
+
sender: 'Ai Agent',
|
|
99
|
+
isBusiness: false,
|
|
100
|
+
isHtml: data.isHtml,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Send message through WebSocket if available
|
|
104
|
+
if (socket?.readyState === WebSocket.OPEN) {
|
|
105
|
+
socket.send(
|
|
106
|
+
JSON.stringify({
|
|
107
|
+
message: data.message,
|
|
108
|
+
additionalData: {
|
|
109
|
+
isBusiness: false,
|
|
110
|
+
SessionId: sessionId,
|
|
111
|
+
sender: 'AI',
|
|
112
|
+
response: 'from_ai_web',
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
// Update messages safely
|
|
120
|
+
setMessages((prev) => {
|
|
121
|
+
const filtered = prev.filter((msg) => !msg.typing);
|
|
122
|
+
const updated = [...filtered, assistantMessage];
|
|
123
|
+
|
|
124
|
+
console.log(calendlyLink)
|
|
125
|
+
// Add Calendly message if applicable
|
|
126
|
+
if (
|
|
127
|
+
data.message &&
|
|
128
|
+
calendlyLink &&
|
|
129
|
+
/book\s?(a\s?)?meeting|schedule\s?(a\s?)?(call|meeting)|let\s?('s)?\s?meet|set\s?up\s?(a\s?)?meeting|book\s?(an\s?)?appointment/i.test(
|
|
130
|
+
data.message
|
|
131
|
+
)
|
|
132
|
+
) {
|
|
133
|
+
console.log("meeting please")
|
|
134
|
+
updated.push({
|
|
135
|
+
role: 'assistant',
|
|
136
|
+
content: 'Scheduling a meeting...',
|
|
137
|
+
isBusiness: false,
|
|
138
|
+
calendly: true,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return updated;
|
|
143
|
+
});
|
|
144
|
+
} else if (data.status === 'success') {
|
|
145
|
+
setMessages((prev) => prev.filter((msg) => !msg.typing));
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
console.error('message-create failed');
|
|
149
|
+
}
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error('Message error:', error);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
[
|
|
155
|
+
disableChatbot,
|
|
156
|
+
disableChatbotGlobally,
|
|
157
|
+
isChatlogCreated,
|
|
158
|
+
createNew,
|
|
159
|
+
disableForm,
|
|
160
|
+
calendlyLink,
|
|
161
|
+
socket,
|
|
162
|
+
newSession,
|
|
163
|
+
]
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
return { apiCall };
|
|
167
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// hooks/useChatbotData.ts
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import config from './config';
|
|
5
|
+
import i18n from '../i18n';
|
|
6
|
+
import type { ChatbotDetailsResponse, SuggestionResponse } from '../types/chatbot';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const MAX_RETRIES = 3;
|
|
10
|
+
const RETRY_DELAY = 3000;
|
|
11
|
+
|
|
12
|
+
export const useChatbotData = () => {
|
|
13
|
+
|
|
14
|
+
const [isFetchingDetails, setIsFetchingDetails] = useState(true);
|
|
15
|
+
const [disableForm, setDisableForm] = useState(false);
|
|
16
|
+
const [colorCode, setColorCode] = useState('');
|
|
17
|
+
const [chatbotLogo, setChatbotLogo] = useState('');
|
|
18
|
+
const [disableChatbotGlobally, setDisableChatbotGlobally] = useState(false);
|
|
19
|
+
const [removePoweredByJaweb, setRemovePoweredByJaweb] = useState(false);
|
|
20
|
+
const [initialMessageText, setInitialMessageText] = useState('');
|
|
21
|
+
const [subscription, setSubscription] = useState('');
|
|
22
|
+
const [calendly, setCalendly] = useState<string | null>(null);
|
|
23
|
+
const [merchantPhone, setMerchantPhone] = useState('');
|
|
24
|
+
const [messagesSuggestions, setMessagesSuggestions] = useState<string[]>([]);
|
|
25
|
+
const [restSuggestions, setRestSuggestions] = useState<string[]>([]);
|
|
26
|
+
const [userType,setUserType]=useState('')
|
|
27
|
+
const [disbleCheckout, setDisbleCheckout] = useState(false);
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const fetchData = async (retryCount = 0) => {
|
|
31
|
+
const company_name = localStorage.getItem('company_username');
|
|
32
|
+
setIsFetchingDetails(true);
|
|
33
|
+
|
|
34
|
+
const configObj = {
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
Accept: 'application/json',
|
|
38
|
+
},
|
|
39
|
+
params: {
|
|
40
|
+
username: company_name,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const chatbotDetailsResponse = await axios.get<ChatbotDetailsResponse>(
|
|
46
|
+
`${config.apiUrl}chatbot-details/`,
|
|
47
|
+
configObj
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const data = chatbotDetailsResponse.data.data;
|
|
51
|
+
|
|
52
|
+
if (data.language === 'Arabic') {
|
|
53
|
+
i18n.changeLanguage('ar');
|
|
54
|
+
} else {
|
|
55
|
+
i18n.changeLanguage('en');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
setDisableForm(data.chatbot_form);
|
|
61
|
+
setColorCode(data.chatbot_color);
|
|
62
|
+
setChatbotLogo(data.chatbot_logo);
|
|
63
|
+
setDisableChatbotGlobally(data.disable_chatbot_globally);
|
|
64
|
+
setRemovePoweredByJaweb(data.remove_powered_by_jaweb);
|
|
65
|
+
setInitialMessageText(data.chatbot_initial_msg);
|
|
66
|
+
setSubscription(data.status);
|
|
67
|
+
setUserType(data.mode)
|
|
68
|
+
setCalendly(data.calendly_link ?? null);
|
|
69
|
+
setDisbleCheckout(data.disable_checkout)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if (data.calendly_link) setCalendly(data.calendly_link);
|
|
74
|
+
if (data.phone_number_id) setMerchantPhone(`+${data.phone_number_id}`);
|
|
75
|
+
|
|
76
|
+
const suggestionsResponse = await axios.get<SuggestionResponse>(
|
|
77
|
+
`${config.apiUrl}chatbot-plugin-suggestions/`,
|
|
78
|
+
configObj
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
// 💡 Safe fallback logic
|
|
83
|
+
let suggestions: string[] = [];
|
|
84
|
+
|
|
85
|
+
if (Array.isArray(suggestionsResponse.data.data)) {
|
|
86
|
+
suggestions = suggestionsResponse.data.data;
|
|
87
|
+
} else if (Array.isArray((suggestionsResponse.data as any).user_questions)) {
|
|
88
|
+
suggestions = (suggestionsResponse.data as any).user_questions;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (suggestions.length > 0) {
|
|
92
|
+
setMessagesSuggestions(suggestions.slice(0, 3));
|
|
93
|
+
setRestSuggestions(suggestions.slice(3));
|
|
94
|
+
} else {
|
|
95
|
+
setMessagesSuggestions([]);
|
|
96
|
+
setRestSuggestions([]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setIsFetchingDetails(false);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('Error fetching data:', error);
|
|
102
|
+
if (retryCount < MAX_RETRIES) {
|
|
103
|
+
setTimeout(() => fetchData(retryCount + 1), RETRY_DELAY);
|
|
104
|
+
} else {
|
|
105
|
+
console.error('Max retries reached. Could not fetch data.');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
fetchData();
|
|
114
|
+
}, []);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
isFetchingDetails,
|
|
118
|
+
disableForm,
|
|
119
|
+
colorCode,
|
|
120
|
+
chatbotLogo,
|
|
121
|
+
disableChatbotGlobally,
|
|
122
|
+
removePoweredByJaweb,
|
|
123
|
+
initialMessageText,
|
|
124
|
+
subscription,
|
|
125
|
+
calendly,
|
|
126
|
+
merchantPhone,
|
|
127
|
+
messagesSuggestions,
|
|
128
|
+
restSuggestions,
|
|
129
|
+
userType,
|
|
130
|
+
disbleCheckout
|
|
131
|
+
};
|
|
132
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import config from './config';
|
|
4
|
+
import type { ChatMessage } from '../types/chatbot';
|
|
5
|
+
|
|
6
|
+
export const useChatbotMessage = (sessionId: string | null) => {
|
|
7
|
+
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
|
8
|
+
const [isFetchingMessages, setisFetchingMessages] = useState(false);
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const loadHistory = async () => {
|
|
12
|
+
const sid = sessionId
|
|
13
|
+
if (!sid) return;
|
|
14
|
+
|
|
15
|
+
setisFetchingMessages(true);
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const res = await axios.get<{ messages: ChatMessage[] }>(
|
|
20
|
+
`${config.apiUrl}chat-message-history/`,
|
|
21
|
+
{
|
|
22
|
+
withCredentials: true,
|
|
23
|
+
params: {
|
|
24
|
+
session_id: sid,
|
|
25
|
+
username: localStorage.getItem('company_username'),
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if (res.data?.messages?.length > 0) {
|
|
32
|
+
setMessages(res.data.messages);
|
|
33
|
+
setisFetchingMessages(false)
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error("Couldn't load history", err);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
loadHistory();
|
|
43
|
+
}, [sessionId]);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
messages,
|
|
47
|
+
setMessages,
|
|
48
|
+
isFetchingMessages
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// hooks/useChatSocket.ts
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import config from './config';
|
|
4
|
+
|
|
5
|
+
export default function useChatSocket(
|
|
6
|
+
session_id: string,
|
|
7
|
+
onMessage: (data: any) => void
|
|
8
|
+
) {
|
|
9
|
+
const socketRef = useRef<WebSocket | null>(null);
|
|
10
|
+
// keep a stable ref to the latest onMessage
|
|
11
|
+
const onMessageRef = useRef(onMessage);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
onMessageRef.current = onMessage;
|
|
14
|
+
}, [onMessage]);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!session_id) return;
|
|
18
|
+
|
|
19
|
+
const ws = new WebSocket(`${config.websocketUrl}/chat/${session_id}/`);
|
|
20
|
+
socketRef.current = ws;
|
|
21
|
+
|
|
22
|
+
// precise add/remove so we never leak handlers
|
|
23
|
+
const handle = (event: MessageEvent) => {
|
|
24
|
+
try {
|
|
25
|
+
const data = JSON.parse(event.data);
|
|
26
|
+
onMessageRef.current(data);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error('Invalid JSON', e);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
ws.addEventListener('message', handle);
|
|
32
|
+
|
|
33
|
+
// you can still do onopen/onclose, but tear them down too if you attach them
|
|
34
|
+
const handleClose = () => { /* reconnect logic… */ };
|
|
35
|
+
ws.addEventListener('close', handleClose);
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
ws.removeEventListener('message', handle);
|
|
39
|
+
ws.removeEventListener('close', handleClose);
|
|
40
|
+
ws.close();
|
|
41
|
+
};
|
|
42
|
+
}, [session_id]);
|
|
43
|
+
|
|
44
|
+
return socketRef.current;
|
|
45
|
+
}
|
package/src/i18n.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/i18n.ts
|
|
2
|
+
import i18n from 'i18next';
|
|
3
|
+
import { initReactI18next } from 'react-i18next';
|
|
4
|
+
|
|
5
|
+
const resources = {
|
|
6
|
+
en: {
|
|
7
|
+
translation: {
|
|
8
|
+
welcome: "Hi there, you’re speaking with Jaweb AI Assistant.",
|
|
9
|
+
// Add more English translations here
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
ar: {
|
|
13
|
+
translation: {
|
|
14
|
+
welcome: "مرحبًا، أنت تتحدث إلى مساعد Jaweb AI.",
|
|
15
|
+
// Add more Arabic translations here
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
i18n.use(initReactI18next).init({
|
|
21
|
+
resources,
|
|
22
|
+
lng: 'en', // default language
|
|
23
|
+
fallbackLng: 'en',
|
|
24
|
+
|
|
25
|
+
interpolation: {
|
|
26
|
+
escapeValue: false, // React already escapes
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default i18n;
|
package/src/index.css
ADDED
package/src/main.tsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// types/chatbot.ts
|
|
2
|
+
|
|
3
|
+
export interface ChatbotDetailsResponse {
|
|
4
|
+
data: {
|
|
5
|
+
language: string;
|
|
6
|
+
chatbot_form: boolean;
|
|
7
|
+
chatbot_color: string;
|
|
8
|
+
chatbot_logo: string;
|
|
9
|
+
disable_chatbot_globally: boolean;
|
|
10
|
+
remove_powered_by_jaweb: boolean;
|
|
11
|
+
chatbot_initial_msg: string;
|
|
12
|
+
status: string;
|
|
13
|
+
calendly_link?: string | null;
|
|
14
|
+
phone_number_id?: string | null;
|
|
15
|
+
mode:string;
|
|
16
|
+
disable_checkout:boolean;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SuggestionResponse {
|
|
21
|
+
data?: string[]; // when data is returned directly
|
|
22
|
+
user_questions?: string[] | null; // when API sends it here
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export interface ChatMessage {
|
|
27
|
+
role?: 'user' | 'bot' | 'assistant' | 'system';
|
|
28
|
+
content?:string;
|
|
29
|
+
isBusiness?:boolean;
|
|
30
|
+
sender?:string;
|
|
31
|
+
typing?: boolean;
|
|
32
|
+
id?:Number;
|
|
33
|
+
image_url?:string;
|
|
34
|
+
status?:string;
|
|
35
|
+
audio_url?: string;
|
|
36
|
+
isConnect?:boolean;
|
|
37
|
+
calendly?:boolean;
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// utils/cookies.ts
|
|
2
|
+
import Cookies from 'js-cookie';
|
|
3
|
+
|
|
4
|
+
export const getCookie = (key: string): string | undefined => {
|
|
5
|
+
return Cookies.get(key);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const setCookie = (key: string, value: string, days = 30): void => {
|
|
9
|
+
Cookies.set(key, value, { expires: days });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const removeCookie = (key: string): void => {
|
|
13
|
+
Cookies.remove(key);
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|