goji-search 1.0.1 → 1.1.0
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/goji-search/components/elements/action-buttons.d.ts +2 -1
- package/dist/goji-search/components/elements/action-buttons.js +52 -19
- package/dist/goji-search/components/elements/auto-expanding-textarea.d.ts +8 -0
- package/dist/goji-search/components/elements/auto-expanding-textarea.js +36 -0
- package/dist/goji-search/components/elements/inspiration-menu.js +17 -17
- package/dist/goji-search/components/elements/message-list.d.ts +1 -3
- package/dist/goji-search/components/elements/message-list.js +81 -103
- package/dist/goji-search/components/elements/search-input.d.ts +2 -2
- package/dist/goji-search/components/elements/search-input.js +37 -33
- package/dist/goji-search/components/elements/suggested-questions.js +1 -1
- package/dist/goji-search/components/goji-search-component.d.ts +9 -1
- package/dist/goji-search/components/goji-search-component.js +295 -105
- package/dist/goji-search/config/company.d.ts +0 -1
- package/dist/goji-search/config/company.js +34 -7
- package/dist/goji-search/lib/goji-client.d.ts +39 -0
- package/dist/goji-search/lib/goji-client.js +55 -2
- package/dist/goji-search.css +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import "./goji-search.css";
|
|
3
3
|
import { ArrowLeft, X, Maximize2, Minimize2 } from "lucide-react";
|
|
4
|
-
import { useState, useEffect, useRef, useId } from "react";
|
|
4
|
+
import { useState, useEffect, useRef, useId, useMemo } from "react";
|
|
5
5
|
import { SuggestedQuestions } from "./elements/suggested-questions";
|
|
6
6
|
import { MessageList } from "./elements/message-list";
|
|
7
|
+
import chatLogo from "../assets/chat-logo.png";
|
|
7
8
|
import { SearchInput } from "./elements/search-input";
|
|
8
9
|
import { ActionButtons } from "./elements/action-buttons";
|
|
9
10
|
import CalendarIntegration from "./elements/calendar-integration";
|
|
10
|
-
import {
|
|
11
|
+
import { createGojiClient } from "../lib/goji-client";
|
|
11
12
|
import { companyConfig } from "../config/company";
|
|
12
|
-
export function GojiSearchComponent() {
|
|
13
|
+
export function GojiSearchComponent({ apiUrl } = {}) {
|
|
14
|
+
// Create client instance based on provided API URL
|
|
15
|
+
const client = useMemo(() => createGojiClient(apiUrl), [apiUrl]);
|
|
13
16
|
const [searchQuery, setSearchQuery] = useState("");
|
|
14
17
|
const [size, setSize] = useState("xs");
|
|
15
18
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -22,13 +25,20 @@ export function GojiSearchComponent() {
|
|
|
22
25
|
const inputRef = useRef(null);
|
|
23
26
|
const sparkleRef = useRef(null);
|
|
24
27
|
const streamingCancelRef = useRef(null);
|
|
28
|
+
const mediaRecorderRef = useRef(null);
|
|
29
|
+
const audioChunksRef = useRef([]);
|
|
25
30
|
const [isInputHovered, setIsInputHovered] = useState(false);
|
|
26
31
|
const [hoverTopExpand, setHoverTopExpand] = useState(false);
|
|
27
32
|
const [hoverTopClose, setHoverTopClose] = useState(false);
|
|
28
|
-
const
|
|
33
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
34
|
+
const [backendSuggestedQuestions, setBackendSuggestedQuestions] = useState(null);
|
|
35
|
+
// Language selection state - will be set from backend default
|
|
36
|
+
const [selectedLanguage, setSelectedLanguage] = useState('en');
|
|
37
|
+
const [showLanguageMenu, setShowLanguageMenu] = useState(false);
|
|
38
|
+
const currentLanguage = selectedLanguage;
|
|
29
39
|
const languageConfig = companyConfig.languages[currentLanguage];
|
|
30
|
-
|
|
31
|
-
const inspirationQuestions =
|
|
40
|
+
// Use backend-provided questions only (no hardcoded prompts)
|
|
41
|
+
const inspirationQuestions = backendSuggestedQuestions || [];
|
|
32
42
|
const idBase = useId();
|
|
33
43
|
const xTooltipId = `${idBase}-x-tip`;
|
|
34
44
|
const expandTooltipId = `${idBase}-expand-tip`;
|
|
@@ -38,22 +48,83 @@ export function GojiSearchComponent() {
|
|
|
38
48
|
}, 4000);
|
|
39
49
|
return () => clearTimeout(timer);
|
|
40
50
|
}, []);
|
|
51
|
+
// Close language menu when clicking outside
|
|
41
52
|
useEffect(() => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
if (!showLanguageMenu)
|
|
54
|
+
return;
|
|
55
|
+
const handleClickOutside = (e) => {
|
|
56
|
+
const target = e.target;
|
|
57
|
+
if (!target.closest('[data-language-menu]')) {
|
|
58
|
+
setShowLanguageMenu(false);
|
|
45
59
|
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
};
|
|
61
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
62
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
63
|
+
}, [showLanguageMenu]);
|
|
64
|
+
// Language change handler with persistence
|
|
65
|
+
const handleLanguageChange = (lang) => {
|
|
66
|
+
setSelectedLanguage(lang);
|
|
67
|
+
setShowLanguageMenu(false);
|
|
68
|
+
// Persist to localStorage
|
|
69
|
+
if (typeof window !== 'undefined') {
|
|
70
|
+
localStorage.setItem('goji-language', lang);
|
|
71
|
+
}
|
|
72
|
+
// Reload suggestions for new language
|
|
73
|
+
client.getSuggestions({ language: lang })
|
|
74
|
+
.then(res => {
|
|
75
|
+
if (Array.isArray(res?.suggestions) && res.suggestions.length > 0) {
|
|
76
|
+
setBackendSuggestedQuestions(res.suggestions);
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.catch(e => console.error("Failed to fetch suggestions", e));
|
|
80
|
+
};
|
|
49
81
|
useEffect(() => {
|
|
82
|
+
// Load initial suggestions and default language from backend on mount (ONLY ONCE)
|
|
83
|
+
(async () => {
|
|
84
|
+
try {
|
|
85
|
+
// Fetch suggestions with initial language (en)
|
|
86
|
+
const res = await client.getSuggestions({ language: 'en' });
|
|
87
|
+
// Check if backend provides a different default language
|
|
88
|
+
if (res?.default_language && typeof res.default_language === 'string') {
|
|
89
|
+
const backendDefaultLang = res.default_language.toLowerCase().trim();
|
|
90
|
+
// Validate it's a supported language
|
|
91
|
+
if (companyConfig.languages[backendDefaultLang]) {
|
|
92
|
+
// Set the language FIRST
|
|
93
|
+
setSelectedLanguage(backendDefaultLang);
|
|
94
|
+
// Then fetch suggestions for the correct language
|
|
95
|
+
if (backendDefaultLang !== 'en') {
|
|
96
|
+
const langRes = await client.getSuggestions({ language: backendDefaultLang });
|
|
97
|
+
if (Array.isArray(langRes?.suggestions) && langRes.suggestions.length > 0) {
|
|
98
|
+
setBackendSuggestedQuestions(langRes.suggestions);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Use English suggestions
|
|
103
|
+
if (Array.isArray(res?.suggestions) && res.suggestions.length > 0) {
|
|
104
|
+
setBackendSuggestedQuestions(res.suggestions);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// No default language override, use English suggestions
|
|
111
|
+
if (Array.isArray(res?.suggestions) && res.suggestions.length > 0) {
|
|
112
|
+
setBackendSuggestedQuestions(res.suggestions);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
// Silent fail; UI will simply show empty inspiration until chat flows populate
|
|
118
|
+
console.error("Failed to fetch suggestions", e);
|
|
119
|
+
}
|
|
120
|
+
})();
|
|
50
121
|
return () => {
|
|
51
122
|
if (streamingCancelRef.current) {
|
|
52
123
|
streamingCancelRef.current();
|
|
53
124
|
}
|
|
54
|
-
|
|
125
|
+
client.closeWebSocket();
|
|
55
126
|
};
|
|
56
|
-
}, []);
|
|
127
|
+
}, [client]);
|
|
57
128
|
const handleSearch = async (e) => {
|
|
58
129
|
e.preventDefault();
|
|
59
130
|
if (!searchQuery.trim() || isStreaming)
|
|
@@ -73,11 +144,11 @@ export function GojiSearchComponent() {
|
|
|
73
144
|
setMessages((prev) => [...prev, { role: "assistant", content: "", timestamp: Date.now() }]);
|
|
74
145
|
let accumulatedContent = "";
|
|
75
146
|
try {
|
|
76
|
-
const cancelFn = await
|
|
147
|
+
const cancelFn = await client.streamChat({
|
|
77
148
|
message: userMessage.content,
|
|
78
149
|
sessionId,
|
|
79
150
|
limit: 5,
|
|
80
|
-
language:
|
|
151
|
+
language: currentLanguage,
|
|
81
152
|
onDelta: (delta) => {
|
|
82
153
|
accumulatedContent += delta;
|
|
83
154
|
setMessages((prev) => {
|
|
@@ -95,10 +166,15 @@ export function GojiSearchComponent() {
|
|
|
95
166
|
const updated = [...prev];
|
|
96
167
|
updated[assistantMessageIndex] = {
|
|
97
168
|
...updated[assistantMessageIndex],
|
|
169
|
+
content: response.answer,
|
|
98
170
|
sources: response.sources,
|
|
99
171
|
};
|
|
100
172
|
return updated;
|
|
101
173
|
});
|
|
174
|
+
// Update suggested questions from backend
|
|
175
|
+
if (response.suggested_questions && response.suggested_questions.length > 0) {
|
|
176
|
+
setBackendSuggestedQuestions(response.suggested_questions);
|
|
177
|
+
}
|
|
102
178
|
setIsStreaming(false);
|
|
103
179
|
streamingCancelRef.current = null;
|
|
104
180
|
},
|
|
@@ -138,11 +214,11 @@ export function GojiSearchComponent() {
|
|
|
138
214
|
setMessages((prev) => [...prev, { role: "assistant", content: "", timestamp: Date.now() }]);
|
|
139
215
|
let accumulatedContent = "";
|
|
140
216
|
try {
|
|
141
|
-
const cancelFn = await
|
|
217
|
+
const cancelFn = await client.streamChat({
|
|
142
218
|
message: question,
|
|
143
219
|
sessionId,
|
|
144
220
|
limit: 5,
|
|
145
|
-
language:
|
|
221
|
+
language: currentLanguage,
|
|
146
222
|
onDelta: (delta) => {
|
|
147
223
|
accumulatedContent += delta;
|
|
148
224
|
setMessages((prev) => {
|
|
@@ -160,10 +236,15 @@ export function GojiSearchComponent() {
|
|
|
160
236
|
const updated = [...prev];
|
|
161
237
|
updated[assistantMessageIndex] = {
|
|
162
238
|
...updated[assistantMessageIndex],
|
|
239
|
+
content: response.answer,
|
|
163
240
|
sources: response.sources,
|
|
164
241
|
};
|
|
165
242
|
return updated;
|
|
166
243
|
});
|
|
244
|
+
// Update suggested questions from backend
|
|
245
|
+
if (response.suggested_questions && response.suggested_questions.length > 0) {
|
|
246
|
+
setBackendSuggestedQuestions(response.suggested_questions);
|
|
247
|
+
}
|
|
167
248
|
setIsStreaming(false);
|
|
168
249
|
streamingCancelRef.current = null;
|
|
169
250
|
},
|
|
@@ -193,8 +274,130 @@ export function GojiSearchComponent() {
|
|
|
193
274
|
setSize("xs");
|
|
194
275
|
setShowCalendar(false);
|
|
195
276
|
};
|
|
196
|
-
const handleVoiceSearch = () => {
|
|
197
|
-
|
|
277
|
+
const handleVoiceSearch = async () => {
|
|
278
|
+
try {
|
|
279
|
+
if (typeof window === "undefined")
|
|
280
|
+
return;
|
|
281
|
+
if (isRecording) {
|
|
282
|
+
try {
|
|
283
|
+
mediaRecorderRef.current?.stop();
|
|
284
|
+
}
|
|
285
|
+
catch (_) { }
|
|
286
|
+
setIsRecording(false);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
290
|
+
const recorder = new MediaRecorder(stream);
|
|
291
|
+
mediaRecorderRef.current = recorder;
|
|
292
|
+
audioChunksRef.current = [];
|
|
293
|
+
recorder.ondataavailable = (e) => {
|
|
294
|
+
if (e.data && e.data.size > 0) {
|
|
295
|
+
audioChunksRef.current.push(e.data);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
recorder.onstop = async () => {
|
|
299
|
+
try {
|
|
300
|
+
const blob = new Blob(audioChunksRef.current, { type: "audio/webm" });
|
|
301
|
+
// Send to backend for transcription
|
|
302
|
+
const language = companyConfig.defaultLanguage || "en";
|
|
303
|
+
const result = await client.transcribeAudio({
|
|
304
|
+
file: blob,
|
|
305
|
+
filename: "recording.webm",
|
|
306
|
+
model: "gpt-4o-transcribe",
|
|
307
|
+
language,
|
|
308
|
+
});
|
|
309
|
+
const text = (result?.text || "").trim();
|
|
310
|
+
if (!text)
|
|
311
|
+
return;
|
|
312
|
+
// Auto-submit the transcribed text
|
|
313
|
+
const userMessage = {
|
|
314
|
+
role: "user",
|
|
315
|
+
content: text,
|
|
316
|
+
timestamp: Date.now(),
|
|
317
|
+
};
|
|
318
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
319
|
+
setSearchQuery("");
|
|
320
|
+
setSize((prev) => (prev === "xl" ? "xl" : "l"));
|
|
321
|
+
setIsStreaming(true);
|
|
322
|
+
const assistantMessageIndex = messages.length + 1;
|
|
323
|
+
setMessages((prev) => [...prev, { role: "assistant", content: "", timestamp: Date.now() }]);
|
|
324
|
+
let accumulatedContent = "";
|
|
325
|
+
try {
|
|
326
|
+
const cancelFn = await client.streamChat({
|
|
327
|
+
message: userMessage.content,
|
|
328
|
+
sessionId,
|
|
329
|
+
limit: 5,
|
|
330
|
+
language: currentLanguage,
|
|
331
|
+
onDelta: (delta) => {
|
|
332
|
+
accumulatedContent += delta;
|
|
333
|
+
setMessages((prev) => {
|
|
334
|
+
const updated = [...prev];
|
|
335
|
+
updated[assistantMessageIndex] = {
|
|
336
|
+
...updated[assistantMessageIndex],
|
|
337
|
+
content: accumulatedContent,
|
|
338
|
+
};
|
|
339
|
+
return updated;
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
onDone: (response) => {
|
|
343
|
+
setSessionId(response.session_id);
|
|
344
|
+
setMessages((prev) => {
|
|
345
|
+
const updated = [...prev];
|
|
346
|
+
updated[assistantMessageIndex] = {
|
|
347
|
+
...updated[assistantMessageIndex],
|
|
348
|
+
content: response.answer,
|
|
349
|
+
sources: response.sources,
|
|
350
|
+
};
|
|
351
|
+
return updated;
|
|
352
|
+
});
|
|
353
|
+
// Update suggested questions from backend
|
|
354
|
+
if (response.suggested_questions && response.suggested_questions.length > 0) {
|
|
355
|
+
setBackendSuggestedQuestions(response.suggested_questions);
|
|
356
|
+
}
|
|
357
|
+
setIsStreaming(false);
|
|
358
|
+
streamingCancelRef.current = null;
|
|
359
|
+
},
|
|
360
|
+
onError: (error) => {
|
|
361
|
+
console.error(" Streaming error:", error);
|
|
362
|
+
setMessages((prev) => {
|
|
363
|
+
const updated = [...prev];
|
|
364
|
+
updated[assistantMessageIndex] = {
|
|
365
|
+
...updated[assistantMessageIndex],
|
|
366
|
+
content: "I'm sorry, I encountered an error. Please try again.",
|
|
367
|
+
};
|
|
368
|
+
return updated;
|
|
369
|
+
});
|
|
370
|
+
setIsStreaming(false);
|
|
371
|
+
streamingCancelRef.current = null;
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
streamingCancelRef.current = cancelFn;
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
console.error(" Failed to start streaming:", error);
|
|
378
|
+
setIsStreaming(false);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
catch (err) {
|
|
382
|
+
console.error("Transcription failed:", err);
|
|
383
|
+
}
|
|
384
|
+
finally {
|
|
385
|
+
// Cleanup audio tracks
|
|
386
|
+
try {
|
|
387
|
+
mediaRecorderRef.current?.stream?.getTracks?.().forEach((t) => t.stop());
|
|
388
|
+
}
|
|
389
|
+
catch (_) { }
|
|
390
|
+
mediaRecorderRef.current = null;
|
|
391
|
+
audioChunksRef.current = [];
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
recorder.start(250);
|
|
395
|
+
setIsRecording(true);
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
console.error("Voice search failed:", err);
|
|
399
|
+
setIsRecording(false);
|
|
400
|
+
}
|
|
198
401
|
};
|
|
199
402
|
const handleToggle = () => {
|
|
200
403
|
setHasInteracted(true);
|
|
@@ -268,7 +471,7 @@ export function GojiSearchComponent() {
|
|
|
268
471
|
};
|
|
269
472
|
const handleCalendarClick = () => {
|
|
270
473
|
setShowCalendar(true);
|
|
271
|
-
setSize("
|
|
474
|
+
setSize("xl");
|
|
272
475
|
};
|
|
273
476
|
const handleBackToChat = () => {
|
|
274
477
|
setShowCalendar(false);
|
|
@@ -277,8 +480,8 @@ export function GojiSearchComponent() {
|
|
|
277
480
|
xs: { maxWidth: "5.5rem", bottom: "0.5rem", padding: "0" },
|
|
278
481
|
s: { maxWidth: "25.5rem", bottom: "0.5rem", padding: "0" },
|
|
279
482
|
m: { maxWidth: "30rem", bottom: "0.75rem", padding: "0.25rem" },
|
|
280
|
-
l: { maxWidth: "45vw", bottom: "1.25rem", padding: "
|
|
281
|
-
xl: { maxWidth: "70vw", bottom: "1.5rem", padding: "
|
|
483
|
+
l: { maxWidth: "45vw", bottom: "1.25rem", padding: "0.5rem" },
|
|
484
|
+
xl: { maxWidth: "70vw", bottom: "1.5rem", padding: "0.75rem" },
|
|
282
485
|
};
|
|
283
486
|
const currentConfig = sizeConfig[size];
|
|
284
487
|
return (_jsx("div", { style: {
|
|
@@ -298,6 +501,8 @@ export function GojiSearchComponent() {
|
|
|
298
501
|
border: size === "xs" || size === "s" ? "none" : "1px solid rgba(85, 85, 85, 0.18)",
|
|
299
502
|
backgroundColor: size === "xs" || size === "s" ? "transparent" : "rgba(233, 210, 251, 0.15)",
|
|
300
503
|
padding: size === "s" ? "0" : currentConfig.padding,
|
|
504
|
+
// remove top padding so inner message list / calendar sit flush with the component border
|
|
505
|
+
paddingTop: 0,
|
|
301
506
|
height: size === "l" ? "55vh" : size === "xl" ? "70vh" : "auto",
|
|
302
507
|
display: "flex",
|
|
303
508
|
flexDirection: "column",
|
|
@@ -310,77 +515,76 @@ export function GojiSearchComponent() {
|
|
|
310
515
|
backdropFilter: size === "xs" || size === "s" ? "none" : "blur(40px) saturate(180%) brightness(110%)",
|
|
311
516
|
WebkitBackdropFilter: size === "xs" || size === "s" ? "none" : "blur(40px) saturate(180%) brightness(110%)",
|
|
312
517
|
transition: "all 0.4s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
313
|
-
}, children: [
|
|
518
|
+
}, children: [["m", "l", "xl"].includes(size) && (_jsx("div", { style: {
|
|
314
519
|
position: "absolute",
|
|
315
|
-
top:
|
|
316
|
-
right:
|
|
520
|
+
top: 0,
|
|
521
|
+
right: "0.5rem",
|
|
317
522
|
zIndex: 50,
|
|
523
|
+
paddingBottom: "0.5rem",
|
|
318
524
|
}, children: _jsx("div", { style: {
|
|
319
525
|
position: "relative",
|
|
320
|
-
|
|
321
|
-
// but hide them when only suggested questions are shown (messages.length === 0 && showSuggestions)
|
|
322
|
-
display: (size === 'm' || messages.length === 0 || showCalendar) && !(messages.length === 0 && showSuggestions) ? 'inline-flex' : 'none',
|
|
526
|
+
display: 'flex',
|
|
323
527
|
gap: '0.5rem',
|
|
324
528
|
alignItems: 'center',
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
529
|
+
justifyContent: 'flex-end',
|
|
530
|
+
zIndex: 20,
|
|
531
|
+
paddingRight: "0.3rem",
|
|
532
|
+
backgroundColor: "transparent",
|
|
533
|
+
borderRadius: "0.75rem",
|
|
534
|
+
}, children: _jsxs("div", { style: {
|
|
535
|
+
display: "flex",
|
|
536
|
+
gap: "0.375rem",
|
|
537
|
+
alignItems: "center",
|
|
538
|
+
padding: "0.3rem 0 0.5rem 0",
|
|
539
|
+
}, children: [_jsxs("div", { style: { position: "relative" }, children: [_jsx("button", { type: "button", onClick: handleExpandToggle, onMouseEnter: () => setHoverTopExpand(true), onMouseLeave: () => setHoverTopExpand(false), "aria-label": size === "xl" ? "Restore" : "Expand", "aria-describedby": hoverTopExpand ? expandTooltipId : undefined, style: {
|
|
540
|
+
padding: "0.375rem",
|
|
541
|
+
display: "flex",
|
|
542
|
+
alignItems: "center",
|
|
543
|
+
justifyContent: "center",
|
|
544
|
+
color: "rgba(0, 0, 0, 0.75)",
|
|
545
|
+
transition: "all 0.15s",
|
|
546
|
+
cursor: "pointer",
|
|
547
|
+
outline: "none",
|
|
548
|
+
}, children: size === "xl" ? (_jsx(Minimize2, { style: { width: "0.9rem", height: "0.9rem" } })) : (_jsx(Maximize2, { style: { width: "0.9rem", height: "0.9rem" } })) }), _jsx("span", { id: expandTooltipId, role: "tooltip", style: {
|
|
549
|
+
position: "absolute",
|
|
550
|
+
top: "calc(100% + 0.4rem)",
|
|
551
|
+
left: "50%",
|
|
552
|
+
transform: "translateX(-50%)",
|
|
553
|
+
whiteSpace: "nowrap",
|
|
554
|
+
background: "rgba(0,0,0,0.9)",
|
|
555
|
+
color: "#fff",
|
|
556
|
+
padding: "4px 6px",
|
|
557
|
+
borderRadius: "1.3rem",
|
|
558
|
+
fontSize: "0.55rem",
|
|
559
|
+
boxShadow: "0 6px 18px rgba(0,0,0,0.35)",
|
|
350
560
|
opacity: hoverTopExpand ? 1 : 0,
|
|
351
|
-
pointerEvents:
|
|
352
|
-
transition:
|
|
561
|
+
pointerEvents: "none",
|
|
562
|
+
transition: "opacity 120ms ease-in-out",
|
|
353
563
|
zIndex: 30,
|
|
354
|
-
}, children: size ===
|
|
355
|
-
|
|
356
|
-
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
357
|
-
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
358
|
-
padding: "0.4rem",
|
|
564
|
+
}, children: size === "xl" ? "Restore" : "Expand" })] }), _jsxs("div", { style: { position: "relative" }, children: [_jsx("button", { type: "button", onClick: handleClose, onMouseEnter: () => setHoverTopClose(true), onMouseLeave: () => setHoverTopClose(false), "aria-label": "Close", "aria-describedby": hoverTopClose ? xTooltipId : undefined, style: {
|
|
565
|
+
padding: "0.375rem",
|
|
359
566
|
display: "flex",
|
|
360
567
|
alignItems: "center",
|
|
361
568
|
justifyContent: "center",
|
|
362
569
|
color: "rgba(0, 0, 0, 0.75)",
|
|
363
|
-
|
|
364
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
365
|
-
transition: "all 0.2s",
|
|
570
|
+
transition: "all 0.15s",
|
|
366
571
|
cursor: "pointer",
|
|
367
572
|
outline: "none",
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
boxShadow: '0 6px 18px rgba(0,0,0,0.35)',
|
|
573
|
+
}, children: _jsx(X, { style: { width: "0.9rem", height: "0.9rem" } }) }), _jsx("span", { id: xTooltipId, role: "tooltip", style: {
|
|
574
|
+
position: "absolute",
|
|
575
|
+
top: "calc(100% + 0.4rem)",
|
|
576
|
+
left: "50%",
|
|
577
|
+
transform: "translateX(-50%)",
|
|
578
|
+
whiteSpace: "nowrap",
|
|
579
|
+
background: "rgba(0,0,0,0.9)",
|
|
580
|
+
color: "#fff",
|
|
581
|
+
padding: "4px 6px",
|
|
582
|
+
borderRadius: "1.3rem",
|
|
583
|
+
fontSize: "0.55rem",
|
|
584
|
+
boxShadow: "0 6px 18px rgba(0,0,0,0.35)",
|
|
381
585
|
opacity: hoverTopClose ? 1 : 0,
|
|
382
|
-
pointerEvents:
|
|
383
|
-
transition:
|
|
586
|
+
pointerEvents: "none",
|
|
587
|
+
transition: "opacity 120ms ease-in-out",
|
|
384
588
|
zIndex: 30,
|
|
385
589
|
}, children: "Close" })] })] }) }) })), size === "xs" ? (_jsx("button", { type: "button", onClick: handleToggle, style: {
|
|
386
590
|
background: "transparent",
|
|
@@ -401,29 +605,21 @@ export function GojiSearchComponent() {
|
|
|
401
605
|
display: "flex",
|
|
402
606
|
alignItems: "center",
|
|
403
607
|
justifyContent: "center",
|
|
404
|
-
padding: "0.5rem",
|
|
405
|
-
borderRadius: "0.5rem",
|
|
406
|
-
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
407
|
-
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
608
|
+
padding: "0.3rem 0 0.5rem 0.3rem",
|
|
408
609
|
color: "rgba(0, 0, 0, 0.75)",
|
|
409
610
|
cursor: "pointer",
|
|
410
611
|
transition: "all 0.2s",
|
|
411
612
|
alignSelf: "flex-start",
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}, onMouseEnter: (e) => {
|
|
415
|
-
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)";
|
|
416
|
-
}, onMouseLeave: (e) => {
|
|
417
|
-
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
|
|
418
|
-
}, children: _jsx(ArrowLeft, { style: { width: "1.125rem", height: "1.125rem" } }) }), _jsx("div", { style: {
|
|
613
|
+
outline: "none",
|
|
614
|
+
}, children: _jsx(ArrowLeft, { style: { width: "0.875rem", height: "0.875rem" } }) }), _jsx("div", { style: {
|
|
419
615
|
flex: 1,
|
|
420
616
|
borderRadius: "0.75rem",
|
|
421
617
|
overflow: "hidden",
|
|
422
|
-
backgroundColor: "
|
|
618
|
+
backgroundColor: "transparent",
|
|
423
619
|
minHeight: 0,
|
|
424
620
|
display: "flex",
|
|
425
621
|
flexDirection: "column",
|
|
426
|
-
}, children: _jsx(CalendarIntegration, { onBooked: handleBackToChat }) })] })) : (_jsxs(_Fragment, { children: [(size === "l" || size === "xl") && messages.length > 0 && (_jsx(MessageList, { messages: messages, isStreaming: isStreaming, aiAvatarSrc:
|
|
622
|
+
}, children: _jsx(CalendarIntegration, { onBooked: handleBackToChat }) })] })) : (_jsxs(_Fragment, { children: [(size === "l" || size === "xl") && messages.length > 0 && (_jsx(MessageList, { messages: messages, isStreaming: isStreaming, aiAvatarSrc: chatLogo, size: size })), size === "s" ? (_jsxs("div", { style: {
|
|
427
623
|
display: "flex",
|
|
428
624
|
alignItems: "center",
|
|
429
625
|
gap: "0.35rem",
|
|
@@ -443,7 +639,7 @@ export function GojiSearchComponent() {
|
|
|
443
639
|
flexDirection: "column",
|
|
444
640
|
gap: "0.35rem",
|
|
445
641
|
flex: 1,
|
|
446
|
-
backgroundColor: "
|
|
642
|
+
backgroundColor: "transparent",
|
|
447
643
|
borderRadius: "1.5rem",
|
|
448
644
|
border: "1px solid rgba(85, 85, 85, 0.18)",
|
|
449
645
|
boxShadow: "0 4px 24px 0 rgba(0, 0, 0, 0.08), inset 0 1px 0 0 rgba(255, 255, 255, 0.3)",
|
|
@@ -456,16 +652,13 @@ export function GojiSearchComponent() {
|
|
|
456
652
|
gap: "0.375rem",
|
|
457
653
|
transition: "gap 0.3s ease",
|
|
458
654
|
flexShrink: 0,
|
|
459
|
-
}, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(SearchInput, { value: searchQuery, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: "Search...", size: size, inputRef: inputRef, inspirationQuestions: inspirationQuestions, onInspirationClick: handleSuggestionClick, sparkleRef: sparkleRef }) }), _jsx(ActionButtons, { size: size, isHovered: isHovered, isStreaming: isStreaming, searchQuery: searchQuery, onSubmit: () => { }, onVoiceSearch: handleVoiceSearch, onClose: handleClose, onCalendarClick: handleCalendarClick })] }) })] })) : (_jsxs("div", { onMouseEnter: handleInputAreaMouseEnter, onMouseLeave: handleInputAreaMouseLeave, style: {
|
|
655
|
+
}, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(SearchInput, { value: searchQuery, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: "Search...", size: size, inputRef: inputRef, inspirationQuestions: inspirationQuestions, onInspirationClick: handleSuggestionClick, sparkleRef: sparkleRef }) }), _jsx(ActionButtons, { size: size, isHovered: isHovered, isStreaming: isStreaming, searchQuery: searchQuery, isRecording: isRecording, onSubmit: () => { }, onVoiceSearch: handleVoiceSearch, onClose: handleClose, onCalendarClick: handleCalendarClick })] }) })] })) : (_jsxs("div", { onMouseEnter: handleInputAreaMouseEnter, onMouseLeave: handleInputAreaMouseLeave, style: {
|
|
460
656
|
display: "flex",
|
|
461
657
|
flexDirection: "column",
|
|
462
658
|
gap: "0.5rem",
|
|
463
|
-
paddingTop:
|
|
659
|
+
paddingTop: 0,
|
|
464
660
|
}, children: [_jsx("button", { type: "button", onClick: handleClose, style: {
|
|
465
|
-
|
|
466
|
-
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
467
|
-
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
468
|
-
padding: "0.4rem",
|
|
661
|
+
padding: " 0 0.4rem",
|
|
469
662
|
// rendered only when size !== 'xs' so show the button
|
|
470
663
|
display: size === 'm' ? "flex" : "none",
|
|
471
664
|
alignItems: "center",
|
|
@@ -473,12 +666,9 @@ export function GojiSearchComponent() {
|
|
|
473
666
|
alignSelf: "flex-end",
|
|
474
667
|
width: "fit-content",
|
|
475
668
|
color: "rgba(0, 0, 0, 0.75)",
|
|
476
|
-
backdropFilter: "blur(20px)",
|
|
477
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
478
669
|
transition: "all 0.2s",
|
|
479
670
|
cursor: "pointer",
|
|
480
|
-
outline: "none"
|
|
481
|
-
boxShadow: "inset 0 1px 0 rgba(255, 255, 255, 0.3)",
|
|
671
|
+
outline: "none"
|
|
482
672
|
}, children: _jsx(X, { style: { width: "0.875rem", height: "0.875rem" } }) }), _jsx("span", { role: "tooltip", style: {
|
|
483
673
|
position: "absolute",
|
|
484
674
|
top: "calc(100% + 0.4rem)",
|
|
@@ -495,11 +685,11 @@ export function GojiSearchComponent() {
|
|
|
495
685
|
pointerEvents: "none",
|
|
496
686
|
transition: "opacity 120ms ease-in-out",
|
|
497
687
|
zIndex: 30,
|
|
498
|
-
}, children: "Close" }), showSuggestions && messages.length === 0 && !searchQuery && (_jsx(SuggestedQuestions, { questions:
|
|
688
|
+
}, children: "Close" }), showSuggestions && messages.length === 0 && !searchQuery && (_jsx(SuggestedQuestions, { questions: inspirationQuestions, onQuestionClick: handleSuggestionClick })), _jsxs("form", { onSubmit: handleSearch, style: {
|
|
499
689
|
display: "flex",
|
|
500
690
|
alignItems: "center",
|
|
501
691
|
gap: "0.375rem",
|
|
502
692
|
transition: "gap 0.3s ease",
|
|
503
693
|
flexShrink: 0,
|
|
504
|
-
}, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(SearchInput, { value: searchQuery, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: "Ask me anything...", size: size, inputRef: inputRef, inspirationQuestions: inspirationQuestions, onInspirationClick: handleSuggestionClick, sparkleRef: sparkleRef }) }), _jsx(ActionButtons, { size: size, isHovered: isHovered, isStreaming: isStreaming, searchQuery: searchQuery, onSubmit: () => { }, onVoiceSearch: handleVoiceSearch, onClose: handleClose, onCalendarClick: handleCalendarClick })] })] }))] })) }))] }) }) }));
|
|
694
|
+
}, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(SearchInput, { value: searchQuery, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: "Ask me anything...", size: size, inputRef: inputRef, inspirationQuestions: inspirationQuestions, onInspirationClick: handleSuggestionClick, sparkleRef: sparkleRef }) }), _jsx(ActionButtons, { size: size, isHovered: isHovered, isStreaming: isStreaming, searchQuery: searchQuery, isRecording: isRecording, onSubmit: () => { }, onVoiceSearch: handleVoiceSearch, onClose: handleClose, onCalendarClick: handleCalendarClick })] })] }))] })) }))] }) }) }));
|
|
505
695
|
}
|