xertica-ui 1.3.6 → 1.3.8
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/components/HomePage.tsx +4 -0
- package/components/Sidebar.tsx +16 -8
- package/components/TemplatePage.tsx +1 -0
- package/components/examples/ApiKeyMapExample.tsx +71 -0
- package/components/examples/SidebarLogoExample.tsx +65 -0
- package/components/ui/google-maps-loader.tsx +56 -12
- package/components/ui/map.tsx +9 -1
- package/components/ui/route-map.tsx +9 -1
- package/components/ui/xertica-assistant.tsx +18 -10
- package/dist/components/Sidebar.d.ts +3 -1
- package/dist/components/ui/google-maps-loader.d.ts +6 -3
- package/dist/index.es.js +80 -28
- package/dist/index.umd.js +80 -28
- package/package.json +1 -1
package/components/HomePage.tsx
CHANGED
|
@@ -51,6 +51,10 @@ export function HomePage({ user, onLogout }: HomePageProps) {
|
|
|
51
51
|
responseGenerator={generateDemoResponse}
|
|
52
52
|
richSuggestions={richSuggestions}
|
|
53
53
|
feedbackOptions={feedbackOptions}
|
|
54
|
+
onEvaluation={(messageId, type, reason) => {
|
|
55
|
+
console.log(`Avaliação recebida: ${type} na mensagem ${messageId}. Motivo: ${reason}`);
|
|
56
|
+
// Aqui você implementaria a lógica para salvar no backend
|
|
57
|
+
}}
|
|
54
58
|
/>
|
|
55
59
|
</div>
|
|
56
60
|
);
|
package/components/Sidebar.tsx
CHANGED
|
@@ -74,6 +74,8 @@ interface SidebarProps {
|
|
|
74
74
|
location: { pathname: string };
|
|
75
75
|
navigate: (path: string) => void;
|
|
76
76
|
routes: RouteConfig[];
|
|
77
|
+
logo?: React.ReactNode;
|
|
78
|
+
logoCollapsed?: React.ReactNode;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export function Sidebar({
|
|
@@ -84,6 +86,8 @@ export function Sidebar({
|
|
|
84
86
|
location,
|
|
85
87
|
navigate,
|
|
86
88
|
routes,
|
|
89
|
+
logo,
|
|
90
|
+
logoCollapsed,
|
|
87
91
|
}: SidebarProps) {
|
|
88
92
|
const navRef = useRef<HTMLDivElement>(null);
|
|
89
93
|
const [hasOverflow, setHasOverflow] = useState(false);
|
|
@@ -318,15 +322,19 @@ export function Sidebar({
|
|
|
318
322
|
>
|
|
319
323
|
<div className="flex items-center justify-center flex-shrink-0">
|
|
320
324
|
{expanded ? (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
logo || (
|
|
326
|
+
<XerticaLogo
|
|
327
|
+
className="h-5 w-auto"
|
|
328
|
+
variant="white"
|
|
329
|
+
/>
|
|
330
|
+
)
|
|
325
331
|
) : (
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
logoCollapsed || (
|
|
333
|
+
<XerticaXLogo
|
|
334
|
+
className="h-5 w-auto"
|
|
335
|
+
variant="white"
|
|
336
|
+
/>
|
|
337
|
+
)
|
|
330
338
|
)}
|
|
331
339
|
</div>
|
|
332
340
|
</div>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Map } from '../ui/map';
|
|
3
|
+
import { RouteMap } from '../ui/route-map';
|
|
4
|
+
|
|
5
|
+
export function ApiKeyMapExample() {
|
|
6
|
+
const [key, setKey] = React.useState('');
|
|
7
|
+
const [appliedKey, setAppliedKey] = React.useState('');
|
|
8
|
+
|
|
9
|
+
const handleApply = () => {
|
|
10
|
+
if (key) setAppliedKey(key);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className="space-y-8 p-6">
|
|
15
|
+
<div className="space-y-4">
|
|
16
|
+
<h2 className="text-2xl font-bold">Map with Explicit API Key</h2>
|
|
17
|
+
<p className="text-muted-foreground">
|
|
18
|
+
Enter a Google Maps API Key to load the maps below. This simulates a scenario where the key is provided dynamically or via props, overriding/fallback for the global context.
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<div className="flex gap-4 max-w-xl">
|
|
22
|
+
<input
|
|
23
|
+
type="text"
|
|
24
|
+
value={key}
|
|
25
|
+
onChange={(e) => setKey(e.target.value)}
|
|
26
|
+
placeholder="Enter Google Maps API Key"
|
|
27
|
+
className="flex-1 px-4 py-2 border rounded-md bg-background"
|
|
28
|
+
/>
|
|
29
|
+
<button
|
|
30
|
+
onClick={handleApply}
|
|
31
|
+
className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
|
|
32
|
+
>
|
|
33
|
+
Load Maps
|
|
34
|
+
</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
{appliedKey ? (
|
|
39
|
+
<div className="grid md:grid-cols-2 gap-8">
|
|
40
|
+
<div className="space-y-4">
|
|
41
|
+
<h3 className="font-semibold">Standard Map</h3>
|
|
42
|
+
<Map
|
|
43
|
+
apiKey={appliedKey}
|
|
44
|
+
height="400px"
|
|
45
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
46
|
+
zoom={12}
|
|
47
|
+
markers={[
|
|
48
|
+
{ position: { lat: -23.5505, lng: -46.6333 }, title: 'São Paulo' }
|
|
49
|
+
]}
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div className="space-y-4">
|
|
54
|
+
<h3 className="font-semibold">Route Map</h3>
|
|
55
|
+
<RouteMap
|
|
56
|
+
apiKey={appliedKey}
|
|
57
|
+
height="400px"
|
|
58
|
+
origin={{ lat: -23.5505, lng: -46.6333 }}
|
|
59
|
+
destination={{ lat: -23.6005, lng: -46.6833 }}
|
|
60
|
+
travelMode="DRIVING"
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
) : (
|
|
65
|
+
<div className="p-12 border-2 border-dashed rounded-lg text-center text-muted-foreground">
|
|
66
|
+
Enter an API Key above to render the maps.
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Sidebar, RouteConfig } from '../Sidebar';
|
|
3
|
+
import { Home, Settings, User } from 'lucide-react';
|
|
4
|
+
import { BrowserRouter, useNavigate, useLocation } from 'react-router';
|
|
5
|
+
|
|
6
|
+
// Wrapper wrapper to provide router context
|
|
7
|
+
export function SidebarLogoExample() {
|
|
8
|
+
return (
|
|
9
|
+
<BrowserRouter>
|
|
10
|
+
<SidebarLogoContent />
|
|
11
|
+
</BrowserRouter>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function SidebarLogoContent() {
|
|
16
|
+
const [expanded, setExpanded] = useState(true);
|
|
17
|
+
const navigate = useNavigate();
|
|
18
|
+
const location = useLocation();
|
|
19
|
+
|
|
20
|
+
const routes: RouteConfig[] = [
|
|
21
|
+
{ path: '/home', label: 'Home', icon: Home },
|
|
22
|
+
{ path: '/profile', label: 'Profile', icon: User },
|
|
23
|
+
{ path: '/settings', label: 'Settings', icon: Settings },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const CustomLogo = (
|
|
27
|
+
<div className="flex items-center gap-2 font-bold text-xl text-primary">
|
|
28
|
+
<div className="w-8 h-8 bg-primary rounded-full flex items-center justify-center text-primary-foreground">
|
|
29
|
+
C
|
|
30
|
+
</div>
|
|
31
|
+
<span>CustomBrand</span>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const CustomLogoCollapsed = (
|
|
36
|
+
<div className="w-8 h-8 bg-primary rounded-full flex items-center justify-center text-primary-foreground font-bold">
|
|
37
|
+
C
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className="flex h-[500px] border rounded-lg overflow-hidden bg-background">
|
|
43
|
+
<Sidebar
|
|
44
|
+
expanded={expanded}
|
|
45
|
+
onToggle={() => setExpanded(!expanded)}
|
|
46
|
+
user={{ email: 'test@example.com' }}
|
|
47
|
+
onLogout={() => console.log('Logout')}
|
|
48
|
+
location={location}
|
|
49
|
+
navigate={navigate}
|
|
50
|
+
routes={routes}
|
|
51
|
+
logo={CustomLogo}
|
|
52
|
+
logoCollapsed={CustomLogoCollapsed}
|
|
53
|
+
/>
|
|
54
|
+
<div className={`flex-1 p-8 transition-all duration-300 ${expanded ? 'ml-64' : 'ml-20'}`}>
|
|
55
|
+
<h1 className="text-2xl font-bold mb-4">Sidebar with Custom Logo</h1>
|
|
56
|
+
<p>This example demonstrates passing a custom logo component to the Sidebar.</p>
|
|
57
|
+
<div className="mt-8 p-4 border rounded bg-muted/20">
|
|
58
|
+
<p className="text-sm text-muted-foreground">
|
|
59
|
+
Try toggling the sidebar to see the collapsed logo version.
|
|
60
|
+
</p>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -6,11 +6,13 @@ import { GOOGLE_MAPS_LIBRARIES, GOOGLE_MAPS_ID } from './map-config';
|
|
|
6
6
|
interface GoogleMapsContextType {
|
|
7
7
|
isLoaded: boolean;
|
|
8
8
|
loadError: Error | undefined;
|
|
9
|
+
load: (apiKey: string) => Promise<void>;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
const GoogleMapsContext = createContext<GoogleMapsContextType>({
|
|
12
13
|
isLoaded: false,
|
|
13
14
|
loadError: undefined,
|
|
15
|
+
load: () => Promise.resolve(),
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
// Singleton global para prevenir múltiplos carregamentos
|
|
@@ -57,7 +59,7 @@ function removeExistingScript(): void {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
// Remover script existente
|
|
60
|
-
const existingScript = document.querySelector(`script[src
|
|
62
|
+
const existingScript = document.querySelector(`script[src*="maps.googleapis.com/maps/api/js"]`);
|
|
61
63
|
if (existingScript) {
|
|
62
64
|
existingScript.remove();
|
|
63
65
|
}
|
|
@@ -202,6 +204,7 @@ function getOrCreateSingleton() {
|
|
|
202
204
|
isLoaded: isPreloaded,
|
|
203
205
|
loadError: undefined,
|
|
204
206
|
listeners: new Set(),
|
|
207
|
+
scriptElement: undefined
|
|
205
208
|
};
|
|
206
209
|
}
|
|
207
210
|
|
|
@@ -218,7 +221,24 @@ function updateSingleton(state: Partial<GoogleMapsContextType>) {
|
|
|
218
221
|
if (state.isLoaded !== undefined) singleton.isLoaded = state.isLoaded;
|
|
219
222
|
if (state.loadError !== undefined) singleton.loadError = state.loadError;
|
|
220
223
|
|
|
221
|
-
|
|
224
|
+
// Prepare safe state to notify
|
|
225
|
+
const newState: GoogleMapsContextType = {
|
|
226
|
+
isLoaded: singleton.isLoaded,
|
|
227
|
+
loadError: singleton.loadError,
|
|
228
|
+
load: async (apiKey: string) => {
|
|
229
|
+
// Allow manual loading call via stored function in context if needed,
|
|
230
|
+
// though typically we use the direct export or loadGoogleMapsScript
|
|
231
|
+
if (singleton.isLoaded) return;
|
|
232
|
+
try {
|
|
233
|
+
await loadGoogleMapsScript(apiKey);
|
|
234
|
+
updateSingleton({ isLoaded: true, loadError: undefined });
|
|
235
|
+
} catch (error: any) {
|
|
236
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
222
242
|
singleton.listeners.forEach(listener => listener(newState));
|
|
223
243
|
}
|
|
224
244
|
|
|
@@ -228,11 +248,25 @@ function updateSingleton(state: Partial<GoogleMapsContextType>) {
|
|
|
228
248
|
const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
|
|
229
249
|
const [state, setState] = useState<GoogleMapsContextType>(() => {
|
|
230
250
|
const singleton = getOrCreateSingleton();
|
|
231
|
-
|
|
251
|
+
|
|
252
|
+
// Default load function that triggers the script load
|
|
253
|
+
const loadFn = async (apiKey: string) => {
|
|
254
|
+
if (singleton?.isLoaded) return;
|
|
255
|
+
try {
|
|
256
|
+
await loadGoogleMapsScript(apiKey);
|
|
257
|
+
updateSingleton({ isLoaded: true, loadError: undefined });
|
|
258
|
+
} catch (error: any) {
|
|
259
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
if (!singleton) return { isLoaded: false, loadError: undefined, load: loadFn };
|
|
232
265
|
|
|
233
266
|
return {
|
|
234
267
|
isLoaded: singleton.isLoaded,
|
|
235
268
|
loadError: singleton.loadError,
|
|
269
|
+
load: loadFn
|
|
236
270
|
};
|
|
237
271
|
});
|
|
238
272
|
|
|
@@ -246,8 +280,12 @@ const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
|
|
|
246
280
|
|
|
247
281
|
singleton.listeners.add(listener);
|
|
248
282
|
|
|
249
|
-
// Sincronizar estado inicial
|
|
250
|
-
listener({
|
|
283
|
+
// Sincronizar estado inicial e função de load
|
|
284
|
+
listener({
|
|
285
|
+
isLoaded: singleton.isLoaded,
|
|
286
|
+
loadError: singleton.loadError,
|
|
287
|
+
load: state.load
|
|
288
|
+
});
|
|
251
289
|
|
|
252
290
|
return () => {
|
|
253
291
|
singleton.listeners.delete(listener);
|
|
@@ -264,7 +302,7 @@ const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
|
|
|
264
302
|
/**
|
|
265
303
|
* Componente que carrega o Google Maps manualmente
|
|
266
304
|
*/
|
|
267
|
-
const LoaderInitializer = () => {
|
|
305
|
+
const LoaderInitializer = ({ apiKey }: { apiKey?: string }) => {
|
|
268
306
|
const hasInitializedRef = useRef(false);
|
|
269
307
|
|
|
270
308
|
useEffect(() => {
|
|
@@ -285,10 +323,11 @@ const LoaderInitializer = () => {
|
|
|
285
323
|
|
|
286
324
|
hasInitializedRef.current = true;
|
|
287
325
|
|
|
288
|
-
|
|
326
|
+
// Use prop key OR get from storage
|
|
327
|
+
const keyToUse = apiKey || getInitialApiKey();
|
|
289
328
|
|
|
290
329
|
// Se não houver API key, apenas marcar como não carregado (sem erro)
|
|
291
|
-
if (!
|
|
330
|
+
if (!keyToUse) {
|
|
292
331
|
updateSingleton({
|
|
293
332
|
isLoaded: false,
|
|
294
333
|
loadError: undefined // Não definir erro quando não há API key
|
|
@@ -296,25 +335,30 @@ const LoaderInitializer = () => {
|
|
|
296
335
|
return;
|
|
297
336
|
}
|
|
298
337
|
|
|
299
|
-
loadGoogleMapsScript(
|
|
338
|
+
loadGoogleMapsScript(keyToUse)
|
|
300
339
|
.then(() => {
|
|
301
340
|
updateSingleton({ isLoaded: true, loadError: undefined });
|
|
302
341
|
})
|
|
303
342
|
.catch((error) => {
|
|
304
343
|
updateSingleton({ isLoaded: false, loadError: error });
|
|
305
344
|
});
|
|
306
|
-
}, []);
|
|
345
|
+
}, [apiKey]);
|
|
307
346
|
|
|
308
347
|
return null;
|
|
309
348
|
};
|
|
310
349
|
|
|
350
|
+
interface GoogleMapsLoaderProviderProps {
|
|
351
|
+
children: ReactNode;
|
|
352
|
+
apiKey?: string;
|
|
353
|
+
}
|
|
354
|
+
|
|
311
355
|
/**
|
|
312
356
|
* GoogleMapsLoaderProvider
|
|
313
357
|
*
|
|
314
358
|
* Provider global que gerencia o carregamento da API do Google Maps.
|
|
315
359
|
* Usa carregamento manual do script para evitar conflitos com custom elements.
|
|
316
360
|
*/
|
|
317
|
-
export const GoogleMapsLoaderProvider = ({ children }:
|
|
361
|
+
export const GoogleMapsLoaderProvider = ({ children, apiKey }: GoogleMapsLoaderProviderProps) => {
|
|
318
362
|
const [shouldInitialize] = useState(() => {
|
|
319
363
|
const singleton = getOrCreateSingleton();
|
|
320
364
|
if (!singleton) return false;
|
|
@@ -330,7 +374,7 @@ export const GoogleMapsLoaderProvider = ({ children }: { children: ReactNode })
|
|
|
330
374
|
|
|
331
375
|
return (
|
|
332
376
|
<>
|
|
333
|
-
{shouldInitialize && <LoaderInitializer />}
|
|
377
|
+
{shouldInitialize && <LoaderInitializer apiKey={apiKey} />}
|
|
334
378
|
<SingletonLoaderWrapper>{children}</SingletonLoaderWrapper>
|
|
335
379
|
</>
|
|
336
380
|
);
|
package/components/ui/map.tsx
CHANGED
|
@@ -96,6 +96,14 @@ const MapContent = React.forwardRef<HTMLDivElement, MapProps & { apiKey: string
|
|
|
96
96
|
|
|
97
97
|
// Initialize map once
|
|
98
98
|
useEffect(() => {
|
|
99
|
+
// If we have an apiKey and not loaded, try to load it
|
|
100
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
101
|
+
const { load } = useGoogleMapsLoader();
|
|
102
|
+
if (load) {
|
|
103
|
+
load(apiKey).catch((console.error));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
100
108
|
|
|
101
109
|
isInitializedRef.current = true;
|
|
@@ -121,7 +129,7 @@ const MapContent = React.forwardRef<HTMLDivElement, MapProps & { apiKey: string
|
|
|
121
129
|
isInitializedRef.current = false;
|
|
122
130
|
mapRef.current = null;
|
|
123
131
|
};
|
|
124
|
-
}, [isLoaded]);
|
|
132
|
+
}, [isLoaded, apiKey]);
|
|
125
133
|
|
|
126
134
|
// Update markers
|
|
127
135
|
useEffect(() => {
|
|
@@ -47,6 +47,14 @@ const RouteMapContent = React.forwardRef<HTMLDivElement, RouteMapProps & { apiKe
|
|
|
47
47
|
|
|
48
48
|
// Initialize map once
|
|
49
49
|
useEffect(() => {
|
|
50
|
+
// If we have an apiKey and not loaded, try to load it
|
|
51
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
52
|
+
const { load } = useGoogleMapsLoader();
|
|
53
|
+
if (load) {
|
|
54
|
+
load(apiKey).catch((console.error));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
51
59
|
|
|
52
60
|
isInitializedRef.current = true;
|
|
@@ -85,7 +93,7 @@ const RouteMapContent = React.forwardRef<HTMLDivElement, RouteMapProps & { apiKe
|
|
|
85
93
|
isInitializedRef.current = false;
|
|
86
94
|
mapRef.current = null;
|
|
87
95
|
};
|
|
88
|
-
}, [isLoaded]);
|
|
96
|
+
}, [isLoaded, apiKey]);
|
|
89
97
|
|
|
90
98
|
// Calculate route
|
|
91
99
|
useEffect(() => {
|
|
@@ -487,9 +487,9 @@ export function XerticaAssistant({
|
|
|
487
487
|
}
|
|
488
488
|
}, [mensagens, abaSelecionada]);
|
|
489
489
|
|
|
490
|
-
// Sincronizar mensagens iniciais
|
|
490
|
+
// Sincronizar mensagens iniciais apenas quando elas mudarem e não forem vazias
|
|
491
491
|
useEffect(() => {
|
|
492
|
-
if (initialMessages.length > 0) {
|
|
492
|
+
if (initialMessages && initialMessages.length > 0) {
|
|
493
493
|
setMensagens(initialMessages);
|
|
494
494
|
}
|
|
495
495
|
}, [initialMessages]);
|
|
@@ -875,17 +875,22 @@ export function XerticaAssistant({
|
|
|
875
875
|
{/* Header - Toggle Button - Apenas visível quando não está em fullPage */}
|
|
876
876
|
{!isFullPage && (
|
|
877
877
|
<div
|
|
878
|
-
className=
|
|
878
|
+
className={cn(
|
|
879
|
+
"border-b border-border flex items-center py-3",
|
|
880
|
+
isExpanded ? "justify-between px-4 py-4" : "justify-center px-0"
|
|
881
|
+
)}
|
|
879
882
|
>
|
|
880
883
|
{isExpanded && (
|
|
881
884
|
<motion.div
|
|
882
|
-
initial={{ opacity: 0, x:
|
|
885
|
+
initial={{ opacity: 0, x: -10 }}
|
|
883
886
|
animate={{ opacity: 1, x: 0 }}
|
|
884
|
-
exit={{ opacity: 0, x:
|
|
885
|
-
className="flex items-center gap-2"
|
|
887
|
+
exit={{ opacity: 0, x: -10 }}
|
|
888
|
+
className="flex items-center gap-2 overflow-hidden"
|
|
886
889
|
>
|
|
887
|
-
<
|
|
888
|
-
|
|
890
|
+
<div className="flex-shrink-0">
|
|
891
|
+
<XerticaOrbe size={32} />
|
|
892
|
+
</div>
|
|
893
|
+
<span className="text-foreground font-medium truncate">Assistente Xertica</span>
|
|
889
894
|
</motion.div>
|
|
890
895
|
)}
|
|
891
896
|
|
|
@@ -895,7 +900,7 @@ export function XerticaAssistant({
|
|
|
895
900
|
variant="ghost"
|
|
896
901
|
size="sm"
|
|
897
902
|
onClick={onNavigateFullPage}
|
|
898
|
-
className="p-
|
|
903
|
+
className="h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full"
|
|
899
904
|
title="Expandir assistente"
|
|
900
905
|
>
|
|
901
906
|
<Maximize2 className="w-4 h-4" />
|
|
@@ -906,7 +911,10 @@ export function XerticaAssistant({
|
|
|
906
911
|
variant="ghost"
|
|
907
912
|
size="sm"
|
|
908
913
|
onClick={handleToggle}
|
|
909
|
-
className=
|
|
914
|
+
className={cn(
|
|
915
|
+
"h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
916
|
+
!isExpanded && "w-10 h-10" // Slightly larger touch target when collapsed if desired, or keep consistent
|
|
917
|
+
)}
|
|
910
918
|
>
|
|
911
919
|
{isExpanded ? (
|
|
912
920
|
<ChevronRight className="w-4 h-4" />
|
|
@@ -17,6 +17,8 @@ interface SidebarProps {
|
|
|
17
17
|
};
|
|
18
18
|
navigate: (path: string) => void;
|
|
19
19
|
routes: RouteConfig[];
|
|
20
|
+
logo?: React.ReactNode;
|
|
21
|
+
logoCollapsed?: React.ReactNode;
|
|
20
22
|
}
|
|
21
|
-
export declare function Sidebar({ expanded, onToggle, user, onLogout, location, navigate, routes, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export declare function Sidebar({ expanded, onToggle, user, onLogout, location, navigate, routes, logo, logoCollapsed, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
22
24
|
export {};
|
|
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
interface GoogleMapsContextType {
|
|
3
3
|
isLoaded: boolean;
|
|
4
4
|
loadError: Error | undefined;
|
|
5
|
+
load: (apiKey: string) => Promise<void>;
|
|
5
6
|
}
|
|
6
7
|
declare global {
|
|
7
8
|
interface Window {
|
|
@@ -13,15 +14,17 @@ declare global {
|
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
16
|
}
|
|
17
|
+
interface GoogleMapsLoaderProviderProps {
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
apiKey?: string;
|
|
20
|
+
}
|
|
16
21
|
/**
|
|
17
22
|
* GoogleMapsLoaderProvider
|
|
18
23
|
*
|
|
19
24
|
* Provider global que gerencia o carregamento da API do Google Maps.
|
|
20
25
|
* Usa carregamento manual do script para evitar conflitos com custom elements.
|
|
21
26
|
*/
|
|
22
|
-
export declare const GoogleMapsLoaderProvider: ({ children }:
|
|
23
|
-
children: ReactNode;
|
|
24
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare const GoogleMapsLoaderProvider: ({ children, apiKey }: GoogleMapsLoaderProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
25
28
|
export declare const useGoogleMapsLoader: () => GoogleMapsContextType;
|
|
26
29
|
/**
|
|
27
30
|
* Recarrega o Google Maps com uma nova API key
|
package/dist/index.es.js
CHANGED
|
@@ -46010,7 +46010,7 @@ function XerticaAssistant({
|
|
|
46010
46010
|
}
|
|
46011
46011
|
}, [mensagens, abaSelecionada]);
|
|
46012
46012
|
useEffect(() => {
|
|
46013
|
-
if (initialMessages.length > 0) {
|
|
46013
|
+
if (initialMessages && initialMessages.length > 0) {
|
|
46014
46014
|
setMensagens(initialMessages);
|
|
46015
46015
|
}
|
|
46016
46016
|
}, [initialMessages]);
|
|
@@ -46321,18 +46321,21 @@ function XerticaAssistant({
|
|
|
46321
46321
|
!isFullPage && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
46322
46322
|
"div",
|
|
46323
46323
|
{
|
|
46324
|
-
className:
|
|
46324
|
+
className: cn(
|
|
46325
|
+
"border-b border-border flex items-center py-3",
|
|
46326
|
+
isExpanded ? "justify-between px-4 py-4" : "justify-center px-0"
|
|
46327
|
+
),
|
|
46325
46328
|
children: [
|
|
46326
46329
|
isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
46327
46330
|
motion.div,
|
|
46328
46331
|
{
|
|
46329
|
-
initial: { opacity: 0, x:
|
|
46332
|
+
initial: { opacity: 0, x: -10 },
|
|
46330
46333
|
animate: { opacity: 1, x: 0 },
|
|
46331
|
-
exit: { opacity: 0, x:
|
|
46332
|
-
className: "flex items-center gap-2",
|
|
46334
|
+
exit: { opacity: 0, x: -10 },
|
|
46335
|
+
className: "flex items-center gap-2 overflow-hidden",
|
|
46333
46336
|
children: [
|
|
46334
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(XerticaOrbe, { size: 32 }),
|
|
46335
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground", children: "Assistente Xertica" })
|
|
46337
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(XerticaOrbe, { size: 32 }) }),
|
|
46338
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground font-medium truncate", children: "Assistente Xertica" })
|
|
46336
46339
|
]
|
|
46337
46340
|
}
|
|
46338
46341
|
),
|
|
@@ -46343,7 +46346,7 @@ function XerticaAssistant({
|
|
|
46343
46346
|
variant: "ghost",
|
|
46344
46347
|
size: "sm",
|
|
46345
46348
|
onClick: onNavigateFullPage,
|
|
46346
|
-
className: "p-
|
|
46349
|
+
className: "h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
46347
46350
|
title: "Expandir assistente",
|
|
46348
46351
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-4 h-4" })
|
|
46349
46352
|
}
|
|
@@ -46354,7 +46357,11 @@ function XerticaAssistant({
|
|
|
46354
46357
|
variant: "ghost",
|
|
46355
46358
|
size: "sm",
|
|
46356
46359
|
onClick: handleToggle,
|
|
46357
|
-
className:
|
|
46360
|
+
className: cn(
|
|
46361
|
+
"h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
46362
|
+
!isExpanded && "w-10 h-10"
|
|
46363
|
+
// Slightly larger touch target when collapsed if desired, or keep consistent
|
|
46364
|
+
),
|
|
46358
46365
|
children: isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PanelRight, { className: "w-4 h-4" })
|
|
46359
46366
|
}
|
|
46360
46367
|
)
|
|
@@ -47728,7 +47735,8 @@ const GOOGLE_MAPS_LIBRARIES = ["marker", "places", "geometry", "drawing"];
|
|
|
47728
47735
|
const GOOGLE_MAPS_ID = "xertica-google-map-script";
|
|
47729
47736
|
const GoogleMapsContext = createContext({
|
|
47730
47737
|
isLoaded: false,
|
|
47731
|
-
loadError: void 0
|
|
47738
|
+
loadError: void 0,
|
|
47739
|
+
load: () => Promise.resolve()
|
|
47732
47740
|
});
|
|
47733
47741
|
function getInitialApiKey() {
|
|
47734
47742
|
if (typeof window === "undefined") return void 0;
|
|
@@ -47849,7 +47857,8 @@ function getOrCreateSingleton() {
|
|
|
47849
47857
|
window.__XERTICA_GOOGLE_MAPS_LOADER__ = {
|
|
47850
47858
|
isLoaded: isPreloaded,
|
|
47851
47859
|
loadError: void 0,
|
|
47852
|
-
listeners: /* @__PURE__ */ new Set()
|
|
47860
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
47861
|
+
scriptElement: void 0
|
|
47853
47862
|
};
|
|
47854
47863
|
}
|
|
47855
47864
|
return window.__XERTICA_GOOGLE_MAPS_LOADER__;
|
|
@@ -47859,16 +47868,40 @@ function updateSingleton(state) {
|
|
|
47859
47868
|
if (!singleton) return;
|
|
47860
47869
|
if (state.isLoaded !== void 0) singleton.isLoaded = state.isLoaded;
|
|
47861
47870
|
if (state.loadError !== void 0) singleton.loadError = state.loadError;
|
|
47862
|
-
const newState = {
|
|
47871
|
+
const newState = {
|
|
47872
|
+
isLoaded: singleton.isLoaded,
|
|
47873
|
+
loadError: singleton.loadError,
|
|
47874
|
+
load: async (apiKey) => {
|
|
47875
|
+
if (singleton.isLoaded) return;
|
|
47876
|
+
try {
|
|
47877
|
+
await loadGoogleMapsScript(apiKey);
|
|
47878
|
+
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47879
|
+
} catch (error) {
|
|
47880
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
47881
|
+
throw error;
|
|
47882
|
+
}
|
|
47883
|
+
}
|
|
47884
|
+
};
|
|
47863
47885
|
singleton.listeners.forEach((listener) => listener(newState));
|
|
47864
47886
|
}
|
|
47865
47887
|
const SingletonLoaderWrapper = ({ children }) => {
|
|
47866
47888
|
const [state, setState] = useState(() => {
|
|
47867
47889
|
const singleton = getOrCreateSingleton();
|
|
47868
|
-
|
|
47890
|
+
const loadFn = async (apiKey) => {
|
|
47891
|
+
if (singleton == null ? void 0 : singleton.isLoaded) return;
|
|
47892
|
+
try {
|
|
47893
|
+
await loadGoogleMapsScript(apiKey);
|
|
47894
|
+
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47895
|
+
} catch (error) {
|
|
47896
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
47897
|
+
throw error;
|
|
47898
|
+
}
|
|
47899
|
+
};
|
|
47900
|
+
if (!singleton) return { isLoaded: false, loadError: void 0, load: loadFn };
|
|
47869
47901
|
return {
|
|
47870
47902
|
isLoaded: singleton.isLoaded,
|
|
47871
|
-
loadError: singleton.loadError
|
|
47903
|
+
loadError: singleton.loadError,
|
|
47904
|
+
load: loadFn
|
|
47872
47905
|
};
|
|
47873
47906
|
});
|
|
47874
47907
|
useEffect(() => {
|
|
@@ -47878,14 +47911,18 @@ const SingletonLoaderWrapper = ({ children }) => {
|
|
|
47878
47911
|
setState(newState);
|
|
47879
47912
|
};
|
|
47880
47913
|
singleton.listeners.add(listener);
|
|
47881
|
-
listener({
|
|
47914
|
+
listener({
|
|
47915
|
+
isLoaded: singleton.isLoaded,
|
|
47916
|
+
loadError: singleton.loadError,
|
|
47917
|
+
load: state.load
|
|
47918
|
+
});
|
|
47882
47919
|
return () => {
|
|
47883
47920
|
singleton.listeners.delete(listener);
|
|
47884
47921
|
};
|
|
47885
47922
|
}, []);
|
|
47886
47923
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(GoogleMapsContext.Provider, { value: state, children });
|
|
47887
47924
|
};
|
|
47888
|
-
const LoaderInitializer = () => {
|
|
47925
|
+
const LoaderInitializer = ({ apiKey }) => {
|
|
47889
47926
|
const hasInitializedRef = useRef(false);
|
|
47890
47927
|
useEffect(() => {
|
|
47891
47928
|
if (hasInitializedRef.current) {
|
|
@@ -47899,8 +47936,8 @@ const LoaderInitializer = () => {
|
|
|
47899
47936
|
return;
|
|
47900
47937
|
}
|
|
47901
47938
|
hasInitializedRef.current = true;
|
|
47902
|
-
const
|
|
47903
|
-
if (!
|
|
47939
|
+
const keyToUse = apiKey || getInitialApiKey();
|
|
47940
|
+
if (!keyToUse) {
|
|
47904
47941
|
updateSingleton({
|
|
47905
47942
|
isLoaded: false,
|
|
47906
47943
|
loadError: void 0
|
|
@@ -47908,15 +47945,15 @@ const LoaderInitializer = () => {
|
|
|
47908
47945
|
});
|
|
47909
47946
|
return;
|
|
47910
47947
|
}
|
|
47911
|
-
loadGoogleMapsScript(
|
|
47948
|
+
loadGoogleMapsScript(keyToUse).then(() => {
|
|
47912
47949
|
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47913
47950
|
}).catch((error) => {
|
|
47914
47951
|
updateSingleton({ isLoaded: false, loadError: error });
|
|
47915
47952
|
});
|
|
47916
|
-
}, []);
|
|
47953
|
+
}, [apiKey]);
|
|
47917
47954
|
return null;
|
|
47918
47955
|
};
|
|
47919
|
-
const GoogleMapsLoaderProvider = ({ children }) => {
|
|
47956
|
+
const GoogleMapsLoaderProvider = ({ children, apiKey }) => {
|
|
47920
47957
|
const [shouldInitialize] = useState(() => {
|
|
47921
47958
|
const singleton = getOrCreateSingleton();
|
|
47922
47959
|
if (!singleton) return false;
|
|
@@ -47927,7 +47964,7 @@ const GoogleMapsLoaderProvider = ({ children }) => {
|
|
|
47927
47964
|
return true;
|
|
47928
47965
|
});
|
|
47929
47966
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
47930
|
-
shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, {}),
|
|
47967
|
+
shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, { apiKey }),
|
|
47931
47968
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SingletonLoaderWrapper, { children })
|
|
47932
47969
|
] });
|
|
47933
47970
|
};
|
|
@@ -50502,7 +50539,9 @@ function Sidebar({
|
|
|
50502
50539
|
onLogout,
|
|
50503
50540
|
location,
|
|
50504
50541
|
navigate,
|
|
50505
|
-
routes: routes2
|
|
50542
|
+
routes: routes2,
|
|
50543
|
+
logo,
|
|
50544
|
+
logoCollapsed
|
|
50506
50545
|
}) {
|
|
50507
50546
|
const navRef = useRef(null);
|
|
50508
50547
|
const [hasOverflow, setHasOverflow] = useState(false);
|
|
@@ -50659,13 +50698,13 @@ function Sidebar({
|
|
|
50659
50698
|
"div",
|
|
50660
50699
|
{
|
|
50661
50700
|
className: `flex items-center h-10 ${expanded ? "justify-center" : "justify-center"}`,
|
|
50662
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50701
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? logo || /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50663
50702
|
XerticaLogo,
|
|
50664
50703
|
{
|
|
50665
50704
|
className: "h-5 w-auto",
|
|
50666
50705
|
variant: "white"
|
|
50667
50706
|
}
|
|
50668
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50707
|
+
) : logoCollapsed || /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50669
50708
|
XerticaXLogo,
|
|
50670
50709
|
{
|
|
50671
50710
|
className: "h-5 w-auto",
|
|
@@ -54854,7 +54893,8 @@ function TemplatePage({ user, onLogout }) {
|
|
|
54854
54893
|
XerticaAssistant,
|
|
54855
54894
|
{
|
|
54856
54895
|
isExpanded: assistenteExpanded,
|
|
54857
|
-
onToggle: toggleAssistente
|
|
54896
|
+
onToggle: toggleAssistente,
|
|
54897
|
+
onEvaluation: (id2, type, reason) => console.log("Feedback:", id2, type, reason)
|
|
54858
54898
|
}
|
|
54859
54899
|
)
|
|
54860
54900
|
] });
|
|
@@ -69221,6 +69261,12 @@ const MapContent = React__default.forwardRef(
|
|
|
69221
69261
|
}
|
|
69222
69262
|
}, []);
|
|
69223
69263
|
useEffect(() => {
|
|
69264
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
69265
|
+
const { load } = useGoogleMapsLoader();
|
|
69266
|
+
if (load) {
|
|
69267
|
+
load(apiKey).catch(console.error);
|
|
69268
|
+
}
|
|
69269
|
+
}
|
|
69224
69270
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
69225
69271
|
isInitializedRef.current = true;
|
|
69226
69272
|
const map2 = new google.maps.Map(mapContainerRef.current, {
|
|
@@ -69242,7 +69288,7 @@ const MapContent = React__default.forwardRef(
|
|
|
69242
69288
|
isInitializedRef.current = false;
|
|
69243
69289
|
mapRef.current = null;
|
|
69244
69290
|
};
|
|
69245
|
-
}, [isLoaded]);
|
|
69291
|
+
}, [isLoaded, apiKey]);
|
|
69246
69292
|
useEffect(() => {
|
|
69247
69293
|
var _a, _b;
|
|
69248
69294
|
const map2 = mapRef.current;
|
|
@@ -69517,6 +69563,12 @@ const RouteMapContent = React__default.forwardRef(
|
|
|
69517
69563
|
const isInitializedRef = useRef(false);
|
|
69518
69564
|
const isCalculatingRef = useRef(false);
|
|
69519
69565
|
useEffect(() => {
|
|
69566
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
69567
|
+
const { load } = useGoogleMapsLoader();
|
|
69568
|
+
if (load) {
|
|
69569
|
+
load(apiKey).catch(console.error);
|
|
69570
|
+
}
|
|
69571
|
+
}
|
|
69520
69572
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
69521
69573
|
isInitializedRef.current = true;
|
|
69522
69574
|
const map2 = new google.maps.Map(mapContainerRef.current, {
|
|
@@ -69549,7 +69601,7 @@ const RouteMapContent = React__default.forwardRef(
|
|
|
69549
69601
|
isInitializedRef.current = false;
|
|
69550
69602
|
mapRef.current = null;
|
|
69551
69603
|
};
|
|
69552
|
-
}, [isLoaded]);
|
|
69604
|
+
}, [isLoaded, apiKey]);
|
|
69553
69605
|
useEffect(() => {
|
|
69554
69606
|
const map2 = mapRef.current;
|
|
69555
69607
|
const renderer = directionsRendererRef.current;
|
package/dist/index.umd.js
CHANGED
|
@@ -46029,7 +46029,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
46029
46029
|
}
|
|
46030
46030
|
}, [mensagens, abaSelecionada]);
|
|
46031
46031
|
React.useEffect(() => {
|
|
46032
|
-
if (initialMessages.length > 0) {
|
|
46032
|
+
if (initialMessages && initialMessages.length > 0) {
|
|
46033
46033
|
setMensagens(initialMessages);
|
|
46034
46034
|
}
|
|
46035
46035
|
}, [initialMessages]);
|
|
@@ -46340,18 +46340,21 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
46340
46340
|
!isFullPage && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
46341
46341
|
"div",
|
|
46342
46342
|
{
|
|
46343
|
-
className:
|
|
46343
|
+
className: cn(
|
|
46344
|
+
"border-b border-border flex items-center py-3",
|
|
46345
|
+
isExpanded ? "justify-between px-4 py-4" : "justify-center px-0"
|
|
46346
|
+
),
|
|
46344
46347
|
children: [
|
|
46345
46348
|
isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
46346
46349
|
motion.div,
|
|
46347
46350
|
{
|
|
46348
|
-
initial: { opacity: 0, x:
|
|
46351
|
+
initial: { opacity: 0, x: -10 },
|
|
46349
46352
|
animate: { opacity: 1, x: 0 },
|
|
46350
|
-
exit: { opacity: 0, x:
|
|
46351
|
-
className: "flex items-center gap-2",
|
|
46353
|
+
exit: { opacity: 0, x: -10 },
|
|
46354
|
+
className: "flex items-center gap-2 overflow-hidden",
|
|
46352
46355
|
children: [
|
|
46353
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(XerticaOrbe, { size: 32 }),
|
|
46354
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground", children: "Assistente Xertica" })
|
|
46356
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(XerticaOrbe, { size: 32 }) }),
|
|
46357
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground font-medium truncate", children: "Assistente Xertica" })
|
|
46355
46358
|
]
|
|
46356
46359
|
}
|
|
46357
46360
|
),
|
|
@@ -46362,7 +46365,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
46362
46365
|
variant: "ghost",
|
|
46363
46366
|
size: "sm",
|
|
46364
46367
|
onClick: onNavigateFullPage,
|
|
46365
|
-
className: "p-
|
|
46368
|
+
className: "h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
46366
46369
|
title: "Expandir assistente",
|
|
46367
46370
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-4 h-4" })
|
|
46368
46371
|
}
|
|
@@ -46373,7 +46376,11 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
46373
46376
|
variant: "ghost",
|
|
46374
46377
|
size: "sm",
|
|
46375
46378
|
onClick: handleToggle,
|
|
46376
|
-
className:
|
|
46379
|
+
className: cn(
|
|
46380
|
+
"h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
46381
|
+
!isExpanded && "w-10 h-10"
|
|
46382
|
+
// Slightly larger touch target when collapsed if desired, or keep consistent
|
|
46383
|
+
),
|
|
46377
46384
|
children: isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PanelRight, { className: "w-4 h-4" })
|
|
46378
46385
|
}
|
|
46379
46386
|
)
|
|
@@ -47747,7 +47754,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47747
47754
|
const GOOGLE_MAPS_ID = "xertica-google-map-script";
|
|
47748
47755
|
const GoogleMapsContext = React.createContext({
|
|
47749
47756
|
isLoaded: false,
|
|
47750
|
-
loadError: void 0
|
|
47757
|
+
loadError: void 0,
|
|
47758
|
+
load: () => Promise.resolve()
|
|
47751
47759
|
});
|
|
47752
47760
|
function getInitialApiKey() {
|
|
47753
47761
|
if (typeof window === "undefined") return void 0;
|
|
@@ -47868,7 +47876,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47868
47876
|
window.__XERTICA_GOOGLE_MAPS_LOADER__ = {
|
|
47869
47877
|
isLoaded: isPreloaded,
|
|
47870
47878
|
loadError: void 0,
|
|
47871
|
-
listeners: /* @__PURE__ */ new Set()
|
|
47879
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
47880
|
+
scriptElement: void 0
|
|
47872
47881
|
};
|
|
47873
47882
|
}
|
|
47874
47883
|
return window.__XERTICA_GOOGLE_MAPS_LOADER__;
|
|
@@ -47878,16 +47887,40 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47878
47887
|
if (!singleton) return;
|
|
47879
47888
|
if (state.isLoaded !== void 0) singleton.isLoaded = state.isLoaded;
|
|
47880
47889
|
if (state.loadError !== void 0) singleton.loadError = state.loadError;
|
|
47881
|
-
const newState = {
|
|
47890
|
+
const newState = {
|
|
47891
|
+
isLoaded: singleton.isLoaded,
|
|
47892
|
+
loadError: singleton.loadError,
|
|
47893
|
+
load: async (apiKey) => {
|
|
47894
|
+
if (singleton.isLoaded) return;
|
|
47895
|
+
try {
|
|
47896
|
+
await loadGoogleMapsScript(apiKey);
|
|
47897
|
+
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47898
|
+
} catch (error) {
|
|
47899
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
47900
|
+
throw error;
|
|
47901
|
+
}
|
|
47902
|
+
}
|
|
47903
|
+
};
|
|
47882
47904
|
singleton.listeners.forEach((listener) => listener(newState));
|
|
47883
47905
|
}
|
|
47884
47906
|
const SingletonLoaderWrapper = ({ children }) => {
|
|
47885
47907
|
const [state, setState] = React.useState(() => {
|
|
47886
47908
|
const singleton = getOrCreateSingleton();
|
|
47887
|
-
|
|
47909
|
+
const loadFn = async (apiKey) => {
|
|
47910
|
+
if (singleton == null ? void 0 : singleton.isLoaded) return;
|
|
47911
|
+
try {
|
|
47912
|
+
await loadGoogleMapsScript(apiKey);
|
|
47913
|
+
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47914
|
+
} catch (error) {
|
|
47915
|
+
updateSingleton({ isLoaded: false, loadError: error });
|
|
47916
|
+
throw error;
|
|
47917
|
+
}
|
|
47918
|
+
};
|
|
47919
|
+
if (!singleton) return { isLoaded: false, loadError: void 0, load: loadFn };
|
|
47888
47920
|
return {
|
|
47889
47921
|
isLoaded: singleton.isLoaded,
|
|
47890
|
-
loadError: singleton.loadError
|
|
47922
|
+
loadError: singleton.loadError,
|
|
47923
|
+
load: loadFn
|
|
47891
47924
|
};
|
|
47892
47925
|
});
|
|
47893
47926
|
React.useEffect(() => {
|
|
@@ -47897,14 +47930,18 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47897
47930
|
setState(newState);
|
|
47898
47931
|
};
|
|
47899
47932
|
singleton.listeners.add(listener);
|
|
47900
|
-
listener({
|
|
47933
|
+
listener({
|
|
47934
|
+
isLoaded: singleton.isLoaded,
|
|
47935
|
+
loadError: singleton.loadError,
|
|
47936
|
+
load: state.load
|
|
47937
|
+
});
|
|
47901
47938
|
return () => {
|
|
47902
47939
|
singleton.listeners.delete(listener);
|
|
47903
47940
|
};
|
|
47904
47941
|
}, []);
|
|
47905
47942
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(GoogleMapsContext.Provider, { value: state, children });
|
|
47906
47943
|
};
|
|
47907
|
-
const LoaderInitializer = () => {
|
|
47944
|
+
const LoaderInitializer = ({ apiKey }) => {
|
|
47908
47945
|
const hasInitializedRef = React.useRef(false);
|
|
47909
47946
|
React.useEffect(() => {
|
|
47910
47947
|
if (hasInitializedRef.current) {
|
|
@@ -47918,8 +47955,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47918
47955
|
return;
|
|
47919
47956
|
}
|
|
47920
47957
|
hasInitializedRef.current = true;
|
|
47921
|
-
const
|
|
47922
|
-
if (!
|
|
47958
|
+
const keyToUse = apiKey || getInitialApiKey();
|
|
47959
|
+
if (!keyToUse) {
|
|
47923
47960
|
updateSingleton({
|
|
47924
47961
|
isLoaded: false,
|
|
47925
47962
|
loadError: void 0
|
|
@@ -47927,15 +47964,15 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47927
47964
|
});
|
|
47928
47965
|
return;
|
|
47929
47966
|
}
|
|
47930
|
-
loadGoogleMapsScript(
|
|
47967
|
+
loadGoogleMapsScript(keyToUse).then(() => {
|
|
47931
47968
|
updateSingleton({ isLoaded: true, loadError: void 0 });
|
|
47932
47969
|
}).catch((error) => {
|
|
47933
47970
|
updateSingleton({ isLoaded: false, loadError: error });
|
|
47934
47971
|
});
|
|
47935
|
-
}, []);
|
|
47972
|
+
}, [apiKey]);
|
|
47936
47973
|
return null;
|
|
47937
47974
|
};
|
|
47938
|
-
const GoogleMapsLoaderProvider = ({ children }) => {
|
|
47975
|
+
const GoogleMapsLoaderProvider = ({ children, apiKey }) => {
|
|
47939
47976
|
const [shouldInitialize] = React.useState(() => {
|
|
47940
47977
|
const singleton = getOrCreateSingleton();
|
|
47941
47978
|
if (!singleton) return false;
|
|
@@ -47946,7 +47983,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
47946
47983
|
return true;
|
|
47947
47984
|
});
|
|
47948
47985
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
47949
|
-
shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, {}),
|
|
47986
|
+
shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, { apiKey }),
|
|
47950
47987
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SingletonLoaderWrapper, { children })
|
|
47951
47988
|
] });
|
|
47952
47989
|
};
|
|
@@ -50521,7 +50558,9 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
|
|
|
50521
50558
|
onLogout,
|
|
50522
50559
|
location: location2,
|
|
50523
50560
|
navigate,
|
|
50524
|
-
routes: routes2
|
|
50561
|
+
routes: routes2,
|
|
50562
|
+
logo,
|
|
50563
|
+
logoCollapsed
|
|
50525
50564
|
}) {
|
|
50526
50565
|
const navRef = React.useRef(null);
|
|
50527
50566
|
const [hasOverflow, setHasOverflow] = React.useState(false);
|
|
@@ -50678,13 +50717,13 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
|
|
|
50678
50717
|
"div",
|
|
50679
50718
|
{
|
|
50680
50719
|
className: `flex items-center h-10 ${expanded ? "justify-center" : "justify-center"}`,
|
|
50681
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50720
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? logo || /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50682
50721
|
XerticaLogo,
|
|
50683
50722
|
{
|
|
50684
50723
|
className: "h-5 w-auto",
|
|
50685
50724
|
variant: "white"
|
|
50686
50725
|
}
|
|
50687
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50726
|
+
) : logoCollapsed || /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50688
50727
|
XerticaXLogo,
|
|
50689
50728
|
{
|
|
50690
50729
|
className: "h-5 w-auto",
|
|
@@ -54873,7 +54912,8 @@ Defaulting to \`null\`.`;
|
|
|
54873
54912
|
XerticaAssistant,
|
|
54874
54913
|
{
|
|
54875
54914
|
isExpanded: assistenteExpanded,
|
|
54876
|
-
onToggle: toggleAssistente
|
|
54915
|
+
onToggle: toggleAssistente,
|
|
54916
|
+
onEvaluation: (id2, type, reason) => console.log("Feedback:", id2, type, reason)
|
|
54877
54917
|
}
|
|
54878
54918
|
)
|
|
54879
54919
|
] });
|
|
@@ -69240,6 +69280,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
|
|
|
69240
69280
|
}
|
|
69241
69281
|
}, []);
|
|
69242
69282
|
React.useEffect(() => {
|
|
69283
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
69284
|
+
const { load } = useGoogleMapsLoader();
|
|
69285
|
+
if (load) {
|
|
69286
|
+
load(apiKey).catch(console.error);
|
|
69287
|
+
}
|
|
69288
|
+
}
|
|
69243
69289
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
69244
69290
|
isInitializedRef.current = true;
|
|
69245
69291
|
const map2 = new google.maps.Map(mapContainerRef.current, {
|
|
@@ -69261,7 +69307,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
|
|
|
69261
69307
|
isInitializedRef.current = false;
|
|
69262
69308
|
mapRef.current = null;
|
|
69263
69309
|
};
|
|
69264
|
-
}, [isLoaded]);
|
|
69310
|
+
}, [isLoaded, apiKey]);
|
|
69265
69311
|
React.useEffect(() => {
|
|
69266
69312
|
var _a, _b;
|
|
69267
69313
|
const map2 = mapRef.current;
|
|
@@ -69536,6 +69582,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
|
|
|
69536
69582
|
const isInitializedRef = React.useRef(false);
|
|
69537
69583
|
const isCalculatingRef = React.useRef(false);
|
|
69538
69584
|
React.useEffect(() => {
|
|
69585
|
+
if (!isLoaded && apiKey && !loadError) {
|
|
69586
|
+
const { load } = useGoogleMapsLoader();
|
|
69587
|
+
if (load) {
|
|
69588
|
+
load(apiKey).catch(console.error);
|
|
69589
|
+
}
|
|
69590
|
+
}
|
|
69539
69591
|
if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
|
|
69540
69592
|
isInitializedRef.current = true;
|
|
69541
69593
|
const map2 = new google.maps.Map(mapContainerRef.current, {
|
|
@@ -69568,7 +69620,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
|
|
|
69568
69620
|
isInitializedRef.current = false;
|
|
69569
69621
|
mapRef.current = null;
|
|
69570
69622
|
};
|
|
69571
|
-
}, [isLoaded]);
|
|
69623
|
+
}, [isLoaded, apiKey]);
|
|
69572
69624
|
React.useEffect(() => {
|
|
69573
69625
|
const map2 = mapRef.current;
|
|
69574
69626
|
const renderer = directionsRendererRef.current;
|