xertica-ui 2.6.0 → 2.7.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -1
  3. package/components/assistant/xertica-assistant/use-assistant.ts +5 -6
  4. package/{templates/src/features/auth/ui → components/blocks/auth}/AuthPageShell.tsx +8 -3
  5. package/components/blocks/auth/PasswordStrengthMeter.tsx +41 -0
  6. package/components/blocks/auth/SocialLoginButtons.tsx +95 -0
  7. package/components/blocks/auth/index.ts +11 -0
  8. package/components/blocks/auth/usePasswordStrength.ts +13 -0
  9. package/components/blocks/index.ts +1 -0
  10. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +45 -139
  11. package/components/pages/login-page/LoginPage.tsx +52 -145
  12. package/components/pages/reset-password-page/ResetPasswordPage.tsx +79 -169
  13. package/components/pages/verify-email-page/VerifyEmailPage.tsx +48 -150
  14. package/dist/AssistantChart-CImCNLfD.cjs +3551 -0
  15. package/dist/AssistantChart-DfdIfmQr.js +3383 -0
  16. package/dist/FeatureCard-BhpfmPPx.js +485 -0
  17. package/dist/FeatureCard-D-5yS_OD.cjs +497 -0
  18. package/dist/ImageWithFallback-CfkAkctC.cjs +122 -0
  19. package/dist/ImageWithFallback-bw-CxxDc.js +98 -0
  20. package/dist/LanguageContext-CX_zdxre.js +1912 -0
  21. package/dist/LanguageContext-CjhSSqJT.cjs +1917 -0
  22. package/dist/LanguageSelector-BR3Ss0k_.js +46 -0
  23. package/dist/LanguageSelector-CHOLPmHr.cjs +48 -0
  24. package/dist/PasswordStrengthMeter-C8irs0G1.js +173 -0
  25. package/dist/PasswordStrengthMeter-MLzhax-d.cjs +179 -0
  26. package/dist/ThemeContext-CEY9pCn-.cjs +86 -0
  27. package/dist/ThemeContext-Dk3tH7Ym.js +83 -0
  28. package/dist/ThemeToggle-BpM_iHh8.js +215 -0
  29. package/dist/ThemeToggle-CZRlv0d4.cjs +219 -0
  30. package/dist/VerifyEmailPage-BKiaw2YK.js +2954 -0
  31. package/dist/VerifyEmailPage-Beaicc6V.cjs +2963 -0
  32. package/dist/VerifyEmailPage-BehPBp0F.cjs +2963 -0
  33. package/dist/VerifyEmailPage-Djb6hthM.js +2954 -0
  34. package/dist/XerticaProvider-BijpC_py.cjs +46 -0
  35. package/dist/XerticaProvider-C2wDRQhT.js +44 -0
  36. package/dist/alert-dialog-BzIcTKn_.cjs +872 -0
  37. package/dist/alert-dialog-kty5pxQp.js +819 -0
  38. package/dist/assistant.cjs.js +1 -1
  39. package/dist/assistant.es.js +1 -1
  40. package/dist/blocks.cjs.js +7 -3
  41. package/dist/blocks.es.js +2 -2
  42. package/dist/brand.cjs.js +7 -6
  43. package/dist/brand.es.js +3 -2
  44. package/dist/components/blocks/auth/AuthPageShell.d.ts +12 -0
  45. package/dist/components/blocks/auth/PasswordStrengthMeter.d.ts +7 -0
  46. package/dist/components/blocks/auth/SocialLoginButtons.d.ts +8 -0
  47. package/dist/components/blocks/auth/index.d.ts +8 -0
  48. package/dist/components/blocks/auth/usePasswordStrength.d.ts +3 -0
  49. package/dist/components/blocks/index.d.ts +1 -0
  50. package/dist/components/pages/reset-password-page/ResetPasswordPage.d.ts +1 -1
  51. package/dist/hooks.cjs.js +5 -4
  52. package/dist/hooks.es.js +2 -1
  53. package/dist/index.cjs.js +29 -24
  54. package/dist/index.es.js +12 -11
  55. package/dist/layout.cjs.js +1 -1
  56. package/dist/layout.es.js +1 -1
  57. package/dist/pages.cjs.js +1 -1
  58. package/dist/pages.es.js +1 -1
  59. package/dist/sidebar-B7YzwAp3.js +1151 -0
  60. package/dist/sidebar-Cb0U7NsV.cjs +1154 -0
  61. package/dist/ui.cjs.js +7 -7
  62. package/dist/ui.es.js +3 -3
  63. package/dist/xertica-assistant-8fh8KA2K.js +2173 -0
  64. package/dist/xertica-assistant-BjfG3zyL.cjs +2180 -0
  65. package/docs/i18n.md +2 -0
  66. package/package.json +1 -1
  67. package/templates/package.json +2 -2
  68. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +1 -2
  69. package/templates/src/features/auth/ui/LoginContent.tsx +1 -2
  70. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +3 -57
  71. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +1 -2
  72. package/templates/src/features/home/index.ts +0 -10
  73. package/templates/src/features/home/ui/HomeContent.tsx +21 -75
  74. package/templates/src/features/template/index.ts +0 -4
  75. package/templates/src/features/template/ui/TemplateContent.tsx +26 -1279
  76. package/templates/src/locales/en/pages/templates.json +5 -313
  77. package/templates/src/locales/es/pages/templates.json +5 -313
  78. package/templates/src/locales/pt-BR/pages/templates.json +5 -313
  79. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +0 -78
  80. package/templates/src/features/home/data/mock.ts +0 -41
  81. package/templates/src/features/home/hooks/useFeatureCards.ts +0 -20
  82. package/templates/src/features/home/store/dashboardStore.ts +0 -25
  83. package/templates/src/features/template/ui/CrudTemplate.tsx +0 -112
  84. package/templates/src/features/template/ui/DashboardTemplate.tsx +0 -110
  85. package/templates/src/features/template/ui/FormTemplate.tsx +0 -117
  86. package/templates/src/features/template/ui/LoginTemplate.tsx +0 -59
  87. package/templates/src/locales/en/pages/crudTemplate.json +0 -25
  88. package/templates/src/locales/en/pages/dashboardTemplate.json +0 -20
  89. package/templates/src/locales/en/pages/formTemplate.json +0 -16
  90. package/templates/src/locales/en/pages/loginTemplate.json +0 -9
  91. package/templates/src/locales/es/pages/crudTemplate.json +0 -25
  92. package/templates/src/locales/es/pages/dashboardTemplate.json +0 -20
  93. package/templates/src/locales/es/pages/formTemplate.json +0 -16
  94. package/templates/src/locales/es/pages/loginTemplate.json +0 -9
  95. package/templates/src/locales/pt-BR/pages/crudTemplate.json +0 -25
  96. package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +0 -20
  97. package/templates/src/locales/pt-BR/pages/formTemplate.json +0 -16
  98. package/templates/src/locales/pt-BR/pages/loginTemplate.json +0 -9
  99. package/templates/vite.config.d.ts +0 -2
  100. package/templates/vite.config.js +0 -20
@@ -0,0 +1,872 @@
1
+ 'use strict';
2
+
3
+ const jsxRuntime = require('react/jsx-runtime');
4
+ const LabelPrimitive = require('@radix-ui/react-label');
5
+ const button = require('./button-0BlA47It.cjs');
6
+ const lucideReact = require('lucide-react');
7
+ const TabsPrimitive = require('@radix-ui/react-tabs');
8
+ const React = require('react');
9
+ const CheckboxPrimitive = require('@radix-ui/react-checkbox');
10
+ const RadioGroupPrimitive = require('@radix-ui/react-radio-group');
11
+ const SwitchPrimitive = require('@radix-ui/react-switch');
12
+ const SeparatorPrimitive = require('@radix-ui/react-separator');
13
+ const client = require('react-dom/client');
14
+ const DOMPurify = require('dompurify');
15
+ const googleMapsLoader = require('./google-maps-loader-DfeBRI8Q.cjs');
16
+ const AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
17
+
18
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
19
+ function _interopNamespaceDefault(e) {
20
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
21
+ if (e) {
22
+ for (const k in e) {
23
+ if (k !== 'default') {
24
+ const d = Object.getOwnPropertyDescriptor(e, k);
25
+ Object.defineProperty(n, k, d.get ? d : {
26
+ enumerable: true,
27
+ get: () => e[k]
28
+ });
29
+ }
30
+ }
31
+ }
32
+ n.default = e;
33
+ return Object.freeze(n);
34
+ }
35
+
36
+ const LabelPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(LabelPrimitive);
37
+ const TabsPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TabsPrimitive);
38
+ const React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
39
+ const CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CheckboxPrimitive);
40
+ const RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(RadioGroupPrimitive);
41
+ const SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(SwitchPrimitive);
42
+ const SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(SeparatorPrimitive);
43
+ const AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(AlertDialogPrimitive);
44
+
45
+ function Label({
46
+ className,
47
+ size = "md",
48
+ ...props
49
+ }) {
50
+ const sizeClasses = {
51
+ sm: "text-xs",
52
+ md: "text-sm",
53
+ lg: "text-base"
54
+ };
55
+ return /* @__PURE__ */ jsxRuntime.jsx(
56
+ LabelPrimitive__namespace.Root,
57
+ {
58
+ "data-slot": "label",
59
+ className: button.cn(
60
+ "flex items-center gap-2 leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
61
+ sizeClasses[size],
62
+ className
63
+ ),
64
+ ...props
65
+ }
66
+ );
67
+ }
68
+
69
+ function PageHeader({
70
+ title,
71
+ subtitle,
72
+ backHref,
73
+ onBack,
74
+ renderBackLink,
75
+ actions,
76
+ className,
77
+ backLabel = "Back"
78
+ }) {
79
+ const showBack = !!(backHref || onBack || renderBackLink);
80
+ const icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-5 w-5" });
81
+ return /* @__PURE__ */ jsxRuntime.jsxs(
82
+ "div",
83
+ {
84
+ className: button.cn(
85
+ "flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-8",
86
+ className
87
+ ),
88
+ children: [
89
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-4", children: [
90
+ showBack && /* @__PURE__ */ jsxRuntime.jsx(
91
+ button.Button,
92
+ {
93
+ variant: "outline",
94
+ size: "icon",
95
+ className: "h-10 w-10 shrink-0",
96
+ onClick: onBack,
97
+ asChild: !!renderBackLink || !!backHref,
98
+ "aria-label": backLabel,
99
+ children: renderBackLink ? renderBackLink(icon) : backHref ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: backHref, children: icon }) : icon
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-1", children: [
103
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
104
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: subtitle })
105
+ ] })
106
+ ] }),
107
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: actions })
108
+ ]
109
+ }
110
+ );
111
+ }
112
+ function PageHeaderHeading({
113
+ className,
114
+ ...props
115
+ }) {
116
+ return /* @__PURE__ */ jsxRuntime.jsx(
117
+ "h1",
118
+ {
119
+ className: button.cn(
120
+ "text-3xl font-bold leading-tight tracking-tighter md:text-4xl lg:leading-[1.1]",
121
+ className
122
+ ),
123
+ ...props
124
+ }
125
+ );
126
+ }
127
+ function PageHeaderDescription({
128
+ className,
129
+ ...props
130
+ }) {
131
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: button.cn("text-lg text-muted-foreground sm:text-xl", className), ...props });
132
+ }
133
+
134
+ function Tabs({ className, ...props }) {
135
+ return /* @__PURE__ */ jsxRuntime.jsx(
136
+ TabsPrimitive__namespace.Root,
137
+ {
138
+ "data-slot": "tabs",
139
+ className: button.cn("flex flex-col gap-2", className),
140
+ ...props
141
+ }
142
+ );
143
+ }
144
+ function TabsList({ className, ...props }) {
145
+ return /* @__PURE__ */ jsxRuntime.jsx(
146
+ TabsPrimitive__namespace.List,
147
+ {
148
+ "data-slot": "tabs-list",
149
+ className: button.cn(
150
+ "relative inline-flex h-12 w-fit items-end justify-start border-b border-border bg-transparent",
151
+ className
152
+ ),
153
+ ...props
154
+ }
155
+ );
156
+ }
157
+ function TabsTrigger({ className, ...props }) {
158
+ return /* @__PURE__ */ jsxRuntime.jsx(
159
+ TabsPrimitive__namespace.Trigger,
160
+ {
161
+ "data-slot": "tabs-trigger",
162
+ className: button.cn(
163
+ "relative inline-flex h-12 items-center justify-center gap-1.5 bg-transparent px-4 py-3 text-sm font-medium whitespace-nowrap transition-all duration-200 ease-in-out border-b-2 border-transparent text-muted-foreground hover:text-foreground hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-primary data-[state=active]:border-primary data-[state=active]:bg-transparent [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
164
+ className
165
+ ),
166
+ ...props
167
+ }
168
+ );
169
+ }
170
+ function TabsContent({ className, ...props }) {
171
+ return /* @__PURE__ */ jsxRuntime.jsx(
172
+ TabsPrimitive__namespace.Content,
173
+ {
174
+ "data-slot": "tabs-content",
175
+ className: button.cn("flex-1 outline-none", className),
176
+ ...props
177
+ }
178
+ );
179
+ }
180
+
181
+ const Checkbox = React__namespace.forwardRef(({ className, size = "md", ...props }, ref) => {
182
+ const sizeClasses = {
183
+ sm: "size-3.5",
184
+ md: "size-4",
185
+ lg: "size-5"
186
+ };
187
+ const iconSizeClasses = {
188
+ sm: "size-3",
189
+ md: "size-3.5",
190
+ lg: "size-4"
191
+ };
192
+ return /* @__PURE__ */ jsxRuntime.jsx(
193
+ CheckboxPrimitive__namespace.Root,
194
+ {
195
+ ref,
196
+ "data-slot": "checkbox",
197
+ className: button.cn(
198
+ "peer border bg-white dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
199
+ sizeClasses[size],
200
+ className
201
+ ),
202
+ ...props,
203
+ children: /* @__PURE__ */ jsxRuntime.jsx(
204
+ CheckboxPrimitive__namespace.Indicator,
205
+ {
206
+ "data-slot": "checkbox-indicator",
207
+ className: "flex items-center justify-center text-current transition-none",
208
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: iconSizeClasses[size] })
209
+ }
210
+ )
211
+ }
212
+ );
213
+ });
214
+ Checkbox.displayName = CheckboxPrimitive__namespace.Root.displayName;
215
+
216
+ const RadioGroup = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Root, { className: button.cn("grid gap-4", className), ...props, ref }));
217
+ RadioGroup.displayName = RadioGroupPrimitive__namespace.Root.displayName;
218
+ const RadioGroupItem = React__namespace.forwardRef(({ className, size = "md", ...props }, ref) => {
219
+ const sizeClasses = {
220
+ sm: "size-4",
221
+ md: "size-5",
222
+ lg: "size-6"
223
+ };
224
+ const dotSizeClasses = {
225
+ sm: "size-2",
226
+ md: "size-2.5",
227
+ lg: "size-3"
228
+ };
229
+ return /* @__PURE__ */ jsxRuntime.jsx(
230
+ RadioGroupPrimitive__namespace.Item,
231
+ {
232
+ ref,
233
+ "data-slot": "radio-group-item",
234
+ className: button.cn(
235
+ // Base styles - Material UI inspired
236
+ "relative aspect-square shrink-0 rounded-full border-2 transition-all duration-200 outline-none cursor-pointer",
237
+ // Default state - sempre com contorno usando variáveis CSS
238
+ "border-muted-foreground bg-background",
239
+ // Hover state - usa variável primary
240
+ "hover:border-primary hover:shadow-md",
241
+ // Focus state - usa variável primary
242
+ "focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
243
+ // Checked state - mantém contorno com primary
244
+ "data-[state=checked]:border-primary data-[state=checked]:bg-background",
245
+ // Disabled state
246
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:border-muted",
247
+ // Invalid state - usa variável destructive
248
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
249
+ sizeClasses[size],
250
+ className
251
+ ),
252
+ ...props,
253
+ children: /* @__PURE__ */ jsxRuntime.jsx(
254
+ RadioGroupPrimitive__namespace.Indicator,
255
+ {
256
+ "data-slot": "radio-group-indicator",
257
+ className: "flex items-center justify-center",
258
+ children: /* @__PURE__ */ jsxRuntime.jsx(
259
+ "div",
260
+ {
261
+ className: button.cn(
262
+ "rounded-full bg-primary transition-all duration-200",
263
+ dotSizeClasses[size]
264
+ )
265
+ }
266
+ )
267
+ }
268
+ )
269
+ }
270
+ );
271
+ });
272
+ RadioGroupItem.displayName = RadioGroupPrimitive__namespace.Item.displayName;
273
+
274
+ const Switch = React__namespace.forwardRef(({ className, size = "md", ...props }, ref) => {
275
+ const trackClasses = {
276
+ sm: "h-3.5 w-7",
277
+ md: "h-[1.15rem] w-8",
278
+ lg: "h-[1.375rem] w-10"
279
+ };
280
+ const thumbClasses = {
281
+ sm: "size-3",
282
+ md: "size-4",
283
+ lg: "size-5"
284
+ };
285
+ return /* @__PURE__ */ jsxRuntime.jsx(
286
+ SwitchPrimitive__namespace.Root,
287
+ {
288
+ className: button.cn(
289
+ "peer inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none disabled:cursor-not-allowed disabled:opacity-50",
290
+ "data-[state=checked]:bg-primary",
291
+ "data-[state=unchecked]:bg-muted",
292
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
293
+ trackClasses[size],
294
+ className
295
+ ),
296
+ ...props,
297
+ ref,
298
+ children: /* @__PURE__ */ jsxRuntime.jsx(
299
+ SwitchPrimitive__namespace.Thumb,
300
+ {
301
+ className: button.cn(
302
+ "pointer-events-none block rounded-full ring-0 transition-transform shadow-sm",
303
+ "bg-background",
304
+ "data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0",
305
+ thumbClasses[size]
306
+ )
307
+ }
308
+ )
309
+ }
310
+ );
311
+ });
312
+ Switch.displayName = SwitchPrimitive__namespace.Root.displayName;
313
+
314
+ function Separator({
315
+ className,
316
+ orientation = "horizontal",
317
+ decorative = true,
318
+ ...props
319
+ }) {
320
+ return /* @__PURE__ */ jsxRuntime.jsx(
321
+ SeparatorPrimitive__namespace.Root,
322
+ {
323
+ "data-slot": "separator-root",
324
+ decorative,
325
+ orientation,
326
+ className: button.cn(
327
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
328
+ className
329
+ ),
330
+ ...props
331
+ }
332
+ );
333
+ }
334
+
335
+ function useMapLayers(map, layers) {
336
+ const trafficLayerRef = React.useRef(null);
337
+ const transitLayerRef = React.useRef(null);
338
+ const bicyclingLayerRef = React.useRef(null);
339
+ React.useEffect(() => {
340
+ if (!map) return;
341
+ if (layers.traffic) {
342
+ if (!trafficLayerRef.current) {
343
+ trafficLayerRef.current = new google.maps.TrafficLayer();
344
+ }
345
+ trafficLayerRef.current.setMap(map);
346
+ } else {
347
+ if (trafficLayerRef.current) {
348
+ trafficLayerRef.current.setMap(null);
349
+ }
350
+ }
351
+ return () => {
352
+ if (trafficLayerRef.current) {
353
+ trafficLayerRef.current.setMap(null);
354
+ }
355
+ };
356
+ }, [map, layers.traffic]);
357
+ React.useEffect(() => {
358
+ if (!map) return;
359
+ if (layers.transit) {
360
+ if (!transitLayerRef.current) {
361
+ transitLayerRef.current = new google.maps.TransitLayer();
362
+ }
363
+ transitLayerRef.current.setMap(map);
364
+ } else {
365
+ if (transitLayerRef.current) {
366
+ transitLayerRef.current.setMap(null);
367
+ }
368
+ }
369
+ return () => {
370
+ if (transitLayerRef.current) {
371
+ transitLayerRef.current.setMap(null);
372
+ }
373
+ };
374
+ }, [map, layers.transit]);
375
+ React.useEffect(() => {
376
+ if (!map) return;
377
+ if (layers.bicycling) {
378
+ if (!bicyclingLayerRef.current) {
379
+ bicyclingLayerRef.current = new google.maps.BicyclingLayer();
380
+ }
381
+ bicyclingLayerRef.current.setMap(map);
382
+ } else {
383
+ if (bicyclingLayerRef.current) {
384
+ bicyclingLayerRef.current.setMap(null);
385
+ }
386
+ }
387
+ return () => {
388
+ if (bicyclingLayerRef.current) {
389
+ bicyclingLayerRef.current.setMap(null);
390
+ }
391
+ };
392
+ }, [map, layers.bicycling]);
393
+ }
394
+
395
+ const __vite_import_meta_env__ = {"BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false};
396
+ const DEFAULT_CENTER = { lat: -23.5505, lng: -46.6333 };
397
+ const DEFAULT_ZOOM = 12;
398
+ const MapContent = React.forwardRef(
399
+ ({ apiKey, ...props }, ref) => {
400
+ const { isLoaded, loadError, load } = googleMapsLoader.useGoogleMapsLoader();
401
+ const {
402
+ center = DEFAULT_CENTER,
403
+ zoom = DEFAULT_ZOOM,
404
+ markers = [],
405
+ circle,
406
+ polygon,
407
+ layers,
408
+ height = "400px",
409
+ mapContainerClassName,
410
+ disableDefaultUI = false,
411
+ zoomControl = true,
412
+ streetViewControl = false,
413
+ mapTypeControl = false,
414
+ fullscreenControl = true,
415
+ gestureHandling = "cooperative",
416
+ onMapLoad,
417
+ className,
418
+ ...divProps
419
+ } = props;
420
+ const [selectedMarker, setSelectedMarker] = React.useState(null);
421
+ const mapRef = React.useRef(null);
422
+ const gmpMapRef = React.useRef(null);
423
+ const infoWindowRef = React.useRef(null);
424
+ const circleRef = React.useRef(null);
425
+ const polygonRef = React.useRef(null);
426
+ const [themeColors, setThemeColors] = React.useState({
427
+ primary: "#4F46E5",
428
+ chart2: "#10B981"
429
+ });
430
+ React.useEffect(() => {
431
+ if (typeof window !== "undefined") {
432
+ const styles = getComputedStyle(document.documentElement);
433
+ setThemeColors({
434
+ primary: styles.getPropertyValue("--primary").trim() || "#4F46E5",
435
+ chart2: styles.getPropertyValue("--chart-2").trim() || "#10B981"
436
+ });
437
+ }
438
+ }, []);
439
+ React.useEffect(() => {
440
+ if (!isLoaded && apiKey && !loadError && load) {
441
+ load(apiKey).catch(console.error);
442
+ }
443
+ }, [isLoaded, apiKey, loadError, load]);
444
+ React.useEffect(() => {
445
+ if (!isLoaded || !gmpMapRef.current) return;
446
+ const gmpMap = gmpMapRef.current;
447
+ if (gmpMap.innerMap) {
448
+ mapRef.current = gmpMap.innerMap;
449
+ if (onMapLoad) {
450
+ onMapLoad(gmpMap.innerMap);
451
+ }
452
+ } else {
453
+ const interval = setInterval(() => {
454
+ if (gmpMap.innerMap) {
455
+ mapRef.current = gmpMap.innerMap;
456
+ if (onMapLoad) {
457
+ onMapLoad(gmpMap.innerMap);
458
+ }
459
+ clearInterval(interval);
460
+ }
461
+ }, 100);
462
+ return () => clearInterval(interval);
463
+ }
464
+ return () => {
465
+ mapRef.current = null;
466
+ };
467
+ }, [isLoaded]);
468
+ React.useEffect(() => {
469
+ if (gmpMapRef.current) {
470
+ if (center) gmpMapRef.current.center = center;
471
+ }
472
+ }, [center]);
473
+ React.useEffect(() => {
474
+ if (gmpMapRef.current) {
475
+ if (zoom !== void 0) gmpMapRef.current.zoom = zoom;
476
+ }
477
+ }, [zoom]);
478
+ React.useEffect(() => {
479
+ if (gmpMapRef.current) {
480
+ if (props.mapTypeId) gmpMapRef.current.mapTypeId = props.mapTypeId;
481
+ }
482
+ }, [props.mapTypeId]);
483
+ React.useEffect(() => {
484
+ const map = mapRef.current;
485
+ if (!map || !isLoaded) return;
486
+ circleRef.current?.setMap(null);
487
+ circleRef.current = null;
488
+ if (circle && circle.center && circle.radius) {
489
+ circleRef.current = new google.maps.Circle({
490
+ map,
491
+ center: circle.center,
492
+ radius: circle.radius,
493
+ fillColor: circle.fillColor || themeColors.primary,
494
+ fillOpacity: 0.2,
495
+ strokeColor: circle.strokeColor || themeColors.primary,
496
+ strokeOpacity: 0.8,
497
+ strokeWeight: 2
498
+ });
499
+ }
500
+ return () => {
501
+ circleRef.current?.setMap(null);
502
+ };
503
+ }, [circle, isLoaded, themeColors, mapRef.current]);
504
+ React.useEffect(() => {
505
+ const map = mapRef.current;
506
+ if (!map || !isLoaded) return;
507
+ polygonRef.current?.setMap(null);
508
+ polygonRef.current = null;
509
+ if (polygon && polygon.paths) {
510
+ polygonRef.current = new google.maps.Polygon({
511
+ map,
512
+ paths: polygon.paths,
513
+ fillColor: polygon.fillColor || themeColors.chart2,
514
+ fillOpacity: 0.2,
515
+ strokeColor: polygon.strokeColor || themeColors.chart2,
516
+ strokeOpacity: 0.8,
517
+ strokeWeight: 2
518
+ });
519
+ }
520
+ return () => {
521
+ polygonRef.current?.setMap(null);
522
+ };
523
+ }, [polygon, isLoaded, themeColors, mapRef.current]);
524
+ useMapLayers(mapRef.current, layers || {});
525
+ React.useEffect(() => {
526
+ const map = mapRef.current;
527
+ if (!map || selectedMarker === null) {
528
+ infoWindowRef.current?.close();
529
+ return;
530
+ }
531
+ const markerData = markers[selectedMarker];
532
+ if (!markerData) return;
533
+ }, [selectedMarker, markers]);
534
+ const handleMarkerClick = (index, markerElement) => {
535
+ setSelectedMarker(index);
536
+ const map = mapRef.current;
537
+ if (!map) return;
538
+ const markerData = markers[index];
539
+ if (!markerData) return;
540
+ let contentToRender = markerData.richContent;
541
+ if (!contentToRender && (markerData.title || markerData.info)) {
542
+ contentToRender = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 pr-8 min-w-[200px] max-w-[300px]", children: [
543
+ markerData.title && /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-base mb-1", children: markerData.title }),
544
+ markerData.info && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: markerData.info })
545
+ ] });
546
+ }
547
+ if (contentToRender && markerElement.innerMarker) {
548
+ if (!infoWindowRef.current) {
549
+ infoWindowRef.current = new google.maps.InfoWindow();
550
+ }
551
+ const container = document.createElement("div");
552
+ const root = client.createRoot(container);
553
+ root.render(contentToRender);
554
+ infoWindowRef.current.setContent(container);
555
+ infoWindowRef.current.open({
556
+ map,
557
+ anchor: markerElement.innerMarker
558
+ });
559
+ infoWindowRef.current.addListener("closeclick", () => {
560
+ setSelectedMarker(null);
561
+ setTimeout(() => root.unmount(), 0);
562
+ });
563
+ }
564
+ };
565
+ if (loadError) {
566
+ return /* @__PURE__ */ jsxRuntime.jsx(
567
+ "div",
568
+ {
569
+ ref,
570
+ className: button.cn(
571
+ "relative rounded-[var(--radius-card)] border border-destructive/50 overflow-hidden bg-destructive/5",
572
+ className
573
+ ),
574
+ style: { height },
575
+ ...divProps,
576
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center space-y-2 p-6", children: [
577
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive", children: /* @__PURE__ */ jsxRuntime.jsx(
578
+ "svg",
579
+ {
580
+ className: "w-12 h-12 mx-auto",
581
+ fill: "none",
582
+ stroke: "currentColor",
583
+ viewBox: "0 0 24 24",
584
+ children: /* @__PURE__ */ jsxRuntime.jsx(
585
+ "path",
586
+ {
587
+ strokeLinecap: "round",
588
+ strokeLinejoin: "round",
589
+ strokeWidth: 2,
590
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
591
+ }
592
+ )
593
+ }
594
+ ) }),
595
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: "Failed to load Google Maps" }),
596
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Check API key in Settings" })
597
+ ] }) })
598
+ }
599
+ );
600
+ }
601
+ if (!isLoaded) {
602
+ return /* @__PURE__ */ jsxRuntime.jsx(
603
+ "div",
604
+ {
605
+ ref,
606
+ className: button.cn(
607
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden bg-muted animate-pulse",
608
+ className
609
+ ),
610
+ style: { height },
611
+ ...divProps
612
+ }
613
+ );
614
+ }
615
+ return /* @__PURE__ */ jsxRuntime.jsx(
616
+ "div",
617
+ {
618
+ ref,
619
+ className: button.cn(
620
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden",
621
+ className
622
+ ),
623
+ style: { height },
624
+ ...divProps,
625
+ children: /* @__PURE__ */ jsxRuntime.jsx(
626
+ "gmp-map",
627
+ {
628
+ ref: gmpMapRef,
629
+ style: { height: "100%", width: "100%", display: "block" },
630
+ "map-id": props.mapId || "DEMO_MAP_ID",
631
+ children: markers.map((markerData, idx) => {
632
+ const markerColor = markerData.customColor || "var(--primary)";
633
+ const iconColor = markerData.iconColor || "white";
634
+ return (
635
+ // @ts-ignore
636
+ /* @__PURE__ */ jsxRuntime.jsx(
637
+ "gmp-advanced-marker",
638
+ {
639
+ title: markerData.title,
640
+ ref: (el) => {
641
+ if (el) {
642
+ el.position = markerData.position;
643
+ el.addEventListener("gmp-click", () => handleMarkerClick(idx, el));
644
+ }
645
+ },
646
+ children: /* @__PURE__ */ jsxRuntime.jsx(
647
+ "div",
648
+ {
649
+ className: "flex items-center justify-center w-8 h-8 border-[3px] border-background shadow-lg cursor-pointer origin-center transition-transform duration-200",
650
+ style: {
651
+ borderRadius: "50% 50% 50% 0",
652
+ transform: "rotate(-45deg)",
653
+ backgroundColor: markerColor
654
+ },
655
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center rotate-45", children: markerData.iconSvg ? /* @__PURE__ */ jsxRuntime.jsx(
656
+ "div",
657
+ {
658
+ dangerouslySetInnerHTML: {
659
+ __html: DOMPurify.sanitize(markerData.iconSvg, {
660
+ USE_PROFILES: { svg: true, svgFilters: true }
661
+ })
662
+ },
663
+ style: { color: iconColor, width: 16, height: 16, fill: "currentColor" }
664
+ }
665
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-sm", style: { color: iconColor }, children: markerData.icon || markerData.label || "" }) })
666
+ }
667
+ )
668
+ },
669
+ idx
670
+ )
671
+ );
672
+ })
673
+ }
674
+ )
675
+ }
676
+ );
677
+ }
678
+ );
679
+ MapContent.displayName = "MapContent";
680
+ const Map = React.forwardRef((props, ref) => {
681
+ const { isLoaded, loadError } = googleMapsLoader.useGoogleMapsLoader();
682
+ const effectiveApiKey = props.apiKey || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('alert-dialog-BzIcTKn_.cjs', document.baseURI).href)) }) !== "undefined" && __vite_import_meta_env__ && undefined || "";
683
+ const isValidKey = effectiveApiKey && effectiveApiKey !== "YOUR_GOOGLE_MAPS_API_KEY_HERE" && effectiveApiKey.startsWith("AIza");
684
+ if (isLoaded || isValidKey || loadError) {
685
+ return /* @__PURE__ */ jsxRuntime.jsx(MapContent, { ref, ...props, apiKey: effectiveApiKey });
686
+ }
687
+ const isScriptInjected = typeof document !== "undefined" && !!document.querySelector('script[src*="maps.googleapis.com/maps/api/js"]');
688
+ if (isScriptInjected) {
689
+ return /* @__PURE__ */ jsxRuntime.jsx(MapContent, { ref, ...props, apiKey: effectiveApiKey });
690
+ }
691
+ return /* @__PURE__ */ jsxRuntime.jsx(
692
+ "div",
693
+ {
694
+ ref,
695
+ className: button.cn(
696
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden bg-muted",
697
+ props.className
698
+ ),
699
+ style: { height: props.height || "400px" },
700
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center space-y-3 p-6", children: [
701
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto bg-primary/10 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
702
+ "svg",
703
+ {
704
+ className: "w-8 h-8 text-primary",
705
+ fill: "none",
706
+ stroke: "currentColor",
707
+ viewBox: "0 0 24 24",
708
+ children: [
709
+ /* @__PURE__ */ jsxRuntime.jsx(
710
+ "path",
711
+ {
712
+ strokeLinecap: "round",
713
+ strokeLinejoin: "round",
714
+ strokeWidth: 2,
715
+ d: "M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
716
+ }
717
+ ),
718
+ /* @__PURE__ */ jsxRuntime.jsx(
719
+ "path",
720
+ {
721
+ strokeLinecap: "round",
722
+ strokeLinejoin: "round",
723
+ strokeWidth: 2,
724
+ d: "M15 11a3 3 0 11-6 0 3 3 0 016 0z"
725
+ }
726
+ )
727
+ ]
728
+ }
729
+ ) }),
730
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Configure Google Maps API Key in Settings" })
731
+ ] }) })
732
+ }
733
+ );
734
+ });
735
+ Map.displayName = "Map";
736
+
737
+ function AlertDialog({ ...props }) {
738
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Root, { "data-slot": "alert-dialog", ...props });
739
+ }
740
+ function AlertDialogTrigger({
741
+ ...props
742
+ }) {
743
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Trigger, { "data-slot": "alert-dialog-trigger", ...props });
744
+ }
745
+ function AlertDialogPortal({ ...props }) {
746
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Portal, { "data-slot": "alert-dialog-portal", ...props });
747
+ }
748
+ const AlertDialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => {
749
+ return /* @__PURE__ */ jsxRuntime.jsx(
750
+ AlertDialogPrimitive__namespace.Overlay,
751
+ {
752
+ ref,
753
+ "data-slot": "alert-dialog-overlay",
754
+ className: button.cn(
755
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
756
+ className
757
+ ),
758
+ ...props
759
+ }
760
+ );
761
+ });
762
+ AlertDialogOverlay.displayName = AlertDialogPrimitive__namespace.Overlay.displayName;
763
+ function AlertDialogContent({
764
+ className,
765
+ ...props
766
+ }) {
767
+ return /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPortal, { children: [
768
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogOverlay, {}),
769
+ /* @__PURE__ */ jsxRuntime.jsx(
770
+ AlertDialogPrimitive__namespace.Content,
771
+ {
772
+ "data-slot": "alert-dialog-content",
773
+ className: button.cn(
774
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
775
+ className
776
+ ),
777
+ ...props
778
+ }
779
+ )
780
+ ] });
781
+ }
782
+ function AlertDialogHeader({ className, ...props }) {
783
+ return /* @__PURE__ */ jsxRuntime.jsx(
784
+ "div",
785
+ {
786
+ "data-slot": "alert-dialog-header",
787
+ className: button.cn("flex flex-col gap-2 text-center sm:text-left", className),
788
+ ...props
789
+ }
790
+ );
791
+ }
792
+ function AlertDialogFooter({ className, ...props }) {
793
+ return /* @__PURE__ */ jsxRuntime.jsx(
794
+ "div",
795
+ {
796
+ "data-slot": "alert-dialog-footer",
797
+ className: button.cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
798
+ ...props
799
+ }
800
+ );
801
+ }
802
+ function AlertDialogTitle({
803
+ className,
804
+ ...props
805
+ }) {
806
+ return /* @__PURE__ */ jsxRuntime.jsx(
807
+ AlertDialogPrimitive__namespace.Title,
808
+ {
809
+ "data-slot": "alert-dialog-title",
810
+ className: button.cn("text-lg font-semibold", className),
811
+ ...props
812
+ }
813
+ );
814
+ }
815
+ function AlertDialogDescription({
816
+ className,
817
+ ...props
818
+ }) {
819
+ return /* @__PURE__ */ jsxRuntime.jsx(
820
+ AlertDialogPrimitive__namespace.Description,
821
+ {
822
+ "data-slot": "alert-dialog-description",
823
+ className: button.cn("text-muted-foreground text-sm", className),
824
+ ...props
825
+ }
826
+ );
827
+ }
828
+ function AlertDialogAction({
829
+ className,
830
+ ...props
831
+ }) {
832
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Action, { className: button.cn(button.buttonVariants(), className), ...props });
833
+ }
834
+ function AlertDialogCancel({
835
+ className,
836
+ ...props
837
+ }) {
838
+ return /* @__PURE__ */ jsxRuntime.jsx(
839
+ AlertDialogPrimitive__namespace.Cancel,
840
+ {
841
+ className: button.cn(button.buttonVariants({ variant: "outline" }), className),
842
+ ...props
843
+ }
844
+ );
845
+ }
846
+
847
+ exports.AlertDialog = AlertDialog;
848
+ exports.AlertDialogAction = AlertDialogAction;
849
+ exports.AlertDialogCancel = AlertDialogCancel;
850
+ exports.AlertDialogContent = AlertDialogContent;
851
+ exports.AlertDialogDescription = AlertDialogDescription;
852
+ exports.AlertDialogFooter = AlertDialogFooter;
853
+ exports.AlertDialogHeader = AlertDialogHeader;
854
+ exports.AlertDialogOverlay = AlertDialogOverlay;
855
+ exports.AlertDialogPortal = AlertDialogPortal;
856
+ exports.AlertDialogTitle = AlertDialogTitle;
857
+ exports.AlertDialogTrigger = AlertDialogTrigger;
858
+ exports.Checkbox = Checkbox;
859
+ exports.Label = Label;
860
+ exports.Map = Map;
861
+ exports.PageHeader = PageHeader;
862
+ exports.PageHeaderDescription = PageHeaderDescription;
863
+ exports.PageHeaderHeading = PageHeaderHeading;
864
+ exports.RadioGroup = RadioGroup;
865
+ exports.RadioGroupItem = RadioGroupItem;
866
+ exports.Separator = Separator;
867
+ exports.Switch = Switch;
868
+ exports.Tabs = Tabs;
869
+ exports.TabsContent = TabsContent;
870
+ exports.TabsList = TabsList;
871
+ exports.TabsTrigger = TabsTrigger;
872
+ exports.useMapLayers = useMapLayers;