UNPKG

autocomplete-gcba-component

Version:

Componente React de autocompletado de direcciones para GCBA

3 lines (2 loc) 16.6 kB
"use strict";var e=require("react/jsx-runtime"),a=require("react"),r=require("axios");const t="https://servicios.usig.buenosaires.gob.ar";class s{debug;maxSuggestions;lastRequest;serverTimeout;constructor(e={}){this.debug=e.debug||!1,this.maxSuggestions=e.maxSuggestions||10,this.serverTimeout=e.serverTimeout||5e3,this.lastRequest=null}abort(){this.lastRequest&&(this.lastRequest.abort(),this.lastRequest=null,this.debug&&console.debug("Request aborted"))}async normalizar(e,a=this.maxSuggestions){this.debug&&console.debug(`ApiNormalizer.normalizar('${e}', ${a})`),this.abort(),this.lastRequest=new AbortController;try{let r=[];const t=await this.searchAddresses(e,a);r=[...r,...t];const s=this.parseCoordinates(e);if(s){const e=await this.reverseGeocode(s.x,s.y);r=[...r,...e]}return r.slice(0,a)}catch(e){return r.isCancel(e)?this.debug&&console.debug("Request was cancelled"):console.error("Error normalizing address:",e),[]}finally{this.lastRequest=null}}async searchAddresses(e,a){try{const s=`${t}/normalizar/?direccion=${encodeURIComponent(e)}&geocodificar=true&max=${a}`,o={headers:{Accept:"application/json"},signal:this.lastRequest?.signal,timeout:this.serverTimeout},i=await r.get(s,o);if(i.data.error)return this.debug&&console.error("API error:",i.data.error),[];if(i.data.direccionesNormalizadas&&i.data.direccionesNormalizadas.length>0){const e=i.data.direccionesNormalizadas.filter((e=>{const a=e.cod_partido?.toLowerCase(),r=e.nombre_partido?.toLowerCase(),t=e.nombre_localidad?.toLowerCase();return"caba"===a||"caba"===r||"caba"===t})),a=await Promise.all(e.map((async e=>{const a=await this.obtenerCoordenadas(e.cod_calle??"",Number(e.altura??0),{x:Number.parseFloat(e.coordenadas?.x??"0"),y:Number.parseFloat(e.coordenadas?.y??"0")});if(a){const{barrio:r,comuna:t}=await this.obtenerBarrioYComuna(a.y,a.x);return{...e,altura_par:a.altura_par,altura_impar:a.altura_impar,calle_alturas:a.calle_alturas,coordenadas:{x:a.x.toString(),y:a.y.toString(),srid:4326},barrio:r,comuna:t}}return e})));return this.processDireccionesNormalizadas(a)}return i.data.calles&&i.data.calles.length>0?this.processCalles(i.data.calles):[]}catch(e){return r.isCancel(e)?this.debug&&console.debug("Address search request was cancelled"):console.error("Error searching addresses:",e),[]}}async obtenerBarrioYComuna(e,a){try{const t=`https://ws.usig.buenosaires.gob.ar/datos_utiles/?x=${a}&y=${e}`,s=(await r.get(t)).data,o=s?.barrio,i=s?.comuna;return{barrio:o,comuna:i}}catch(e){return console.error("Error al obtener barrio y comuna:",e),{}}}async obtenerCoordenadas(e,a,t){try{if(t){const e=`https://ws.usig.buenosaires.gob.ar/geocoder/2.2/reversegeocoding?x=${t.x}&y=${t.y}`,a=`https://ws.usig.buenosaires.gob.ar/rest/convertir_coordenadas/?x=${t.x}&y=${t.y}&output=lonlat`,s=await r.get(a),o=(await r.get(e)).data.replace(/^\(|\)$/g,""),{calle_alturas:i,altura_impar:c,altura_par:n}=JSON.parse(o),{x:l,y:d}=s.data.resultado;return{y:d,x:l,altura_par:n,altura_impar:c,calle_alturas:i}}const s=`https://ws.usig.buenosaires.gob.ar/geocoder/2.2/geocoding?cod_calle=${encodeURIComponent(e)}&altura=${a}`,o=await r.get(s),i=o.data.replace(/^\(|\)$/g,""),c=JSON.parse(i),{x:n,y:l}=c,d=`https://ws.usig.buenosaires.gob.ar/geocoder/2.2/reversegeocoding?x=${n}&y=${l}`,u=`https://ws.usig.buenosaires.gob.ar/rest/convertir_coordenadas/?x=${n}&y=${l}&output=lonlat`,m=await r.get(u),p=(await r.get(d)).data.replace(/^\(|\)$/g,""),{calle_alturas:g,altura_impar:b,altura_par:h}=JSON.parse(p),{x:x,y:C}=m.data.resultado;return{y:C,x:x,altura_par:h,altura_impar:b,calle_alturas:g}}catch(e){return console.error("Error al obtener coordenadas:",e),null}}parseCoordinates(e){const a=e.trim().replace(/\s+/g,""),r=[/^(-?\d+\.?\d*),(-?\d+\.?\d*)$/,/x:?(-?\d+\.?\d*)[,\s]+y:?(-?\d+\.?\d*)/i,/y:?(-?\d+\.?\d*)[,\s]+x:?(-?\d+\.?\d*)/i];for(const e of r){const t=a.match(e);if(t){if(e===r[0])return{y:Number.parseFloat(t[1]),x:Number.parseFloat(t[2])};if(e===r[1])return{x:Number.parseFloat(t[1]),y:Number.parseFloat(t[2])};if(e===r[2])return{y:Number.parseFloat(t[1]),x:Number.parseFloat(t[2])}}}return null}async reverseGeocode(e,a){this.debug&&console.debug(`ApiNormalizer.reverseGeocode(${e}, ${a})`),this.abort(),this.lastRequest=new AbortController;try{const s=`${t}/reverseGeocoderLugares/?x=${e}&y=${a}&srid=4326`,o={headers:{Accept:"application/json"},signal:this.lastRequest.signal,timeout:this.serverTimeout},i=await r.get(s,o);if(i.data.error)return this.debug&&console.error("Reverse geocoding API error:",i.data.error),[];if(!i.data.direccion)return[];const c={codigo:i.data.cod_calle||"coord",nombre:i.data.nombre||i.data.direccion||"Coordenada",descripcion:i.data.direccion||"Coordenada",tipo:"CALLE",alturas:[{inicio:1,fin:1e4}]};let n=0;i.data.altura&&(n=Number.parseInt(i.data.altura,10));return[{calle:c,altura:n||1,tipoDireccion:"DIRECCION_CALLE_ALTURA",tipo:"DIRECCION",nombre:i.data.direccion||`Coordenada (${e.toFixed(6)}, ${a.toFixed(6)})`,descripcion:`Coordenada (${e.toFixed(6)}, ${a.toFixed(6)})`,coordenadas:{x:e,y:a,srid:i.data.coordenadas?.srid||4326},barrio:i.data.nombre_barrio,altura_par:i.data.altura_par,altura_impar:i.data.altura_impar,calle_alturas:i.data.calle_alturas,comuna:i.data.nombre_comuna}]}catch(e){return r.isCancel(e)?this.debug&&console.debug("Reverse geocoding request was cancelled"):console.error("Error in reverse geocoding:",e),[]}finally{this.lastRequest=null}}processDireccionesNormalizadas(e){if(!e)return Promise.resolve([]);const a=e.map((async e=>{if(!e.direccion||!e.cod_calle)return null;const a={codigo:e.cod_calle,nombre:e.nombre||e.direccion.split(" ")[0],descripcion:e.direccion,tipo:"CALLE",alturas:[{inicio:1,fin:1e4}]};let r;if(e.direccion.includes(" y ")){const t=e.direccion.split(" y ").map((e=>e.trim()));r={calle:a,calleCruce:{codigo:`${e.cod_calle}_cruce`,nombre:t[1]||"Calle cruce",descripcion:t[1]||"Calle cruce",tipo:"CALLE",alturas:[{inicio:1,fin:1e4}]},tipoDireccion:"DIRECCION_CALLE_Y_CALLE",tipo:"DIRECCION",nombre:e.direccion,descripcion:e.direccion,coordenadas:e.coordenadas?{x:Number.parseFloat(e.coordenadas.x),y:Number.parseFloat(e.coordenadas.y),srid:e.coordenadas.srid}:void 0,barrio:e.barrio,comuna:e.comuna,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas}}else{const t=e.altura?Number.parseInt(e.altura,10):0;if(r={calle:a,altura:t,tipoDireccion:"DIRECCION_CALLE_ALTURA",tipo:"DIRECCION",nombre:e.direccion,descripcion:e.direccion,coordenadas:e.coordenadas?{x:Number.parseFloat(e.coordenadas.x),y:Number.parseFloat(e.coordenadas.y),srid:e.coordenadas.srid}:void 0,barrio:e.barrio,comuna:e.comuna,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas},t>0)try{const a=await this.getSMP({nombre:e.direccion,descripcion:e.direccion||"",tipo:"DIRECCION",codigo:e.cod_calle,altura:e.altura,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas,calle:{codigo:e.cod_calle}});a&&(r.smp=a)}catch(e){this.debug&&console.error("Error getting SMP:",e)}}return r}));return Promise.all(a).then((e=>e.filter(Boolean)))}processCalles(e){return e?e.map((e=>({codigo:e.cod_calle,nombre:e.nombre,descripcion:e.tipo?`${e.tipo} ${e.nombre}`:e.nombre,tipo:"CALLE",alturas:[{inicio:e.altura?.inicial||1,fin:e.altura?.final||1e4}],partido:e.partido,localidad:e.localidad}))):[]}async getCoordinates(e){try{this.abort(),this.lastRequest=new AbortController;const a=`${t}/normalizar/?direccion=${encodeURIComponent(e.nombre)},${encodeURIComponent(e.descripcion)}&geocodificar=true&srid=4326`,s={headers:{Accept:"application/json"},signal:this.lastRequest.signal,timeout:this.serverTimeout},o=await r.get(a,s),i=o.data.direccionesNormalizadas?.[0];if(i?.coordenadas){const e=i.coordenadas;return{x:Number.parseFloat(e.x),y:Number.parseFloat(e.y),srid:e.srid}}return}catch(e){return void(r.isCancel(e)?this.debug&&console.debug("Request was aborted"):console.error("Error fetching coordinates:",e))}finally{this.lastRequest=null}}async getSMP(e){try{this.abort(),this.lastRequest=new AbortController;const a=e.codigo||e.calle?.codigo;if(!a||!e.altura)return;const t=`https://epok.buenosaires.gob.ar/catastro/parcela/?codigo_calle=${encodeURIComponent(a)}&altura=${encodeURIComponent(String(e.altura))}&geocodificar=true&srid=4326`,s={headers:{Accept:"application/json"},signal:this.lastRequest.signal,timeout:this.serverTimeout};return(await r.get(t,s)).data.smp}catch(e){return void(r.isCancel(e)?this.debug&&console.debug("Request was aborted"):console.error("Error fetching catastro data:",e))}finally{this.lastRequest=null}}static inicializado(){return!0}}const o=({className:a="",size:r=24,color:t="currentColor"})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:a,children:e.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),i=({className:a="",size:r=24,color:t="currentColor"})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:a,children:e.jsx("polygon",{points:"3,11 22,2 13,21 11,13 3,11"})});exports.AddressSearch=({maxSuggestions:r=10,onAddressSelect:t,onAddressesRemove:c,placeholder:n="Buscar dirección o coordenadas...",debug:l=!1,className:d="",inputClassName:u="",selectedAddresses:m=[],suggestionsClassName:p="",suggestionItemClassName:g="",selectedAddressesClassName:b="",loadingClassName:h="",suggestionsContainerClassName:x="",selectedAddressesContainerClassName:C="",selectedAddressItemClassName:_="",removeButtonClassName:N="",errorClassName:y="",iconClassName:f="",titleClassName:v="",coordsClassName:$="",smpClassName:A="",serverTimeout:w=5e3,isDebug:L=!1})=>{const[R,j]=a.useState(""),[E,S]=a.useState([]),[F,I]=a.useState(!1),[T,q]=a.useState(!1),[D,z]=a.useState(null),B=a.useRef(null),k=a.useRef(null);a.useEffect((()=>(k.current=new s({debug:l,maxSuggestions:r,serverTimeout:w}),()=>{B.current&&clearTimeout(B.current),k.current&&k.current.abort()})),[l,r,w]);const O=e=>"CALLE"===e.tipo?{title:e.nombre,subTitle:e.descripcion||"CABA",type:"CALLE",category:"CALLE",suggesterName:"Direcciones",data:{nombre:e.nombre,descripcion:e.descripcion||"",tipo:"CALLE",codigo:e.codigo,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas}}:{title:e.nombre,subTitle:e.descripcion||"CABA",type:e.tipoDireccion,category:e.tipoDireccion,suggesterName:"Direcciones",data:{nombre:e.nombre,descripcion:e.descripcion||"",tipo:e.tipo,codigo:e.calle.codigo,altura:"DIRECCION_CALLE_ALTURA"===e.tipoDireccion?e.altura:void 0,calle:{codigo:e.calle.codigo},coordenadas:e.coordenadas,smp:e.smp,barrio:e.barrio,comuna:e.comuna,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas}},P=a.useCallback((async e=>{if(l&&console.debug(`getSuggestions('${e}')`),!k.current||!e||e.length<3)S([]);else try{I(!0),z(null);const a=(await k.current.normalizar(e,r)).map(O);S(a),q(!0),0===a.length&&z("No se encontraron resultados")}catch(e){console.error("Error getting suggestions:",e),S([]),z("Error al buscar direcciones")}finally{I(!1)}}),[l,r]);return e.jsxs("div",{className:`w-full ${d}`,children:[e.jsxs("div",{className:"relative max-w-[500px]",children:[e.jsx("input",{type:"text",value:R,onChange:e=>{const a=e.target.value;j(a),z(null),B.current&&clearTimeout(B.current),k.current&&k.current.abort(),a.length>=3?(q(!0),I(!0),B.current=setTimeout((()=>{P(a)}),300)):(S([]),q(!1),I(!1))},onFocus:()=>{R.length>=3&&q(!0)},onBlur:()=>{setTimeout((()=>{q(!1)}),200)},placeholder:n,className:`w-full h-[24px] p-[8px] border rounded ${u}`}),F&&e.jsx("div",{className:`absolute right-[0] top-1/2 transform -translate-y-1/2 ${h}`,children:e.jsx(o,{className:"h-4 w-4 text-gray-500 animate-spin"})}),(T||F)&&e.jsx("div",{className:`absolute z-10 w-full bg-[#FFFFFF] border border-t-0 rounded shadow-lg max-h-[200px] overflow-auto px-[8px] ${x}`,children:F?e.jsxs("div",{className:`p-[8px] flex items-center justify-center gap-[8px] text-gray-500 ${p}`,children:[e.jsx(o,{className:"h-5 w-2 animate-spin mb-2"}),e.jsx("span",{children:"Buscando direcciones..."})]}):E.length>0?E.map(((a,r)=>e.jsx("div",{className:`my-[8px] border-b border-[#b8b5b4] last:border-b-0 cursor-pointer hover:bg-[#dfe0e1] transition duration-300 ease-in-out bg-white rounded-[4px] w-[100%] ${g}`,onClick:()=>(e=>{m.some((a=>a.data?.nombre===e.data?.nombre))||t(e),j(""),S([]),q(!1)})(a),children:e.jsxs("div",{className:"flex items-center gap-[8px]",children:[e.jsx("div",{children:e.jsx(i,{className:`h-4 text-[#0042ff] ${f}`})}),e.jsxs("div",{className:"flex flex-center gap-[8px]",children:[e.jsxs("span",{className:`font-medium text-[14px] truncate ${v}`,children:[a.title,"."]}),a.data.coordenadas&&e.jsxs("span",{className:`text-xs text-gray-400 truncate ${$}`,children:["Coord: ",a.data.coordenadas.x.toFixed(6),","," ",a.data.coordenadas.y.toFixed(6)]}),a.data.smp&&e.jsxs("span",{className:`text-xs text-gray-400 ${A}`,children:["SMP: ",a.data.smp]})]})]})},`${a.data.nombre}-${r}`))):R.length>=3?e.jsx("div",{className:`p-[8px] text-center text-red-500 ${y}`,children:D||"No se encontraron resultados"}):e.jsx("div",{className:`p-4 text-center text-gray-500 ${p}`,children:"Ingrese al menos 3 caracteres para buscar"})}),D&&!F&&!T&&e.jsx("div",{className:`mt-[8px] text-sm text-red-500 ${y}`,children:D})]}),L&&e.jsx(e.Fragment,{children:m.length>0&&e.jsxs("div",{className:`${b} ${C}`,children:[e.jsx("h3",{className:"text-sm font-medium mb-2",children:"Direcciones seleccionadas:"}),e.jsx("ul",{className:"space-y-2",children:m.map(((a,r)=>e.jsxs("li",{className:`flex justify-between items-center p-2 bg-gray-50 rounded ${_}`,children:[e.jsxs("div",{className:"flex items-center gap-[8px]",children:[e.jsx("div",{className:"mt-1",children:e.jsx(i,{className:`h-4 w-4 text-[#0042ff] ${f}`})}),e.jsxs("div",{className:"flex flex-center gap-[8px]",children:[e.jsxs("div",{className:`font-medium ${v}`,children:[a.title,"."]}),a.data.coordenadas&&e.jsxs("div",{className:`text-xs text-gray-400 ${$}`,children:["Coord: ",a.data.coordenadas.x.toFixed(6),","," ",a.data.coordenadas.y.toFixed(6)]}),a.data.smp&&e.jsxs("div",{className:`text-xs text-gray-400 ${A}`,children:["SMP: ",a.data.smp]})]})]}),e.jsx("button",{type:"button",onClick:()=>(e=>{c(e)})(r),className:`text-[#FFF] bg-[#ff0000] rounded-[4px] border-0 h-[24px] w-[24px] cursor-pointer transition duration-300 ease-in-out hover:scale-125 ${N}`,children:"×"})]},`selected-${r}`)))})]})})]})},exports.useAddressSearch=function(e={}){const{maxSuggestions:r=10,debug:t=!1,serverTimeout:o=5e3}=e,[i,c]=a.useState(""),[n,l]=a.useState([]),[d,u]=a.useState([]),[m,p]=a.useState(!1),[g,b]=a.useState(null),[h,x]=a.useState(!1),C=a.useRef(null),_=a.useRef(null);a.useEffect((()=>(_.current=new s({debug:t,maxSuggestions:r,serverTimeout:o}),()=>{C.current&&clearTimeout(C.current),_.current&&_.current.abort()})),[t,r,o]);const N=e=>"CALLE"===e.tipo?{title:e.nombre,subTitle:e.descripcion||"CABA",type:"CALLE",category:"CALLE",suggesterName:"Direcciones",data:{nombre:e.nombre,descripcion:e.descripcion||"",tipo:"CALLE",codigo:e.codigo,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas}}:{title:e.nombre,subTitle:e.descripcion||"CABA",type:e.tipoDireccion,category:e.tipoDireccion,suggesterName:"Direcciones",data:{nombre:e.nombre,descripcion:e.descripcion||"",tipo:e.tipo,codigo:e.calle.codigo,altura:"DIRECCION_CALLE_ALTURA"===e.tipoDireccion?e.altura:void 0,calle:{codigo:e.calle.codigo},coordenadas:e.coordenadas,altura_par:e.altura_par,altura_impar:e.altura_impar,calle_alturas:e.calle_alturas,smp:e.smp}},y=a.useCallback((async e=>{if(t&&console.debug(`fetchSuggestions('${e}')`),!_.current||!e||e.length<3)l([]);else try{p(!0),b(null);const a=(await _.current.normalizar(e,r)).map(N);l(a),0===a.length&&b("No se encontraron resultados")}catch(e){console.error("Error getting suggestions:",e),l([]),b("Error al buscar direcciones")}finally{p(!1)}}),[t,r]);return{searchText:i,setSearchText:c,suggestions:n,selectedAddresses:d,isLoading:m,error:g,showSuggestions:h,setShowSuggestions:x,handleInputChange:e=>{const a=e.target.value;c(a),b(null),C.current&&clearTimeout(C.current),_.current&&_.current.abort(),a.length>=3?C.current=setTimeout((()=>{y(a)}),300):l([])},handleSelectSuggestion:e=>{d.some((a=>a.data?.nombre===e.data.nombre))||u((a=>[...a,e])),c(""),l([]),x(!1)},handleRemoveAddress:e=>{u((a=>{const r=[...a];return r.splice(e,1),r}))},handleInputFocus:()=>{i.length>=3&&n.length>0&&x(!0)},handleInputBlur:()=>{setTimeout((()=>{x(!1)}),200)}}}; //# sourceMappingURL=index.cjs.js.map