diff --git a/sepa/bun.lockb b/sepa/bun.lockb index afa3f68..13f51e8 100755 Binary files a/sepa/bun.lockb and b/sepa/bun.lockb differ diff --git a/sepa/package.json b/sepa/package.json index 6e9602f..ddeecd8 100644 --- a/sepa/package.json +++ b/sepa/package.json @@ -3,7 +3,8 @@ "private": true, "type": "module", "devDependencies": { - "@types/bun": "^1.1.7", + "@types/bun": "^1.1.11", + "bun-types": "^1.1.30", "@types/papaparse": "^5.3.14", "drizzle-kit": "^0.24.2" }, diff --git a/sepa/sitio2/package.json b/sepa/sitio2/package.json index 0d9551a..32010a2 100644 --- a/sepa/sitio2/package.json +++ b/sepa/sitio2/package.json @@ -51,12 +51,14 @@ "d3-scale": "^4.0.2", "date-fns": "^4.1.0", "drizzle-orm": "^0.33.0", + "geojson": "^0.5.0", "layerchart": "^0.44.0", "leaflet": "^1.9.4", "leaflet.markercluster": "^1.5.3", "lucide-svelte": "^0.441.0", "maplibre-gl": "^4.7.1", "postgres": "^3.4.4", + "svelte-maplibre": "^0.9.14", "tailwind-merge": "^2.5.2", "tailwind-variants": "^0.2.1" } diff --git a/sepa/sitio2/src/lib/components/ui/button/index.ts b/sepa/sitio2/src/lib/components/ui/button/index.ts index d6431f3..bd777dc 100644 --- a/sepa/sitio2/src/lib/components/ui/button/index.ts +++ b/sepa/sitio2/src/lib/components/ui/button/index.ts @@ -16,8 +16,10 @@ const buttonVariants = tv({ size: { default: 'h-10 px-4 py-2', sm: 'h-9 rounded-md px-3', + xs: 'h-8 rounded-md px-2', lg: 'h-11 rounded-md px-8', - icon: 'h-10 w-10' + icon: 'h-10 w-10', + icon_sm: 'h-8 w-8' } }, defaultVariants: { diff --git a/sepa/sitio2/src/lib/sepa-utils.ts b/sepa/sitio2/src/lib/sepa-utils.ts index 40f1a79..000b157 100644 --- a/sepa/sitio2/src/lib/sepa-utils.ts +++ b/sepa/sitio2/src/lib/sepa-utils.ts @@ -29,6 +29,13 @@ export const pesosFormatter = new Intl.NumberFormat('es-AR', { currency: 'ARS' }); +export const dateFormatter = Intl.DateTimeFormat('es-AR', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + weekday: 'long' +}); + export function parseMarcas(marcas: readonly string[]) { const x = marcas .map((m) => m.trim().replaceAll(/['`´]/g, '')) diff --git a/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte b/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte index 35288dc..e270576 100644 --- a/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte +++ b/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte @@ -1,15 +1,77 @@ @@ -34,84 +96,202 @@ EAN {data.id_producto} + + + + - { - // var markers = L.MarkerClusterGroup(); - const myRenderer = L.canvas({ padding: 0.5 }); - const prices = data.precios.map((p) => p.productos_precio_lista); - const sortedPrices = prices.sort((a, b) => a - b); - const q1Index = Math.floor(sortedPrices.length * 0.1); - const q3Index = Math.floor(sortedPrices.length * 0.9); - const iqr = sortedPrices[q3Index] - sortedPrices[q1Index]; - const lowerBound = sortedPrices[q1Index] - 1.5 * iqr; - const upperBound = sortedPrices[q3Index] + 1.5 * iqr; - const filteredPrices = sortedPrices.filter((p) => p >= lowerBound && p <= upperBound); - const min = Math.min(...filteredPrices); - const max = Math.max(...filteredPrices); - console.log({ min, max, outliers: prices.length - filteredPrices.length }); + - const createElement = () => { - const div = document.createElement('div'); + p.productos_precio_lista)), + 'rgba(0,255,0,0)', + Math.max(...data.precios.map((p) => p.productos_precio_lista)), + 'rgba(255,0,0,1)' + ], + 'circle-radius': ['interpolate', ['linear'], ['zoom'], 3, 4, 10, 6], + 'circle-stroke-width': 1, + 'circle-stroke-color': '#fff' + // 'circle-stroke-opacity': hoverStateFilter(0, 1) + }} + > + + {#if data?.properties} +
+
+ + {dateFormatter.format(new Date(data.properties.fecha))} + + + {pesosFormatter.format(data.properties.precio)} + +
- [ - `fecha del precio: ${precio.dataset_date}`, - `precio: ${pesosFormatter.format(precio.productos_precio_lista)}`, - `comercio: ${processBanderaNombre(precio)} (${precio.comercio_razon_social} CUIT ${precio.comercio_cuit})`, - `sucursal: ${precio.sucursales_nombre}`, - `dirección: ${precio.sucursales_calle} ${precio.sucursales_numero}`, - () => { - const a = document.createElement('a'); - if (precio.sucursales_calle) { - a.href = generateGoogleMapsLink({ - sucursales_calle: precio.sucursales_calle, - sucursales_numero: precio.sucursales_numero - }); - } - a.target = '_blank'; - a.append('ver en Google Maps'); - return a; - }, - `descripcion del producto segun el comercio: ${precio.productos_descripcion}`, - () => { - const a = document.createElement('a'); - a.href = `/id_producto/${data.id_producto}/sucursal/${precio.id_comercio}/${precio.id_sucursal}`; - a.append('ver precios historicos'); - return a; - } - ].forEach((el) => { - div.append(typeof el === 'function' ? el() : el); - div.append(document.createElement('br')); - }); - return div; - }; +
+
+ {data.properties.comercio} + {data.properties.direccion} +
- var marker = L.circleMarker([precio.sucursales_latitud, precio.sucursales_longitud], { - opacity: 1, - renderer: myRenderer, - color, - radius: 5 - }) - .bindPopup(createElement) - .addTo(map); - marker.on('click', function (this: L.CircleMarker) { - this.openPopup(); - }); - } + +
- // Helper function to get a color that works in Safari - function getSafeColor(normalizedPrice: number) { - const r = Math.round(255 * normalizedPrice); - const g = Math.round(255 * (1 - normalizedPrice)); - return `rgb(${r}, ${g}, 0)`; - } - }} - /> +
+ +
+
+ {/if} +
+
+
+
+ +