saveinmed/frontend/src/components/LocationPicker.tsx
eycksilva 3559afc1f7 feat(ui): padronizar paleta #0F4C81 e estrutura em múltiplas telas
- SellerDashboard: migrado para Shell (header topo), removida sidebar lateral,
  cards KPI brancos com react-icons pretos (FaChartLine, FaBoxOpen, FaReceipt)
- Shell: adicionados todos os links de nav para owner/seller no header
  (Estoque, Buscar Produtos, Pedidos, Carteira, Equipe, Config. Entrega)
- Wallet: ícone FaMoneyCheck no botão Solicitar Saque, card saldo com #0F4C81,
  thead da tabela com #0F4C81, fix R$ NaN (formatCurrency null-safe)
- Team: botões e thead com #0F4C81, emojis removidos dos roleLabels
- ShippingSettings: wrapped com Shell (mantém header), emojis substituídos por
  react-icons pretos (FaTruck, FaLocationDot, FaStore, FaCircleInfo, FaFloppyDisk),
  botão Salvar com #0F4C81
- Orders: removido box cinza de fundo dos ícones nas abas e estado vazio
- LocationPicker: fallback seguro para OpenStreetMap quando VITE_MAP_TILE_LAYER
  não está definido (corrige tela branca em /search)
- Inventory/Cart: cores dos botões e thead atualizadas para #0F4C81
2026-02-26 15:56:03 -03:00

63 lines
2.3 KiB
TypeScript

import { MapContainer, TileLayer, Marker, useMapEvents } from 'react-leaflet'
import { useState } from 'react'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
// Fix generic Leaflet icon missing in webpack/vite
import icon from 'leaflet/dist/images/marker-icon.png'
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
const DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
iconSize: [25, 41],
iconAnchor: [12, 41]
})
L.Marker.prototype.options.icon = DefaultIcon
// Use env vars with safe fallback to OpenStreetMap
const TILE_URL = import.meta.env.VITE_MAP_TILE_LAYER ||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
const TILE_ATTR = import.meta.env.VITE_MAP_ATTRIBUTION ||
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
interface LocationPickerProps {
initialLat?: number
initialLng?: number
onLocationSelect: (lat: number, lng: number) => void
}
const LocationMarker = ({ onLocationSelect }: { onLocationSelect: (lat: number, lng: number) => void }) => {
const [position, setPosition] = useState<L.LatLng | null>(null)
const map = useMapEvents({
click(e) {
setPosition(e.latlng)
onLocationSelect(e.latlng.lat, e.latlng.lng)
map.flyTo(e.latlng, map.getZoom())
},
})
return position === null ? null : (
<Marker position={position} />
)
}
export const LocationPicker = ({ initialLat, initialLng, onLocationSelect }: LocationPickerProps) => {
const defaultPosition: [number, number] = [-16.3285, -48.9534] // Anápolis center
const center = (initialLat && initialLng) ? [initialLat, initialLng] as [number, number] : defaultPosition
return (
<div className="h-[300px] w-full rounded-lg overflow-hidden border border-gray-300">
<MapContainer center={center} zoom={13} scrollWheelZoom={true} style={{ height: '100%', width: '100%' }}>
<TileLayer
attribution={TILE_ATTR}
url={TILE_URL}
/>
<LocationMarker onLocationSelect={onLocationSelect} />
{(initialLat && initialLng) && <Marker position={[initialLat, initialLng]} />}
</MapContainer>
</div>
)
}