Frontend: - Migração da API de Geocoding do Mapbox para o Google Maps Places API (googleMapsService.ts) no formulário de eventos, garantindo a busca correta pelo nome de locais (estádios, teatros) e com autopreenchimento. - Correção do fluxo de estado do 'horario_fim', propagando e persistindo o 'endTime' pelo DataContext, garantindo a população dos dados na edição do EventForm. - Adição da visualização do horário final na listagem do Dashboard, no EventCard, painéis de EventDetails e atualização das props defaultEndTime no EventScheduler. Backend: - Atualização e migração dos arquivos gerados pelo sqlc (models.go, agenda.sql.go) para suportar operações no novo design do banco. - Atualização síncrona dos artefatos Swagger de documentação de API (docs.go, swagger.json, swagger.yaml).
130 lines
4.7 KiB
TypeScript
130 lines
4.7 KiB
TypeScript
import { MapboxResult } from "./mapboxService";
|
|
|
|
// Exporting MapboxResult from mapboxService to keep compatibility
|
|
// but using Google Maps to fetch the data.
|
|
|
|
const GOOGLE_MAPS_KEY = import.meta.env.VITE_GOOGLE_MAPS_KEY || "";
|
|
|
|
/**
|
|
* Busca endereços e locais usando a API de Geocoding do Google
|
|
*/
|
|
export async function searchGoogleLocation(query: string, country: string = "br"): Promise<MapboxResult[]> {
|
|
if (!GOOGLE_MAPS_KEY || GOOGLE_MAPS_KEY.includes("YOUR")) {
|
|
console.warn("⚠️ Google Maps Token não configurado em .env.local");
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
const encodedQuery = encodeURIComponent(query);
|
|
const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodedQuery}&components=country:${country}&language=pt-BR&key=${GOOGLE_MAPS_KEY}`;
|
|
|
|
const response = await fetch(url);
|
|
const data = await response.json();
|
|
|
|
if (data.status !== "OK" || !data.results) {
|
|
if (data.status !== "ZERO_RESULTS") {
|
|
console.error("Google Maps API Error:", data.status, data.error_message);
|
|
}
|
|
return [];
|
|
}
|
|
|
|
return data.results.map((result: any) => {
|
|
// Find components
|
|
const getComponent = (type: string) => {
|
|
const comp = result.address_components.find((c: any) => c.types.includes(type));
|
|
return comp ? comp.long_name : "";
|
|
};
|
|
const getShortComponent = (type: string) => {
|
|
const comp = result.address_components.find((c: any) => c.types.includes(type));
|
|
return comp ? comp.short_name : "";
|
|
};
|
|
|
|
const street = getComponent("route");
|
|
const number = getComponent("street_number");
|
|
const city = getComponent("administrative_area_level_2") || getComponent("locality");
|
|
const state = getShortComponent("administrative_area_level_1");
|
|
const zip = getComponent("postal_code");
|
|
|
|
// Verify if it's a POI by checking the types of the location
|
|
const isPoi = result.types.includes("establishment") || result.types.includes("stadium") || result.types.includes("point_of_interest");
|
|
|
|
let placeName = undefined;
|
|
let finalStreet = street;
|
|
|
|
if (isPoi) {
|
|
// Obter o nome do estabelecimento do formatted_address (ex: "Allianz Parque, Av. Francisco Matarazzo...")
|
|
placeName = result.address_components.find((c: any) => c.types.includes("establishment") || c.types.includes("point_of_interest"))?.long_name;
|
|
if (!placeName && result.formatted_address) {
|
|
placeName = result.formatted_address.split(",")[0];
|
|
}
|
|
}
|
|
|
|
// Se a query não conseguiu resolver route/street, usa a formatação
|
|
if (!finalStreet) finalStreet = result.formatted_address;
|
|
|
|
return {
|
|
placeName,
|
|
description: placeName ? `${placeName} - ${result.formatted_address}` : result.formatted_address,
|
|
street: finalStreet,
|
|
number,
|
|
city,
|
|
state,
|
|
zip,
|
|
lat: result.geometry.location.lat,
|
|
lng: result.geometry.location.lng,
|
|
mapLink: `https://www.google.com/maps/search/?api=1&query=${result.geometry.location.lat},${result.geometry.location.lng}`,
|
|
};
|
|
});
|
|
} catch (error) {
|
|
console.error("Erro ao buscar no Google Maps:", error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Busca reversa via Google Maps Geocoding
|
|
*/
|
|
export async function reverseGeocodeGoogle(lat: number, lng: number): Promise<MapboxResult | null> {
|
|
if (!GOOGLE_MAPS_KEY) return null;
|
|
|
|
try {
|
|
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&language=pt-BR&key=${GOOGLE_MAPS_KEY}`;
|
|
const response = await fetch(url);
|
|
const data = await response.json();
|
|
|
|
if (data.status === "OK" && data.results.length > 0) {
|
|
const result = data.results[0];
|
|
|
|
const getComponent = (type: string) => {
|
|
const comp = result.address_components.find((c: any) => c.types.includes(type));
|
|
return comp ? comp.long_name : "";
|
|
};
|
|
const getShortComponent = (type: string) => {
|
|
const comp = result.address_components.find((c: any) => c.types.includes(type));
|
|
return comp ? comp.short_name : "";
|
|
};
|
|
|
|
const street = getComponent("route") || result.formatted_address;
|
|
const number = getComponent("street_number");
|
|
const city = getComponent("administrative_area_level_2") || getComponent("locality");
|
|
const state = getShortComponent("administrative_area_level_1");
|
|
const zip = getComponent("postal_code");
|
|
|
|
return {
|
|
description: result.formatted_address,
|
|
street,
|
|
number,
|
|
city,
|
|
state,
|
|
zip,
|
|
lat,
|
|
lng,
|
|
mapLink: `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`,
|
|
};
|
|
}
|
|
return null;
|
|
} catch (error) {
|
|
console.error("Erro no reverse geocode do Google:", error);
|
|
return null;
|
|
}
|
|
}
|