@aslaluroba/help-center-react 3.0.21 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/image-attachment.d.ts +9 -0
- package/dist/components/ui/image-preview-dialog.d.ts +10 -0
- package/dist/components/ui/index.d.ts +4 -0
- package/dist/core/api.d.ts +3 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +5332 -843
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5332 -843
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +23 -0
- package/dist/services.esm.js +492 -361
- package/dist/services.esm.js.map +1 -1
- package/dist/services.js +492 -361
- package/dist/services.js.map +1 -1
- package/dist/ui/chatbot-popup/chat-window-screen/footer.d.ts +3 -2
- package/dist/ui/chatbot-popup/chat-window-screen/index.d.ts +3 -2
- package/dist/ui/help-center.d.ts +1 -1
- package/dist/ui/help-popup.d.ts +3 -2
- package/package.json +1 -1
- package/src/.DS_Store +0 -0
- package/src/assets/icons/paperclip.svg +3 -0
- package/src/assets/icons/x.svg +4 -0
- package/src/components/ui/image-attachment.tsx +107 -0
- package/src/components/ui/image-preview-dialog.tsx +354 -0
- package/src/components/ui/index.ts +4 -0
- package/src/core/AblyService.ts +6 -3
- package/src/core/ApiService.ts +0 -2
- package/src/core/api.ts +106 -58
- package/src/lib/types.ts +110 -84
- package/src/ui/chatbot-popup/chat-window-screen/footer.tsx +259 -22
- package/src/ui/chatbot-popup/chat-window-screen/index.tsx +206 -101
- package/src/ui/help-center.tsx +88 -92
- package/src/ui/help-popup.tsx +11 -9
- package/src/ui/powered-by.tsx +10 -9
package/src/ui/help-center.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import ReviewDialog from
|
|
2
|
-
import { useEffect, useState } from
|
|
3
|
-
import { apiRequest } from
|
|
4
|
-
import { ClientAblyService } from
|
|
5
|
-
import { useLocalTranslation } from
|
|
6
|
-
import
|
|
7
|
-
import { HelpScreenData, Message, Option, ReviewProps } from
|
|
8
|
-
import FloatingMessage from
|
|
9
|
-
import HelpButton from
|
|
10
|
-
import HelpPopup from
|
|
11
|
-
import { defaultLanguage } from
|
|
12
|
-
import { LanguageProvider } from
|
|
13
|
-
import { getThemeStyles } from
|
|
1
|
+
import ReviewDialog from '@/ui/review-dialog';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { apiRequest } from '../core/api';
|
|
4
|
+
import { ClientAblyService } from '../core/AblyService';
|
|
5
|
+
import { useLocalTranslation } from '../useLocalTranslation';
|
|
6
|
+
import '../globals.css';
|
|
7
|
+
import { HelpScreenData, Message, Option, ReviewProps } from '@/lib/types';
|
|
8
|
+
import FloatingMessage from './floating-message';
|
|
9
|
+
import HelpButton from './help-button';
|
|
10
|
+
import HelpPopup from './help-popup';
|
|
11
|
+
import { defaultLanguage } from '@/i18n';
|
|
12
|
+
import { LanguageProvider } from '@/lib/LanguageContext';
|
|
13
|
+
import { getThemeStyles } from '@/lib/theme-utils';
|
|
14
14
|
|
|
15
15
|
interface HelpCenterProps {
|
|
16
16
|
helpScreenId: string;
|
|
@@ -43,11 +43,9 @@ const HelpCenterContent = ({
|
|
|
43
43
|
const { t } = useLocalTranslation();
|
|
44
44
|
const [isOpen, setIsOpen] = useState(false);
|
|
45
45
|
const [showArrowAnimation, setShowArrowAnimation] = useState(showArrow);
|
|
46
|
-
const [helpScreenData, setHelpScreenData] = useState<HelpScreenData | null>(
|
|
47
|
-
|
|
48
|
-
);
|
|
49
|
-
const [status, setStatus] = useState("idle");
|
|
50
|
-
const [error, setError] = useState("");
|
|
46
|
+
const [helpScreenData, setHelpScreenData] = useState<HelpScreenData | null>(null);
|
|
47
|
+
const [status, setStatus] = useState('idle');
|
|
48
|
+
const [error, setError] = useState('');
|
|
51
49
|
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
|
52
50
|
|
|
53
51
|
const [sessionId, setSessionId] = useState<string | null>(null);
|
|
@@ -56,7 +54,7 @@ const HelpCenterContent = ({
|
|
|
56
54
|
const [isChatClosed, setIsChatClosed] = useState(false);
|
|
57
55
|
const [messages, setMessages] = useState<Message[]>([]);
|
|
58
56
|
const [needsAgent, setNeedsAgent] = useState(false);
|
|
59
|
-
const [assistantStatus, setAssistantStatus] = useState(
|
|
57
|
+
const [assistantStatus, setAssistantStatus] = useState('idle');
|
|
60
58
|
const [isReviewDialogOpen, setIsReviewDialogOpen] = useState(false);
|
|
61
59
|
|
|
62
60
|
const handleTogglePopup = () => {
|
|
@@ -72,24 +70,26 @@ const HelpCenterContent = ({
|
|
|
72
70
|
message: string,
|
|
73
71
|
senderType: number,
|
|
74
72
|
needsAgent: boolean,
|
|
73
|
+
attachments: string[] = []
|
|
75
74
|
) => {
|
|
76
75
|
if (needsAgent) {
|
|
77
76
|
setNeedsAgent(true);
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
setMessages((prevMessages) => {
|
|
81
|
-
const newMessage = {
|
|
80
|
+
const newMessage: Message = {
|
|
82
81
|
id: Date.now(),
|
|
83
82
|
senderType: senderType,
|
|
84
83
|
messageContent: message,
|
|
85
84
|
sentAt: new Date(),
|
|
86
85
|
isSeen: true,
|
|
86
|
+
...(attachments.length > 0 && { attachmentIds: attachments }),
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
return [...prevMessages, newMessage];
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
setAssistantStatus(
|
|
92
|
+
setAssistantStatus('idle');
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
const handleEndChat = async () => {
|
|
@@ -98,15 +98,12 @@ const HelpCenterContent = ({
|
|
|
98
98
|
try {
|
|
99
99
|
await ClientAblyService.stopConnection();
|
|
100
100
|
setIsAblyConnected(false);
|
|
101
|
-
setAssistantStatus(
|
|
101
|
+
setAssistantStatus('idle');
|
|
102
102
|
|
|
103
|
-
const response = await apiRequest(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{ language: language },
|
|
108
|
-
);
|
|
109
|
-
if (!response.ok) throw new Error("Failed to close chat session");
|
|
103
|
+
const response = await apiRequest(`Client/ClientChatSession/${sessionId}/close`, 'POST', null, {
|
|
104
|
+
language: language,
|
|
105
|
+
});
|
|
106
|
+
if (!response.ok) throw new Error('Failed to close chat session');
|
|
110
107
|
|
|
111
108
|
// Store sessionId for review before clearing the main sessionId
|
|
112
109
|
setReviewSessionId(sessionId);
|
|
@@ -118,9 +115,8 @@ const HelpCenterContent = ({
|
|
|
118
115
|
|
|
119
116
|
setIsReviewDialogOpen(true);
|
|
120
117
|
} catch (error) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
setAssistantStatus("idle");
|
|
118
|
+
setError('Failed to end chat session');
|
|
119
|
+
setAssistantStatus('idle');
|
|
124
120
|
// Even if there's an error, clear the session state to prevent stuck state
|
|
125
121
|
setReviewSessionId(sessionId);
|
|
126
122
|
setSessionId(null);
|
|
@@ -134,18 +130,14 @@ const HelpCenterContent = ({
|
|
|
134
130
|
const payload = { rating, comment };
|
|
135
131
|
|
|
136
132
|
try {
|
|
137
|
-
const response = await apiRequest(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
{ language },
|
|
142
|
-
);
|
|
143
|
-
if (!response.ok) throw new Error("Failed to send chat review");
|
|
133
|
+
const response = await apiRequest(`Client/ClientChatSession/${reviewSessionId}/review`, 'POST', payload, {
|
|
134
|
+
language,
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) throw new Error('Failed to send chat review');
|
|
144
137
|
|
|
145
138
|
handleCloseChatReview();
|
|
146
139
|
} catch (error) {
|
|
147
|
-
|
|
148
|
-
setError("Failed to send chat review");
|
|
140
|
+
setError('Failed to send chat review');
|
|
149
141
|
}
|
|
150
142
|
};
|
|
151
143
|
|
|
@@ -159,20 +151,19 @@ const HelpCenterContent = ({
|
|
|
159
151
|
{
|
|
160
152
|
id: Date.now(),
|
|
161
153
|
senderType: 3,
|
|
162
|
-
messageContent:
|
|
163
|
-
option?.assistant?.greeting || "مرحباً! كيف يمكنني مساعدتك اليوم؟",
|
|
154
|
+
messageContent: option?.assistant?.greeting || 'مرحباً! كيف يمكنني مساعدتك اليوم؟',
|
|
164
155
|
sentAt: new Date(),
|
|
165
156
|
isSeen: true,
|
|
166
157
|
},
|
|
167
158
|
]);
|
|
168
159
|
setIsChatClosed(false);
|
|
169
|
-
setStatus(
|
|
160
|
+
setStatus('succeeded');
|
|
170
161
|
};
|
|
171
162
|
|
|
172
163
|
const startNewChatSession = async (option: Option): Promise<string> => {
|
|
173
164
|
try {
|
|
174
|
-
setStatus(
|
|
175
|
-
setError(
|
|
165
|
+
setStatus('loading');
|
|
166
|
+
setError('');
|
|
176
167
|
|
|
177
168
|
const chatSessionCreateDto = {
|
|
178
169
|
helpScreenId: helpScreenId,
|
|
@@ -186,15 +177,12 @@ const HelpCenterContent = ({
|
|
|
186
177
|
}),
|
|
187
178
|
};
|
|
188
179
|
|
|
189
|
-
const response = await apiRequest(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
chatSessionCreateDto,
|
|
193
|
-
{ language },
|
|
194
|
-
);
|
|
180
|
+
const response = await apiRequest('Client/ClientChatSession/create-session', 'POST', chatSessionCreateDto, {
|
|
181
|
+
language,
|
|
182
|
+
});
|
|
195
183
|
|
|
196
184
|
if (!response.ok) {
|
|
197
|
-
throw new Error(
|
|
185
|
+
throw new Error('Failed to create chat session');
|
|
198
186
|
}
|
|
199
187
|
|
|
200
188
|
const responseData = await response.json();
|
|
@@ -206,39 +194,53 @@ const HelpCenterContent = ({
|
|
|
206
194
|
newSessionId,
|
|
207
195
|
responseData.ablyToken,
|
|
208
196
|
handleReceiveMessage,
|
|
209
|
-
responseData.chatSession.tenantId
|
|
197
|
+
responseData.chatSession.tenantId
|
|
210
198
|
);
|
|
211
199
|
|
|
212
200
|
// Verify the connection is actually active
|
|
213
201
|
if (!ClientAblyService.isConnectionActive()) {
|
|
214
|
-
throw new Error(
|
|
202
|
+
throw new Error('Ably connection failed to establish properly');
|
|
215
203
|
}
|
|
216
204
|
|
|
217
205
|
setIsAblyConnected(true);
|
|
218
206
|
setIsChatClosed(false);
|
|
219
|
-
setStatus(
|
|
207
|
+
setStatus('succeeded');
|
|
220
208
|
|
|
221
209
|
return newSessionId; // Return the session ID
|
|
222
210
|
} catch (error) {
|
|
223
|
-
setError(
|
|
224
|
-
|
|
225
|
-
);
|
|
226
|
-
setStatus("failed");
|
|
211
|
+
setError(error instanceof Error ? error.message : 'Failed to start chat session');
|
|
212
|
+
setStatus('failed');
|
|
227
213
|
throw error; // Re-throw to handle in calling function
|
|
228
214
|
}
|
|
229
215
|
};
|
|
230
216
|
|
|
231
|
-
const
|
|
232
|
-
|
|
217
|
+
const handleEnsureSession = async (): Promise<string> => {
|
|
218
|
+
// If we already have a session ID and connection, return it
|
|
219
|
+
if (sessionId && isAblyConnected) {
|
|
220
|
+
return sessionId;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// If we have a selected option but no session, create one
|
|
224
|
+
if (selectedOption) {
|
|
225
|
+
const newSessionId = await startNewChatSession(selectedOption);
|
|
226
|
+
return newSessionId;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
throw new Error('No option selected');
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const handleSendMessage = async (message: string, attachmentIds: string[] = []) => {
|
|
233
|
+
if (message.trim() !== '') {
|
|
233
234
|
try {
|
|
234
|
-
setAssistantStatus(
|
|
235
|
+
setAssistantStatus('typing');
|
|
235
236
|
|
|
236
|
-
const userMessage = {
|
|
237
|
+
const userMessage: Message = {
|
|
237
238
|
id: Date.now(),
|
|
238
239
|
senderType: 1,
|
|
239
240
|
messageContent: message,
|
|
240
241
|
sentAt: new Date(),
|
|
241
242
|
isSeen: false,
|
|
243
|
+
attachmentIds: attachmentIds.length > 0 ? attachmentIds : undefined,
|
|
242
244
|
};
|
|
243
245
|
|
|
244
246
|
setMessages((prevMessages) => [...prevMessages, userMessage]);
|
|
@@ -251,37 +253,36 @@ const HelpCenterContent = ({
|
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
if (!currentSessionId) {
|
|
254
|
-
throw new Error(
|
|
256
|
+
throw new Error('No active session available');
|
|
255
257
|
}
|
|
256
258
|
|
|
257
|
-
const messageDto = {
|
|
259
|
+
const messageDto = {
|
|
260
|
+
messageContent: message,
|
|
261
|
+
...(attachmentIds.length > 0 && { attachmentIds }),
|
|
262
|
+
};
|
|
263
|
+
|
|
258
264
|
const response = await apiRequest(
|
|
259
265
|
`Client/ClientChatSession/${currentSessionId}/send-message`,
|
|
260
|
-
|
|
266
|
+
'POST',
|
|
261
267
|
messageDto,
|
|
262
|
-
{ language }
|
|
268
|
+
{ language }
|
|
263
269
|
);
|
|
264
270
|
|
|
265
271
|
if (!response.ok) {
|
|
266
|
-
throw new Error(
|
|
272
|
+
throw new Error('Failed to send message');
|
|
267
273
|
}
|
|
268
274
|
|
|
269
275
|
setMessages((prevMessages) => {
|
|
270
|
-
return prevMessages.map((msg) =>
|
|
271
|
-
msg.senderType === 1 && !msg.isSeen
|
|
272
|
-
? { ...msg, isSeen: true }
|
|
273
|
-
: msg,
|
|
274
|
-
);
|
|
276
|
+
return prevMessages.map((msg) => (msg.senderType === 1 && !msg.isSeen ? { ...msg, isSeen: true } : msg));
|
|
275
277
|
});
|
|
276
278
|
} catch (error) {
|
|
277
|
-
|
|
278
|
-
setAssistantStatus("idle");
|
|
279
|
+
setAssistantStatus('idle');
|
|
279
280
|
|
|
280
|
-
const errorMessage = {
|
|
281
|
+
const errorMessage: Message = {
|
|
281
282
|
id: Date.now(),
|
|
282
283
|
senderType: 3,
|
|
283
284
|
messageContent:
|
|
284
|
-
|
|
285
|
+
'Failed to send the message. Please try again.\n لم يتم إرسال الرسالة. يرجى المحاولة مرة أخرى.',
|
|
285
286
|
sentAt: new Date(),
|
|
286
287
|
isSeen: true,
|
|
287
288
|
};
|
|
@@ -293,20 +294,20 @@ const HelpCenterContent = ({
|
|
|
293
294
|
|
|
294
295
|
useEffect(() => {
|
|
295
296
|
if (isOpen && helpScreenId) {
|
|
296
|
-
setStatus(
|
|
297
|
+
setStatus('loading');
|
|
297
298
|
|
|
298
|
-
apiRequest(`client/clientHelpScreen/${helpScreenId}`,
|
|
299
|
+
apiRequest(`client/clientHelpScreen/${helpScreenId}`, 'GET', null, {
|
|
299
300
|
language,
|
|
300
301
|
})
|
|
301
302
|
.then((res) => res.json())
|
|
302
303
|
.then((data) => {
|
|
303
304
|
setHelpScreenData(data);
|
|
304
|
-
setStatus(
|
|
305
|
-
setError(
|
|
305
|
+
setStatus('succeeded');
|
|
306
|
+
setError('');
|
|
306
307
|
})
|
|
307
308
|
.catch((err) => {
|
|
308
309
|
setError(err.message);
|
|
309
|
-
setStatus(
|
|
310
|
+
setStatus('failed');
|
|
310
311
|
});
|
|
311
312
|
}
|
|
312
313
|
}, [isOpen, helpScreenId]);
|
|
@@ -314,12 +315,9 @@ const HelpCenterContent = ({
|
|
|
314
315
|
const themeStyles = getThemeStyles({ primaryColor, secondaryColor });
|
|
315
316
|
|
|
316
317
|
return (
|
|
317
|
-
<div className=
|
|
318
|
+
<div className='babylai-help-center-container mb-4' style={themeStyles}>
|
|
318
319
|
{showArrowAnimation && !isOpen && (
|
|
319
|
-
<FloatingMessage
|
|
320
|
-
onClose={handleCloseArrowAnimation}
|
|
321
|
-
message={messageLabel || t("homeSdk.needAssistance")}
|
|
322
|
-
/>
|
|
320
|
+
<FloatingMessage onClose={handleCloseArrowAnimation} message={messageLabel || t('homeSdk.needAssistance')} />
|
|
323
321
|
)}
|
|
324
322
|
|
|
325
323
|
<HelpButton onClick={handleTogglePopup} />
|
|
@@ -334,6 +332,7 @@ const HelpCenterContent = ({
|
|
|
334
332
|
user={user}
|
|
335
333
|
onStartChat={handleStartChat}
|
|
336
334
|
onSendMessage={handleSendMessage}
|
|
335
|
+
onEnsureSession={handleEnsureSession}
|
|
337
336
|
onEndChat={handleEndChat}
|
|
338
337
|
messages={messages}
|
|
339
338
|
needsAgent={needsAgent}
|
|
@@ -348,10 +347,7 @@ const HelpCenterContent = ({
|
|
|
348
347
|
/>
|
|
349
348
|
)}
|
|
350
349
|
{isOpen && !!isReviewDialogOpen && reviewSessionId && (
|
|
351
|
-
<ReviewDialog
|
|
352
|
-
handleSubmit={handleSendChatReview}
|
|
353
|
-
onClose={handleCloseChatReview}
|
|
354
|
-
/>
|
|
350
|
+
<ReviewDialog handleSubmit={handleSendChatReview} onClose={handleCloseChatReview} />
|
|
355
351
|
)}
|
|
356
352
|
</div>
|
|
357
353
|
);
|
package/src/ui/help-popup.tsx
CHANGED
|
@@ -21,7 +21,8 @@ type HelpPopupProps = {
|
|
|
21
21
|
error: string | null;
|
|
22
22
|
user: any;
|
|
23
23
|
onStartChat: (option: Option) => void;
|
|
24
|
-
onSendMessage: (message: string) => void;
|
|
24
|
+
onSendMessage: (message: string, attachmentIds: string[]) => void;
|
|
25
|
+
onEnsureSession: () => Promise<string>;
|
|
25
26
|
onEndChat: (option?: Option) => void;
|
|
26
27
|
messages: Message[];
|
|
27
28
|
needsAgent: boolean;
|
|
@@ -42,6 +43,7 @@ const HelpPopup = ({
|
|
|
42
43
|
error,
|
|
43
44
|
onStartChat,
|
|
44
45
|
onSendMessage,
|
|
46
|
+
onEnsureSession,
|
|
45
47
|
onEndChat,
|
|
46
48
|
messages,
|
|
47
49
|
assistantStatus,
|
|
@@ -112,9 +114,9 @@ const HelpPopup = ({
|
|
|
112
114
|
);
|
|
113
115
|
|
|
114
116
|
const handleSendMessage = useCallback(
|
|
115
|
-
(message: string) => {
|
|
117
|
+
(message: string, attachmentIds: string[]) => {
|
|
116
118
|
if (message.trim()) {
|
|
117
|
-
onSendMessage(message.trim());
|
|
119
|
+
onSendMessage(message.trim(), attachmentIds);
|
|
118
120
|
}
|
|
119
121
|
},
|
|
120
122
|
[onSendMessage]
|
|
@@ -167,6 +169,7 @@ const HelpPopup = ({
|
|
|
167
169
|
/>
|
|
168
170
|
<ChatWindow
|
|
169
171
|
onSendMessage={handleSendMessage}
|
|
172
|
+
onEnsureSession={onEnsureSession}
|
|
170
173
|
messages={memoizedMessages}
|
|
171
174
|
assistantStatus={assistantStatus}
|
|
172
175
|
needsAgent={needsAgent}
|
|
@@ -188,11 +191,7 @@ const HelpPopup = ({
|
|
|
188
191
|
/>
|
|
189
192
|
);
|
|
190
193
|
}
|
|
191
|
-
return <HomeScreen
|
|
192
|
-
setIsShowList={setIsShowList}
|
|
193
|
-
onClose={onClose}
|
|
194
|
-
logoUrl={logoUrl}
|
|
195
|
-
/>;
|
|
194
|
+
return <HomeScreen setIsShowList={setIsShowList} onClose={onClose} logoUrl={logoUrl} />;
|
|
196
195
|
}, [
|
|
197
196
|
showChat,
|
|
198
197
|
selectedOption,
|
|
@@ -202,6 +201,7 @@ const HelpPopup = ({
|
|
|
202
201
|
isShowList,
|
|
203
202
|
setIsShowList,
|
|
204
203
|
handleSendMessage,
|
|
204
|
+
onEnsureSession,
|
|
205
205
|
memoizedMessages,
|
|
206
206
|
assistantStatus,
|
|
207
207
|
needsAgent,
|
|
@@ -210,6 +210,8 @@ const HelpPopup = ({
|
|
|
210
210
|
setExpandedOption,
|
|
211
211
|
handleStartChat,
|
|
212
212
|
showHelpScreen,
|
|
213
|
+
isAblyConnected,
|
|
214
|
+
logoUrl,
|
|
213
215
|
]);
|
|
214
216
|
|
|
215
217
|
// Memoize confirmation modal
|
|
@@ -311,6 +313,6 @@ md:babylai-bottom-[6rem] md:babylai-right-4 babylai-rounded-none md:babylai-roun
|
|
|
311
313
|
</div>
|
|
312
314
|
</div>
|
|
313
315
|
);
|
|
314
|
-
}
|
|
316
|
+
};
|
|
315
317
|
|
|
316
318
|
export default HelpPopup;
|
package/src/ui/powered-by.tsx
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { useLocalTranslation } from
|
|
1
|
+
import { useLocalTranslation } from '@/useLocalTranslation';
|
|
2
2
|
|
|
3
3
|
const PoweredBy: React.FC = () => {
|
|
4
4
|
const { t } = useLocalTranslation();
|
|
5
5
|
|
|
6
6
|
return (
|
|
7
|
-
<section className=
|
|
7
|
+
<section className='dark:babylai-text-white babylai-font-bold babylai-text-center babylai-px-8 babylai-py-2 babylai-w-full'>
|
|
8
8
|
<a
|
|
9
|
-
href=
|
|
10
|
-
target=
|
|
11
|
-
rel=
|
|
12
|
-
className=
|
|
9
|
+
href='https://www.babylai.net/'
|
|
10
|
+
target='_blank'
|
|
11
|
+
rel='noopener noreferrer'
|
|
12
|
+
className='babylai-text-xs babylai-opacity-60 hover:babylai-opacity-100 babylai-transition-all'
|
|
13
|
+
>
|
|
13
14
|
{t('homeSdk.poweredBy')} BabylAI © 2025
|
|
14
15
|
</a>
|
|
15
16
|
</section>
|
|
16
|
-
)
|
|
17
|
-
}
|
|
17
|
+
);
|
|
18
|
+
};
|
|
18
19
|
|
|
19
|
-
export default PoweredBy
|
|
20
|
+
export default PoweredBy;
|