xertica-ui 1.0.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/App.tsx +182 -0
- package/README.md +330 -0
- package/assets/xertica-logo.svg +38 -0
- package/assets/xertica-x-logo.svg +21 -0
- package/bin/cli.ts +193 -0
- package/components/AssistenteXertica.tsx +2003 -0
- package/components/AudioPlayer.tsx +203 -0
- package/components/CodeBlock.tsx +242 -0
- package/components/DocumentEditor.tsx +504 -0
- package/components/ForgotPasswordPage.tsx +170 -0
- package/components/FormattedDocument.tsx +87 -0
- package/components/HomeContent.tsx +123 -0
- package/components/HomePage.tsx +70 -0
- package/components/LanguageSelector.tsx +54 -0
- package/components/LoginPage.tsx +199 -0
- package/components/MarkdownMessage.tsx +62 -0
- package/components/ModernChatInput.tsx +502 -0
- package/components/PodcastPlayer.tsx +409 -0
- package/components/ResetPasswordPage.tsx +234 -0
- package/components/Sidebar.tsx +489 -0
- package/components/TemplateContent.tsx +629 -0
- package/components/TemplatePage.tsx +70 -0
- package/components/ThemeToggle.tsx +65 -0
- package/components/VerifyEmailPage.tsx +187 -0
- package/components/XerticaLogo.tsx +69 -0
- package/components/XerticaOrbe.tsx +1339 -0
- package/components/XerticaXLogo.tsx +53 -0
- package/components/examples/DrawingMapExample.tsx +530 -0
- package/components/examples/FilterableMapExample.tsx +380 -0
- package/components/examples/LocationPickerExample.tsx +330 -0
- package/components/examples/MapExamples.tsx +280 -0
- package/components/examples/MapShowcase.tsx +446 -0
- package/components/examples/RouteMapExamples.tsx +329 -0
- package/components/examples/SimpleFilterableMap.tsx +192 -0
- package/components/examples/index.ts +52 -0
- package/components/figma/ImageWithFallback.tsx +27 -0
- package/components/index.ts +44 -0
- package/components/media/AudioPlayer.tsx +278 -0
- package/components/media/FloatingMediaWrapper.tsx +166 -0
- package/components/media/VideoPlayer.tsx +285 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +159 -0
- package/components/ui/alert.tsx +91 -0
- package/components/ui/aspect-ratio.tsx +11 -0
- package/components/ui/avatar.tsx +65 -0
- package/components/ui/badge.tsx +55 -0
- package/components/ui/breadcrumb.tsx +109 -0
- package/components/ui/button.tsx +78 -0
- package/components/ui/calendar.tsx +235 -0
- package/components/ui/card.tsx +92 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +353 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +177 -0
- package/components/ui/context-menu.tsx +252 -0
- package/components/ui/dialog.tsx +138 -0
- package/components/ui/drawer.tsx +134 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/empty.tsx +90 -0
- package/components/ui/file-upload.tsx +152 -0
- package/components/ui/form.tsx +195 -0
- package/components/ui/google-maps-loader.tsx +379 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/index.ts +242 -0
- package/components/ui/input-otp.tsx +77 -0
- package/components/ui/input.tsx +38 -0
- package/components/ui/label.tsx +24 -0
- package/components/ui/map-config.ts +12 -0
- package/components/ui/map-layers.tsx +129 -0
- package/components/ui/map.exports.ts +31 -0
- package/components/ui/map.tsx +412 -0
- package/components/ui/menubar.tsx +276 -0
- package/components/ui/navigation-menu.tsx +162 -0
- package/components/ui/notification-badge.tsx +61 -0
- package/components/ui/page-header.tsx +229 -0
- package/components/ui/pagination.tsx +127 -0
- package/components/ui/popover.tsx +48 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/radio-group.tsx +56 -0
- package/components/ui/rating.tsx +102 -0
- package/components/ui/resizable.tsx +405 -0
- package/components/ui/route-map.tsx +246 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/search.tsx +70 -0
- package/components/ui/select.tsx +176 -0
- package/components/ui/separator.tsx +28 -0
- package/components/ui/sheet.tsx +138 -0
- package/components/ui/sidebar.tsx +726 -0
- package/components/ui/simple-map.tsx +92 -0
- package/components/ui/skeleton.tsx +13 -0
- package/components/ui/slider.tsx +58 -0
- package/components/ui/sonner.tsx +77 -0
- package/components/ui/stats-card.tsx +84 -0
- package/components/ui/stepper.tsx +126 -0
- package/components/ui/switch.tsx +34 -0
- package/components/ui/table.tsx +116 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +26 -0
- package/components/ui/timeline.tsx +140 -0
- package/components/ui/toggle-group.tsx +71 -0
- package/components/ui/toggle.tsx +46 -0
- package/components/ui/tooltip.tsx +61 -0
- package/components/ui/tree-view.tsx +123 -0
- package/components/ui/use-mobile.ts +24 -0
- package/components/ui/utils.ts +6 -0
- package/components/ui/xertica-assistant.tsx +1420 -0
- package/contexts/ApiKeyContext.tsx +123 -0
- package/contexts/AssistenteContext.tsx +118 -0
- package/contexts/BrandColorsContext.tsx +551 -0
- package/contexts/LanguageContext.tsx +36 -0
- package/contexts/ThemeContext.tsx +85 -0
- package/dist/cli.js +20922 -0
- package/eslint.config.js +41 -0
- package/guidelines/Guidelines.md +61 -0
- package/hooks/useTheme.ts +4 -0
- package/imports/Podcast.tsx +389 -0
- package/imports/XerticaAi.tsx +46 -0
- package/imports/XerticaX.tsx +20 -0
- package/imports/svg-aueiaqngck.ts +11 -0
- package/imports/svg-v9krss1ozd.ts +16 -0
- package/imports/svg-vhrdofe3qe.ts +5 -0
- package/index.css +4448 -0
- package/index.html +14 -0
- package/main.tsx +10 -0
- package/package.json +119 -0
- package/postcss.config.js +6 -0
- package/routes.tsx +33 -0
- package/styles/globals.css +15 -0
- package/styles/xertica/app-overrides/chat.css +61 -0
- package/styles/xertica/app-overrides/scrollbar.css +33 -0
- package/styles/xertica/base.css +70 -0
- package/styles/xertica/integrations/google-maps.css +76 -0
- package/styles/xertica/integrations/sonner.css +73 -0
- package/styles/xertica/theme-map.css +88 -0
- package/styles/xertica/tokens.css +190 -0
- package/tsconfig.json +31 -0
- package/tsconfig.node.json +10 -0
- package/utils/gemini.ts +140 -0
- package/vite-env.d.ts +12 -0
- package/vite.config.ts +36 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Map } from '../ui/map';
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card';
|
|
4
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
|
|
5
|
+
import { Badge } from '../ui/badge';
|
|
6
|
+
import { Button } from '../ui/button';
|
|
7
|
+
import { Alert, AlertDescription } from '../ui/alert';
|
|
8
|
+
import { Info, Layers, MapPin, MousePointer2, Pencil } from 'lucide-react';
|
|
9
|
+
import { Checkbox } from '../ui/checkbox';
|
|
10
|
+
import { Label } from '../ui/label';
|
|
11
|
+
import { Switch } from '../ui/switch';
|
|
12
|
+
import { FilterableMapExample } from './FilterableMapExample';
|
|
13
|
+
import { SimpleFilterableMap } from './SimpleFilterableMap';
|
|
14
|
+
import { DrawingMapExample } from './DrawingMapExample';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* MapShowcase - Componente de demonstração completo e organizado
|
|
18
|
+
*
|
|
19
|
+
* Organizado em 3 abas principais conforme diretrizes do Design System:
|
|
20
|
+
* 1. Mapas Simples (Padrão, Layers, Compacto)
|
|
21
|
+
* 2. Marcadores (Pins, Áreas, Personalização)
|
|
22
|
+
* 3. Controles (Filtros, Controles Nativos)
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export function MapShowcase() {
|
|
26
|
+
const [activeTab, setActiveTab] = useState('simple');
|
|
27
|
+
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
28
|
+
|
|
29
|
+
// Estados para Layers
|
|
30
|
+
const [showTraffic, setShowTraffic] = useState(false);
|
|
31
|
+
const [showTransit, setShowTransit] = useState(false);
|
|
32
|
+
const [showBicycling, setShowBicycling] = useState(false);
|
|
33
|
+
|
|
34
|
+
// Estados para Controles Nativos
|
|
35
|
+
const [showZoomControl, setShowZoomControl] = useState(true);
|
|
36
|
+
const [showMapTypeControl, setShowMapTypeControl] = useState(false);
|
|
37
|
+
const [showStreetViewControl, setShowStreetViewControl] = useState(false);
|
|
38
|
+
const [showFullscreenControl, setShowFullscreenControl] = useState(true);
|
|
39
|
+
|
|
40
|
+
// Handler para troca de tabs com cleanup
|
|
41
|
+
const handleTabChange = (value: string) => {
|
|
42
|
+
if (value === activeTab) return;
|
|
43
|
+
setIsTransitioning(true);
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
setActiveTab(value);
|
|
46
|
+
setIsTransitioning(false);
|
|
47
|
+
}, 50);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className="space-y-8">
|
|
52
|
+
{/* Header */}
|
|
53
|
+
<div className="space-y-4">
|
|
54
|
+
<div className="flex items-center gap-3">
|
|
55
|
+
<h2>Mapas</h2>
|
|
56
|
+
<Badge>Design System</Badge>
|
|
57
|
+
</div>
|
|
58
|
+
<p className="text-muted-foreground max-w-3xl">
|
|
59
|
+
Biblioteca de componentes de mapa para visualização de dados geoespaciais.
|
|
60
|
+
Utiliza a API do Google Maps com estilização personalizada do Xertica UI.
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{/* API Key Notice */}
|
|
65
|
+
<Alert>
|
|
66
|
+
<AlertDescription>
|
|
67
|
+
<strong>Nota:</strong> Certifique-se de que a API Key do Google Maps esteja configurada corretamente para visualizar os mapas.
|
|
68
|
+
</AlertDescription>
|
|
69
|
+
</Alert>
|
|
70
|
+
|
|
71
|
+
{/* Tabs Principais */}
|
|
72
|
+
<Tabs value={activeTab} onValueChange={handleTabChange} className="w-full">
|
|
73
|
+
<TabsList className="grid w-full grid-cols-4 mb-8">
|
|
74
|
+
<TabsTrigger value="simple">Mapas Simples</TabsTrigger>
|
|
75
|
+
<TabsTrigger value="markers">Marcadores</TabsTrigger>
|
|
76
|
+
<TabsTrigger value="controls">Controles</TabsTrigger>
|
|
77
|
+
<TabsTrigger value="drawing" className="flex items-center gap-2">
|
|
78
|
+
<Pencil className="w-3 h-3" /> Desenho
|
|
79
|
+
</TabsTrigger>
|
|
80
|
+
</TabsList>
|
|
81
|
+
|
|
82
|
+
{/* 1. Mapas Simples */}
|
|
83
|
+
<TabsContent value="simple" className="space-y-8">
|
|
84
|
+
{!isTransitioning && activeTab === 'simple' && (
|
|
85
|
+
<>
|
|
86
|
+
{/* Mapa Padrão */}
|
|
87
|
+
<Card>
|
|
88
|
+
<CardHeader>
|
|
89
|
+
<CardTitle>Mapa Padrão</CardTitle>
|
|
90
|
+
<CardDescription>
|
|
91
|
+
Configuração básica do mapa centralizado em uma coordenada específica.
|
|
92
|
+
</CardDescription>
|
|
93
|
+
</CardHeader>
|
|
94
|
+
<CardContent>
|
|
95
|
+
<Map
|
|
96
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
97
|
+
zoom={13}
|
|
98
|
+
height="400px"
|
|
99
|
+
/>
|
|
100
|
+
</CardContent>
|
|
101
|
+
</Card>
|
|
102
|
+
|
|
103
|
+
{/* Mapa com Layers */}
|
|
104
|
+
<Card>
|
|
105
|
+
<CardHeader>
|
|
106
|
+
<CardTitle>Camadas (Layers)</CardTitle>
|
|
107
|
+
<CardDescription>
|
|
108
|
+
Sobreposição de informações como tráfego, transporte público e ciclovias.
|
|
109
|
+
</CardDescription>
|
|
110
|
+
</CardHeader>
|
|
111
|
+
<CardContent className="space-y-4">
|
|
112
|
+
<div className="flex flex-wrap gap-6 p-4 border rounded-lg bg-muted/50">
|
|
113
|
+
<div className="flex items-center space-x-2">
|
|
114
|
+
<Switch
|
|
115
|
+
id="traffic"
|
|
116
|
+
checked={showTraffic}
|
|
117
|
+
onCheckedChange={setShowTraffic}
|
|
118
|
+
/>
|
|
119
|
+
<Label htmlFor="traffic" className="flex items-center gap-2">
|
|
120
|
+
<Layers className="w-4 h-4" /> Trânsito
|
|
121
|
+
</Label>
|
|
122
|
+
</div>
|
|
123
|
+
<div className="flex items-center space-x-2">
|
|
124
|
+
<Switch
|
|
125
|
+
id="transit"
|
|
126
|
+
checked={showTransit}
|
|
127
|
+
onCheckedChange={setShowTransit}
|
|
128
|
+
/>
|
|
129
|
+
<Label htmlFor="transit" className="flex items-center gap-2">
|
|
130
|
+
<Layers className="w-4 h-4" /> Transporte
|
|
131
|
+
</Label>
|
|
132
|
+
</div>
|
|
133
|
+
<div className="flex items-center space-x-2">
|
|
134
|
+
<Switch
|
|
135
|
+
id="bicycling"
|
|
136
|
+
checked={showBicycling}
|
|
137
|
+
onCheckedChange={setShowBicycling}
|
|
138
|
+
/>
|
|
139
|
+
<Label htmlFor="bicycling" className="flex items-center gap-2">
|
|
140
|
+
<Layers className="w-4 h-4" /> Ciclovias
|
|
141
|
+
</Label>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<Map
|
|
146
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
147
|
+
zoom={12}
|
|
148
|
+
height="500px"
|
|
149
|
+
layers={{
|
|
150
|
+
traffic: showTraffic,
|
|
151
|
+
transit: showTransit,
|
|
152
|
+
bicycling: showBicycling,
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
</CardContent>
|
|
156
|
+
</Card>
|
|
157
|
+
|
|
158
|
+
{/* Mapas Compactos */}
|
|
159
|
+
<div className="grid md:grid-cols-3 gap-4">
|
|
160
|
+
<Card>
|
|
161
|
+
<CardHeader className="p-4 pb-2">
|
|
162
|
+
<CardTitle className="text-sm">São Paulo</CardTitle>
|
|
163
|
+
</CardHeader>
|
|
164
|
+
<CardContent className="p-4 pt-0">
|
|
165
|
+
<Map
|
|
166
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
167
|
+
zoom={11}
|
|
168
|
+
height="200px"
|
|
169
|
+
disableDefaultUI={true}
|
|
170
|
+
/>
|
|
171
|
+
</CardContent>
|
|
172
|
+
</Card>
|
|
173
|
+
<Card>
|
|
174
|
+
<CardHeader className="p-4 pb-2">
|
|
175
|
+
<CardTitle className="text-sm">Rio de Janeiro</CardTitle>
|
|
176
|
+
</CardHeader>
|
|
177
|
+
<CardContent className="p-4 pt-0">
|
|
178
|
+
<Map
|
|
179
|
+
center={{ lat: -22.9068, lng: -43.1729 }}
|
|
180
|
+
zoom={11}
|
|
181
|
+
height="200px"
|
|
182
|
+
disableDefaultUI={true}
|
|
183
|
+
/>
|
|
184
|
+
</CardContent>
|
|
185
|
+
</Card>
|
|
186
|
+
<Card>
|
|
187
|
+
<CardHeader className="p-4 pb-2">
|
|
188
|
+
<CardTitle className="text-sm">New York</CardTitle>
|
|
189
|
+
</CardHeader>
|
|
190
|
+
<CardContent className="p-4 pt-0">
|
|
191
|
+
<Map
|
|
192
|
+
center={{ lat: 40.7128, lng: -74.0060 }}
|
|
193
|
+
zoom={11}
|
|
194
|
+
height="200px"
|
|
195
|
+
disableDefaultUI={true}
|
|
196
|
+
/>
|
|
197
|
+
</CardContent>
|
|
198
|
+
</Card>
|
|
199
|
+
</div>
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
</TabsContent>
|
|
203
|
+
|
|
204
|
+
{/* 2. Marcadores */}
|
|
205
|
+
<TabsContent value="markers" className="space-y-8">
|
|
206
|
+
{!isTransitioning && activeTab === 'markers' && (
|
|
207
|
+
<>
|
|
208
|
+
{/* Marcadores e Pins */}
|
|
209
|
+
<Card>
|
|
210
|
+
<CardHeader>
|
|
211
|
+
<CardTitle>Marcadores e Pins</CardTitle>
|
|
212
|
+
<CardDescription>
|
|
213
|
+
Exemplos de marcadores personalizados com diferentes cores e informações.
|
|
214
|
+
</CardDescription>
|
|
215
|
+
</CardHeader>
|
|
216
|
+
<CardContent>
|
|
217
|
+
<Map
|
|
218
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
219
|
+
zoom={13}
|
|
220
|
+
height="500px"
|
|
221
|
+
markers={[
|
|
222
|
+
{
|
|
223
|
+
position: { lat: -23.5505, lng: -46.6333 },
|
|
224
|
+
title: "Principal",
|
|
225
|
+
info: "Marcador padrão",
|
|
226
|
+
customColor: "#4F46E5"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
position: { lat: -23.540, lng: -46.640 },
|
|
230
|
+
title: "Secundário",
|
|
231
|
+
info: "Marcador de alerta",
|
|
232
|
+
customColor: "#EF4444",
|
|
233
|
+
icon: "!"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
position: { lat: -23.560, lng: -46.620 },
|
|
237
|
+
title: "Loja",
|
|
238
|
+
info: "Ponto de venda",
|
|
239
|
+
customColor: "#10B981",
|
|
240
|
+
icon: "S"
|
|
241
|
+
}
|
|
242
|
+
]}
|
|
243
|
+
/>
|
|
244
|
+
</CardContent>
|
|
245
|
+
</Card>
|
|
246
|
+
|
|
247
|
+
{/* Marcador com Conteúdo Rico */}
|
|
248
|
+
<Card>
|
|
249
|
+
<CardHeader>
|
|
250
|
+
<CardTitle>Marcador com Ações</CardTitle>
|
|
251
|
+
<CardDescription>
|
|
252
|
+
Marcador interativo que exibe conteúdo rico (texto, imagem, botões) ao ser clicado.
|
|
253
|
+
</CardDescription>
|
|
254
|
+
</CardHeader>
|
|
255
|
+
<CardContent>
|
|
256
|
+
<Map
|
|
257
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
258
|
+
zoom={13}
|
|
259
|
+
height="500px"
|
|
260
|
+
markers={[
|
|
261
|
+
{
|
|
262
|
+
position: { lat: -23.5505, lng: -46.6333 },
|
|
263
|
+
label: "🏢",
|
|
264
|
+
richContent: (
|
|
265
|
+
<div className="p-4 max-w-[260px]">
|
|
266
|
+
<div className="flex items-center justify-between mb-2">
|
|
267
|
+
<h4 className="font-semibold text-base">Xertica HQ</h4>
|
|
268
|
+
<Badge variant="outline" className="text-[10px] h-5">Open</Badge>
|
|
269
|
+
</div>
|
|
270
|
+
<div className="w-full h-32 bg-muted rounded-md mb-3 overflow-hidden relative">
|
|
271
|
+
<div className="absolute inset-0 bg-[image:var(--gradient-diagonal)] opacity-80" />
|
|
272
|
+
<div className="absolute inset-0 flex items-center justify-center text-white font-medium">
|
|
273
|
+
Office View
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
<p className="text-sm text-muted-foreground mb-3 leading-relaxed">
|
|
277
|
+
Sede principal em São Paulo. Espaço moderno para reuniões e eventos.
|
|
278
|
+
</p>
|
|
279
|
+
<div className="grid grid-cols-2 gap-2">
|
|
280
|
+
<Button size="sm" className="w-full h-8 text-xs shadow-sm">
|
|
281
|
+
Navegar
|
|
282
|
+
</Button>
|
|
283
|
+
<Button size="sm" variant="outline" className="w-full h-8 text-xs bg-background">
|
|
284
|
+
Detalhes
|
|
285
|
+
</Button>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
]}
|
|
291
|
+
/>
|
|
292
|
+
</CardContent>
|
|
293
|
+
</Card>
|
|
294
|
+
|
|
295
|
+
{/* Áreas e Polígonos */}
|
|
296
|
+
<Card>
|
|
297
|
+
<CardHeader>
|
|
298
|
+
<CardTitle>Áreas e Zonas</CardTitle>
|
|
299
|
+
<CardDescription>
|
|
300
|
+
Delimitação de áreas geográficas usando círculos e polígonos.
|
|
301
|
+
</CardDescription>
|
|
302
|
+
</CardHeader>
|
|
303
|
+
<CardContent>
|
|
304
|
+
<Map
|
|
305
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
306
|
+
zoom={12}
|
|
307
|
+
height="500px"
|
|
308
|
+
markers={[
|
|
309
|
+
{
|
|
310
|
+
position: { lat: -23.5505, lng: -46.6333 },
|
|
311
|
+
title: "Centro da Zona",
|
|
312
|
+
info: "Raio de 3km",
|
|
313
|
+
customColor: "#6366F1"
|
|
314
|
+
}
|
|
315
|
+
]}
|
|
316
|
+
circle={{
|
|
317
|
+
center: { lat: -23.5505, lng: -46.6333 },
|
|
318
|
+
radius: 3000,
|
|
319
|
+
fillColor: "#6366F1",
|
|
320
|
+
strokeColor: "#4F46E5"
|
|
321
|
+
}}
|
|
322
|
+
polygon={{
|
|
323
|
+
paths: [
|
|
324
|
+
{ lat: -23.520, lng: -46.600 },
|
|
325
|
+
{ lat: -23.520, lng: -46.660 },
|
|
326
|
+
{ lat: -23.580, lng: -46.660 },
|
|
327
|
+
{ lat: -23.580, lng: -46.600 }
|
|
328
|
+
],
|
|
329
|
+
fillColor: "#10B981",
|
|
330
|
+
strokeColor: "#059669"
|
|
331
|
+
}}
|
|
332
|
+
/>
|
|
333
|
+
</CardContent>
|
|
334
|
+
</Card>
|
|
335
|
+
</>
|
|
336
|
+
)}
|
|
337
|
+
</TabsContent>
|
|
338
|
+
|
|
339
|
+
{/* 3. Controles */}
|
|
340
|
+
<TabsContent value="controls" className="space-y-8">
|
|
341
|
+
{!isTransitioning && activeTab === 'controls' && (
|
|
342
|
+
<>
|
|
343
|
+
{/* Controles Nativos */}
|
|
344
|
+
<Card>
|
|
345
|
+
<CardHeader>
|
|
346
|
+
<CardTitle>Controles do Mapa</CardTitle>
|
|
347
|
+
<CardDescription>
|
|
348
|
+
Personalize a interface do mapa ativando ou desativando controles nativos.
|
|
349
|
+
</CardDescription>
|
|
350
|
+
</CardHeader>
|
|
351
|
+
<CardContent className="space-y-4">
|
|
352
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 p-4 border rounded-lg bg-muted/50">
|
|
353
|
+
<div className="flex items-center space-x-2">
|
|
354
|
+
<Checkbox
|
|
355
|
+
id="zoom"
|
|
356
|
+
checked={showZoomControl}
|
|
357
|
+
onCheckedChange={(c) => setShowZoomControl(!!c)}
|
|
358
|
+
/>
|
|
359
|
+
<Label htmlFor="zoom">Zoom Control</Label>
|
|
360
|
+
</div>
|
|
361
|
+
<div className="flex items-center space-x-2">
|
|
362
|
+
<Checkbox
|
|
363
|
+
id="maptype"
|
|
364
|
+
checked={showMapTypeControl}
|
|
365
|
+
onCheckedChange={(c) => setShowMapTypeControl(!!c)}
|
|
366
|
+
/>
|
|
367
|
+
<Label htmlFor="maptype">Map Type</Label>
|
|
368
|
+
</div>
|
|
369
|
+
<div className="flex items-center space-x-2">
|
|
370
|
+
<Checkbox
|
|
371
|
+
id="streetview"
|
|
372
|
+
checked={showStreetViewControl}
|
|
373
|
+
onCheckedChange={(c) => setShowStreetViewControl(!!c)}
|
|
374
|
+
/>
|
|
375
|
+
<Label htmlFor="streetview">Street View</Label>
|
|
376
|
+
</div>
|
|
377
|
+
<div className="flex items-center space-x-2">
|
|
378
|
+
<Checkbox
|
|
379
|
+
id="fullscreen"
|
|
380
|
+
checked={showFullscreenControl}
|
|
381
|
+
onCheckedChange={(c) => setShowFullscreenControl(!!c)}
|
|
382
|
+
/>
|
|
383
|
+
<Label htmlFor="fullscreen">Fullscreen</Label>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<Map
|
|
388
|
+
center={{ lat: -23.5505, lng: -46.6333 }}
|
|
389
|
+
zoom={13}
|
|
390
|
+
height="400px"
|
|
391
|
+
zoomControl={showZoomControl}
|
|
392
|
+
mapTypeControl={showMapTypeControl}
|
|
393
|
+
streetViewControl={showStreetViewControl}
|
|
394
|
+
fullscreenControl={showFullscreenControl}
|
|
395
|
+
/>
|
|
396
|
+
</CardContent>
|
|
397
|
+
</Card>
|
|
398
|
+
|
|
399
|
+
{/* Filtros Customizados */}
|
|
400
|
+
<Card>
|
|
401
|
+
<CardHeader>
|
|
402
|
+
<CardTitle>Filtros Interativos</CardTitle>
|
|
403
|
+
<CardDescription>
|
|
404
|
+
Exemplo avançado de mapa com controles customizados para filtragem de marcadores.
|
|
405
|
+
</CardDescription>
|
|
406
|
+
</CardHeader>
|
|
407
|
+
<CardContent>
|
|
408
|
+
<FilterableMapExample />
|
|
409
|
+
</CardContent>
|
|
410
|
+
</Card>
|
|
411
|
+
</>
|
|
412
|
+
)}
|
|
413
|
+
</TabsContent>
|
|
414
|
+
|
|
415
|
+
{/* 4. Desenho */}
|
|
416
|
+
<TabsContent value="drawing" className="space-y-8">
|
|
417
|
+
{!isTransitioning && activeTab === 'drawing' && (
|
|
418
|
+
<DrawingMapExample />
|
|
419
|
+
)}
|
|
420
|
+
</TabsContent>
|
|
421
|
+
</Tabs>
|
|
422
|
+
|
|
423
|
+
{/* Footer Info */}
|
|
424
|
+
<div className="grid md:grid-cols-3 gap-6 pt-8 border-t">
|
|
425
|
+
<div className="space-y-2">
|
|
426
|
+
<h4 className="font-semibold text-sm">Documentação</h4>
|
|
427
|
+
<p className="text-xs text-muted-foreground">
|
|
428
|
+
Verifique <code>MAP_SETUP.md</code> para configuração inicial e requisitos de API.
|
|
429
|
+
</p>
|
|
430
|
+
</div>
|
|
431
|
+
<div className="space-y-2">
|
|
432
|
+
<h4 className="font-semibold text-sm">Performance</h4>
|
|
433
|
+
<p className="text-xs text-muted-foreground">
|
|
434
|
+
Utiliza carregamento assíncrono e AdvancedMarkerElement para melhor desempenho.
|
|
435
|
+
</p>
|
|
436
|
+
</div>
|
|
437
|
+
<div className="space-y-2">
|
|
438
|
+
<h4 className="font-semibold text-sm">Design System</h4>
|
|
439
|
+
<p className="text-xs text-muted-foreground">
|
|
440
|
+
Componentes seguem estritamente as variáveis de tokens do <code>globals.css</code>.
|
|
441
|
+
</p>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
);
|
|
446
|
+
}
|