Showing
26 changed files
with
108 additions
and
120 deletions
This diff is collapsed. Click to expand it.
| ... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
| 21 | "dependencies": { | 21 | "dependencies": { |
| 22 | "@observablehq/plot": "^0.6.17", | 22 | "@observablehq/plot": "^0.6.17", |
| 23 | "@supabase/supabase-js": "^2.98.0", | 23 | "@supabase/supabase-js": "^2.98.0", |
| 24 | + "@sveltejs/adapter-node": "^5.5.4", | ||
| 24 | "d3": "^7.9.0", | 25 | "d3": "^7.9.0", |
| 25 | "fuse.js": "^7.1.0", | 26 | "fuse.js": "^7.1.0", |
| 26 | "hyparquet": "^1.25.1", | 27 | "hyparquet": "^1.25.1", | ... | ... |
src/lib/assets/favicon.ico
0 → 100644
No preview for this file type
| ... | @@ -133,22 +133,31 @@ | ... | @@ -133,22 +133,31 @@ |
| 133 | <a | 133 | <a |
| 134 | href="/" | 134 | href="/" |
| 135 | onclick={closeDrawer} | 135 | onclick={closeDrawer} |
| 136 | - class="w-full flex items-center gap-3 px-3 py-3 rounded-lg transition-colors text-left mb-4" | 136 | + class="w-full flex items-center px-3 py-2.5 rounded-lg transition-colors text-left" |
| 137 | style="background-color: {$page.url.pathname === '/' ? 'var(--theme-fill)' : 'transparent'};" | 137 | style="background-color: {$page.url.pathname === '/' ? 'var(--theme-fill)' : 'transparent'};" |
| 138 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 138 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 139 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/' ? 'var(--theme-fill)' : 'transparent'} | 139 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/' ? 'var(--theme-fill)' : 'transparent'} |
| 140 | > | 140 | > |
| 141 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-texto);" fill="currentColor" viewBox="0 0 20 20"> | 141 | + <span class="text-sm" style="color: var(--theme-titulo);">Inicio / Buscador</span> |
| 142 | - <rect x="2" y="2" width="7" height="7" rx="1.5"/> | ||
| 143 | - <rect x="11" y="2" width="7" height="7" rx="1.5"/> | ||
| 144 | - <rect x="2" y="11" width="7" height="7" rx="1.5"/> | ||
| 145 | - <rect x="11" y="11" width="7" height="7" rx="1.5"/> | ||
| 146 | - </svg> | ||
| 147 | - <span class="font-medium text-sm" style="color: var(--theme-titulo);">Inicio / Buscador</span> | ||
| 148 | </a> | 142 | </a> |
| 149 | 143 | ||
| 144 | + <!-- Descargas --> | ||
| 145 | + <a | ||
| 146 | + href="/descargas" | ||
| 147 | + onclick={closeDrawer} | ||
| 148 | + class="w-full flex items-center px-3 py-2.5 rounded-lg transition-colors text-left mb-4" | ||
| 149 | + style="background-color: {$page.url.pathname === '/descargas' ? 'var(--theme-fill)' : 'transparent'};" | ||
| 150 | + onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | ||
| 151 | + onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/descargas' ? 'var(--theme-fill)' : 'transparent'} | ||
| 152 | + > | ||
| 153 | + <span class="text-sm" style="color: var(--theme-titulo);">Descargas</span> | ||
| 154 | + </a> | ||
| 155 | + | ||
| 156 | + <!-- Separador --> | ||
| 157 | + <div class="border-t mb-4" style="border-color: var(--theme-borde);"></div> | ||
| 158 | + | ||
| 150 | <!-- Clasificadores --> | 159 | <!-- Clasificadores --> |
| 151 | - <div class="mb-6"> | 160 | + <div class="mb-4"> |
| 152 | <h3 class="text-xs font-semibold uppercase tracking-wider mb-3 px-2" style="color: var(--theme-texto);"> | 161 | <h3 class="text-xs font-semibold uppercase tracking-wider mb-3 px-2" style="color: var(--theme-texto);"> |
| 153 | Navegar por clasificadores | 162 | Navegar por clasificadores |
| 154 | </h3> | 163 | </h3> |
| ... | @@ -157,13 +166,13 @@ | ... | @@ -157,13 +166,13 @@ |
| 157 | <a | 166 | <a |
| 158 | href={c.href} | 167 | href={c.href} |
| 159 | onclick={closeDrawer} | 168 | onclick={closeDrawer} |
| 160 | - class="w-full flex items-center justify-between px-3 py-2.5 rounded-lg transition-colors text-left group" | 169 | + class="w-full flex items-center justify-between px-3 py-2 rounded-lg transition-colors text-left group" |
| 161 | style="background-color: {isActive(c.href) ? 'var(--theme-fill)' : 'transparent'};" | 170 | style="background-color: {isActive(c.href) ? 'var(--theme-fill)' : 'transparent'};" |
| 162 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 171 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 163 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = isActive(c.href) ? 'var(--theme-fill)' : 'transparent'} | 172 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = isActive(c.href) ? 'var(--theme-fill)' : 'transparent'} |
| 164 | > | 173 | > |
| 165 | <div class="flex-1 min-w-0"> | 174 | <div class="flex-1 min-w-0"> |
| 166 | - <span class="text-sm font-medium block" style="color: var(--theme-titulo);">{c.nombre}</span> | 175 | + <span class="text-sm block" style="color: var(--theme-titulo);">{c.nombre}</span> |
| 167 | <span class="text-xs" style="color: var(--theme-texto);">{c.desc}</span> | 176 | <span class="text-xs" style="color: var(--theme-texto);">{c.desc}</span> |
| 168 | </div> | 177 | </div> |
| 169 | <svg | 178 | <svg |
| ... | @@ -178,86 +187,52 @@ | ... | @@ -178,86 +187,52 @@ |
| 178 | </svg> | 187 | </svg> |
| 179 | </a> | 188 | </a> |
| 180 | {/each} | 189 | {/each} |
| 181 | - </div> | ||
| 182 | - </div> | ||
| 183 | - | ||
| 184 | - <!-- Ver todos los clasificadores --> | ||
| 185 | <a | 190 | <a |
| 186 | href="/clasificadores" | 191 | href="/clasificadores" |
| 187 | onclick={closeDrawer} | 192 | onclick={closeDrawer} |
| 188 | - class="w-full flex items-center gap-3 px-3 py-3 rounded-lg transition-colors text-left mb-6" | 193 | + class="w-full flex items-center px-3 py-2 rounded-lg transition-colors text-left mt-1" |
| 189 | style="background-color: {$page.url.pathname === '/clasificadores' ? 'var(--theme-fill)' : 'transparent'};" | 194 | style="background-color: {$page.url.pathname === '/clasificadores' ? 'var(--theme-fill)' : 'transparent'};" |
| 190 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 195 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 191 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/clasificadores' ? 'var(--theme-fill)' : 'transparent'} | 196 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/clasificadores' ? 'var(--theme-fill)' : 'transparent'} |
| 192 | > | 197 | > |
| 193 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-accent);" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"> | 198 | + <span class="text-xs" style="color: var(--theme-texto);">Ver todos los clasificadores</span> |
| 194 | - <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z"/> | ||
| 195 | - </svg> | ||
| 196 | - <span class="text-sm" style="color: var(--theme-accent);">Ver todos los clasificadores</span> | ||
| 197 | </a> | 199 | </a> |
| 200 | + </div> | ||
| 201 | + </div> | ||
| 198 | 202 | ||
| 199 | <!-- Separador --> | 203 | <!-- Separador --> |
| 200 | - <div class="border-t my-4" style="border-color: var(--theme-borde);"></div> | 204 | + <div class="border-t mb-4" style="border-color: var(--theme-borde);"></div> |
| 201 | 205 | ||
| 202 | <!-- Enlaces --> | 206 | <!-- Enlaces --> |
| 203 | <div class="space-y-1"> | 207 | <div class="space-y-1"> |
| 204 | <a | 208 | <a |
| 205 | href="/documentacion" | 209 | href="/documentacion" |
| 206 | onclick={closeDrawer} | 210 | onclick={closeDrawer} |
| 207 | - class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg transition-colors text-left" | 211 | + class="w-full flex items-center px-3 py-2 rounded-lg transition-colors text-left" |
| 208 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 212 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 209 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} | 213 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} |
| 210 | > | 214 | > |
| 211 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-texto);" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"> | ||
| 212 | - <path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25"/> | ||
| 213 | - </svg> | ||
| 214 | <span class="text-sm" style="color: var(--theme-titulo);">Documentación</span> | 215 | <span class="text-sm" style="color: var(--theme-titulo);">Documentación</span> |
| 215 | </a> | 216 | </a> |
| 216 | <a | 217 | <a |
| 217 | href="/sobre" | 218 | href="/sobre" |
| 218 | onclick={closeDrawer} | 219 | onclick={closeDrawer} |
| 219 | - class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg transition-colors text-left" | 220 | + class="w-full flex items-center px-3 py-2 rounded-lg transition-colors text-left" |
| 220 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 221 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 221 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} | 222 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} |
| 222 | > | 223 | > |
| 223 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-texto);" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"> | ||
| 224 | - <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"/> | ||
| 225 | - </svg> | ||
| 226 | <span class="text-sm" style="color: var(--theme-titulo);">Sobre el proyecto</span> | 224 | <span class="text-sm" style="color: var(--theme-titulo);">Sobre el proyecto</span> |
| 227 | </a> | 225 | </a> |
| 228 | - </div> | ||
| 229 | - | ||
| 230 | - <!-- Separador --> | ||
| 231 | - <div class="border-t my-4" style="border-color: var(--theme-borde);"></div> | ||
| 232 | - | ||
| 233 | - <!-- Descargas --> | ||
| 234 | - <a | ||
| 235 | - href="/descargas" | ||
| 236 | - onclick={closeDrawer} | ||
| 237 | - class="w-full flex items-center gap-3 px-3 py-3 rounded-lg transition-colors text-left" | ||
| 238 | - style="background-color: {$page.url.pathname === '/descargas' ? 'var(--theme-fill)' : 'transparent'};" | ||
| 239 | - onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | ||
| 240 | - onmouseleave={(e) => e.currentTarget.style.backgroundColor = $page.url.pathname === '/descargas' ? 'var(--theme-fill)' : 'transparent'} | ||
| 241 | - > | ||
| 242 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-accent);" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"> | ||
| 243 | - <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/> | ||
| 244 | - </svg> | ||
| 245 | - <span class="text-sm font-medium" style="color: var(--theme-accent);">Descargas</span> | ||
| 246 | - </a> | ||
| 247 | - | ||
| 248 | - <!-- Créditos --> | ||
| 249 | <a | 226 | <a |
| 250 | href="/creditos" | 227 | href="/creditos" |
| 251 | onclick={closeDrawer} | 228 | onclick={closeDrawer} |
| 252 | - class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg transition-colors text-left mt-2" | 229 | + class="w-full flex items-center px-3 py-2 rounded-lg transition-colors text-left" |
| 253 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} | 230 | onmouseenter={(e) => e.currentTarget.style.backgroundColor = 'var(--theme-fill)'} |
| 254 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} | 231 | onmouseleave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} |
| 255 | > | 232 | > |
| 256 | - <svg class="w-4 h-4 flex-shrink-0" style="color: var(--theme-texto);" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"> | ||
| 257 | - <path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z"/> | ||
| 258 | - </svg> | ||
| 259 | <span class="text-sm" style="color: var(--theme-texto);">Créditos institucionales</span> | 233 | <span class="text-sm" style="color: var(--theme-texto);">Créditos institucionales</span> |
| 260 | </a> | 234 | </a> |
| 235 | + </div> | ||
| 261 | </nav> | 236 | </nav> |
| 262 | 237 | ||
| 263 | <!-- Footer --> | 238 | <!-- Footer --> | ... | ... |
| ... | @@ -220,7 +220,7 @@ | ... | @@ -220,7 +220,7 @@ |
| 220 | const url = `${base}${item.codigo}`; | 220 | const url = `${base}${item.codigo}`; |
| 221 | console.log('[SEARCH] goToResult:', item.tipo, item.codigo, '→', url); | 221 | console.log('[SEARCH] goToResult:', item.tipo, item.codigo, '→', url); |
| 222 | open = false; | 222 | open = false; |
| 223 | - window.location.href = url; | 223 | + goto(url); |
| 224 | } | 224 | } |
| 225 | } | 225 | } |
| 226 | 226 | ... | ... |
| 1 | <script> | 1 | <script> |
| 2 | import '../app.css'; | 2 | import '../app.css'; |
| 3 | import { page, navigating } from '$app/stores'; | 3 | import { page, navigating } from '$app/stores'; |
| 4 | - import favicon from '$lib/assets/favicon.svg'; | 4 | + import favicon from '$lib/assets/favicon.ico'; |
| 5 | import Navbar from '$lib/components/ui/Navbar.svelte'; | 5 | import Navbar from '$lib/components/ui/Navbar.svelte'; |
| 6 | import NavigationDrawer from '$lib/components/layout/NavigationDrawer.svelte'; | 6 | import NavigationDrawer from '$lib/components/layout/NavigationDrawer.svelte'; |
| 7 | import SearchModal from '$lib/components/ui/SearchModal.svelte'; | 7 | import SearchModal from '$lib/components/ui/SearchModal.svelte'; | ... | ... |
| 1 | <script> | 1 | <script> |
| 2 | import { onMount } from 'svelte'; | 2 | import { onMount } from 'svelte'; |
| 3 | + import { goto } from '$app/navigation'; | ||
| 3 | import { landingSearchMode, landingSelectedClassifiers, landingSearchQuery } from '$lib/stores/landingSearchState'; | 4 | import { landingSearchMode, landingSelectedClassifiers, landingSearchQuery } from '$lib/stores/landingSearchState'; |
| 4 | import { openDrawer } from '$lib/stores/drawer.js'; | 5 | import { openDrawer } from '$lib/stores/drawer.js'; |
| 5 | 6 | ||
| ... | @@ -811,7 +812,7 @@ | ... | @@ -811,7 +812,7 @@ |
| 811 | url = `/programa/${generateCodigo(hit)}`; | 812 | url = `/programa/${generateCodigo(hit)}`; |
| 812 | } | 813 | } |
| 813 | 814 | ||
| 814 | - window.location.href = url; | 815 | + goto(url); |
| 815 | } | 816 | } |
| 816 | 817 | ||
| 817 | function clearSearch() { | 818 | function clearSearch() { |
| ... | @@ -1123,7 +1124,7 @@ | ... | @@ -1123,7 +1124,7 @@ |
| 1123 | {#each EXAMPLES_PROGRAMAS as ex} | 1124 | {#each EXAMPLES_PROGRAMAS as ex} |
| 1124 | <span | 1125 | <span |
| 1125 | class="mode-pill" | 1126 | class="mode-pill" |
| 1126 | - onclick={() => searchFromPill(ex.label)} | 1127 | + onclick={(e) => { e.stopPropagation(); searchFromPill(ex.label); }} |
| 1127 | onkeydown={(e) => e.key === 'Enter' && searchFromPill(ex.label)} | 1128 | onkeydown={(e) => e.key === 'Enter' && searchFromPill(ex.label)} |
| 1128 | role="button" | 1129 | role="button" |
| 1129 | tabindex="0" | 1130 | tabindex="0" |
| ... | @@ -1165,7 +1166,7 @@ | ... | @@ -1165,7 +1166,7 @@ |
| 1165 | class="clf-chip" | 1166 | class="clf-chip" |
| 1166 | class:clf-chip-active={selectedClassifiers.includes(clf.id)} | 1167 | class:clf-chip-active={selectedClassifiers.includes(clf.id)} |
| 1167 | class:clf-chip-disabled={clf.disabled} | 1168 | class:clf-chip-disabled={clf.disabled} |
| 1168 | - onclick={() => { if (!clf.disabled) toggleClassifier(clf.id); }} | 1169 | + onclick={(e) => { e.stopPropagation(); if (!clf.disabled) toggleClassifier(clf.id); }} |
| 1169 | disabled={clf.disabled} | 1170 | disabled={clf.disabled} |
| 1170 | > | 1171 | > |
| 1171 | <span class="clf-dot"></span> | 1172 | <span class="clf-dot"></span> |
| ... | @@ -1176,11 +1177,11 @@ | ... | @@ -1176,11 +1177,11 @@ |
| 1176 | <div class="mode-card-pills"> | 1177 | <div class="mode-card-pills"> |
| 1177 | {#each EXAMPLES_CLASIFICADORES as ex} | 1178 | {#each EXAMPLES_CLASIFICADORES as ex} |
| 1178 | {#if ex.href} | 1179 | {#if ex.href} |
| 1179 | - <a href={ex.href} class="mode-pill">{ex.label}</a> | 1180 | + <a href={ex.href} class="mode-pill" onclick={(e) => e.stopPropagation()}>{ex.label}</a> |
| 1180 | {:else} | 1181 | {:else} |
| 1181 | <span | 1182 | <span |
| 1182 | class="mode-pill" | 1183 | class="mode-pill" |
| 1183 | - onclick={() => searchFromPill(ex.label, ex.classifier)} | 1184 | + onclick={(e) => { e.stopPropagation(); searchFromPill(ex.label, ex.classifier); }} |
| 1184 | onkeydown={(e) => e.key === 'Enter' && searchFromPill(ex.label, ex.classifier)} | 1185 | onkeydown={(e) => e.key === 'Enter' && searchFromPill(ex.label, ex.classifier)} |
| 1185 | role="button" | 1186 | role="button" |
| 1186 | tabindex="0" | 1187 | tabindex="0" |
| ... | @@ -2240,8 +2241,8 @@ | ... | @@ -2240,8 +2241,8 @@ |
| 2240 | .pills-hint{font-family:var(--sans);font-size:10px;color:#7B7870;font-weight:500} | 2241 | .pills-hint{font-family:var(--sans);font-size:10px;color:#7B7870;font-weight:500} |
| 2241 | .hint-desktop{display:inline} | 2242 | .hint-desktop{display:inline} |
| 2242 | .hint-mobile{display:none} | 2243 | .hint-mobile{display:none} |
| 2243 | - .mode-pill{font-family:var(--sans);font-size:11px;font-weight:500;padding:5px 10px;border-radius:8px;cursor:pointer;transition:all 0.2s;border:1px solid rgba(255,255,255,0.15);background:rgba(255,255,255,0.06);color:#F5F0E8} | 2244 | + .mode-pill{font-family:var(--sans);font-size:11px;font-weight:500;padding:5px 10px;border-radius:8px;cursor:pointer;transition:all 0.2s;border:1px solid rgba(255,255,255,0.15);background:rgba(255,255,255,0.06);color:#F5F0E8 !important;text-decoration:none} |
| 2244 | - .mode-pill:hover{background:rgba(255,255,255,0.12);border-color:rgba(255,255,255,0.25);color:#F5F0E8} | 2245 | + .mode-pill:hover{background:rgba(255,255,255,0.12);border-color:rgba(255,255,255,0.25);color:#FFFFFF !important} |
| 2245 | 2246 | ||
| 2246 | .mode-card-radio{position:absolute;top:16px;right:16px} | 2247 | .mode-card-radio{position:absolute;top:16px;right:16px} |
| 2247 | .radio-dot{width:18px;height:18px;border-radius:50%;border:2px solid rgba(255,255,255,0.2);display:block;transition:all 0.2s;position:relative} | 2248 | .radio-dot{width:18px;height:18px;border-radius:50%;border:2px solid rgba(255,255,255,0.2);display:block;transition:all 0.2s;position:relative} |
| ... | @@ -2635,8 +2636,8 @@ | ... | @@ -2635,8 +2636,8 @@ |
| 2635 | :global(html:not(.dark)) .radio-dot-active{border-color:#D4A017} | 2636 | :global(html:not(.dark)) .radio-dot-active{border-color:#D4A017} |
| 2636 | 2637 | ||
| 2637 | /* Mode pills */ | 2638 | /* Mode pills */ |
| 2638 | - :global(html:not(.dark)) .mode-pill{border-color:rgba(0,0,0,0.12);background:rgba(0,0,0,0.04);color:#555} | 2639 | + :global(html:not(.dark)) .mode-pill{border-color:rgba(0,0,0,0.12);background:rgba(0,0,0,0.04);color:#555 !important} |
| 2639 | - :global(html:not(.dark)) .mode-pill:hover{background:rgba(0,0,0,0.08);border-color:rgba(0,0,0,0.2);color:#1d1d1f} | 2640 | + :global(html:not(.dark)) .mode-pill:hover{background:rgba(0,0,0,0.08);border-color:rgba(0,0,0,0.2);color:#1d1d1f !important} |
| 2640 | :global(html:not(.dark)) .pills-hint{color:#999} | 2641 | :global(html:not(.dark)) .pills-hint{color:#999} |
| 2641 | 2642 | ||
| 2642 | /* Gear / settings */ | 2643 | /* Gear / settings */ | ... | ... |
| ... | @@ -1217,18 +1217,19 @@ | ... | @@ -1217,18 +1217,19 @@ |
| 1217 | .slice(0, 20); | 1217 | .slice(0, 20); |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | - function parseDescripciones(descripcionesStr) { | 1220 | + function parseDescripciones(descs) { |
| 1221 | - if (!descripcionesStr) return []; | 1221 | + if (!descs) return []; |
| 1222 | - try { | 1222 | + let arr; |
| 1223 | - const parsed = JSON.parse(descripcionesStr); | 1223 | + if (typeof descs === 'string') { |
| 1224 | - return parsed.sort((a, b) => { | 1224 | + try { arr = JSON.parse(descs); } catch { return []; } |
| 1225 | - const maxYearA = getMaxYear(a.rangos); | 1225 | + } else { |
| 1226 | - const maxYearB = getMaxYear(b.rangos); | 1226 | + arr = Array.isArray(descs) ? descs : []; |
| 1227 | + } | ||
| 1228 | + return [...arr].sort((a, b) => { | ||
| 1229 | + const maxYearA = getMaxYear(a.gestion || a.rangos); | ||
| 1230 | + const maxYearB = getMaxYear(b.gestion || b.rangos); | ||
| 1227 | return maxYearB - maxYearA; | 1231 | return maxYearB - maxYearA; |
| 1228 | }); | 1232 | }); |
| 1229 | - } catch { | ||
| 1230 | - return []; | ||
| 1231 | - } | ||
| 1232 | } | 1233 | } |
| 1233 | 1234 | ||
| 1234 | function getMaxYear(rangos) { | 1235 | function getMaxYear(rangos) { | ... | ... |
| ... | @@ -1364,19 +1364,19 @@ | ... | @@ -1364,19 +1364,19 @@ |
| 1364 | .slice(0, 20); | 1364 | .slice(0, 20); |
| 1365 | } | 1365 | } |
| 1366 | 1366 | ||
| 1367 | - function parseDescripciones(descripcionesStr) { | 1367 | + function parseDescripciones(descs) { |
| 1368 | - if (!descripcionesStr) return []; | 1368 | + if (!descs) return []; |
| 1369 | - try { | 1369 | + let arr; |
| 1370 | - const parsed = JSON.parse(descripcionesStr); | 1370 | + if (typeof descs === 'string') { |
| 1371 | - // Ordenar por año más reciente (extraer el máximo año de cada rango) | 1371 | + try { arr = JSON.parse(descs); } catch { return []; } |
| 1372 | - return parsed.sort((a, b) => { | 1372 | + } else { |
| 1373 | - const maxYearA = getMaxYear(a.rangos); | 1373 | + arr = Array.isArray(descs) ? descs : []; |
| 1374 | - const maxYearB = getMaxYear(b.rangos); | ||
| 1375 | - return maxYearB - maxYearA; // Descendente, más reciente primero | ||
| 1376 | - }); | ||
| 1377 | - } catch { | ||
| 1378 | - return []; | ||
| 1379 | } | 1374 | } |
| 1375 | + return [...arr].sort((a, b) => { | ||
| 1376 | + const maxYearA = getMaxYear(a.gestion || a.rangos); | ||
| 1377 | + const maxYearB = getMaxYear(b.gestion || b.rangos); | ||
| 1378 | + return maxYearB - maxYearA; | ||
| 1379 | + }); | ||
| 1380 | } | 1380 | } |
| 1381 | 1381 | ||
| 1382 | function getMaxYear(rangos) { | 1382 | function getMaxYear(rangos) { | ... | ... |
| ... | @@ -881,18 +881,19 @@ | ... | @@ -881,18 +881,19 @@ |
| 881 | .slice(0, 20); | 881 | .slice(0, 20); |
| 882 | } | 882 | } |
| 883 | 883 | ||
| 884 | - function parseDescripciones(descripcionesStr) { | 884 | + function parseDescripciones(descs) { |
| 885 | - if (!descripcionesStr) return []; | 885 | + if (!descs) return []; |
| 886 | - try { | 886 | + let arr; |
| 887 | - const parsed = typeof descripcionesStr === 'string' ? JSON.parse(descripcionesStr) : descripcionesStr; | 887 | + if (typeof descs === 'string') { |
| 888 | - return parsed.sort((a, b) => { | 888 | + try { arr = JSON.parse(descs); } catch { return []; } |
| 889 | - const maxYearA = getMaxYear(a.rangos); | 889 | + } else { |
| 890 | - const maxYearB = getMaxYear(b.rangos); | 890 | + arr = Array.isArray(descs) ? descs : []; |
| 891 | + } | ||
| 892 | + return [...arr].sort((a, b) => { | ||
| 893 | + const maxYearA = getMaxYear(a.gestion || a.rangos); | ||
| 894 | + const maxYearB = getMaxYear(b.gestion || b.rangos); | ||
| 891 | return maxYearB - maxYearA; | 895 | return maxYearB - maxYearA; |
| 892 | }); | 896 | }); |
| 893 | - } catch { | ||
| 894 | - return []; | ||
| 895 | - } | ||
| 896 | } | 897 | } |
| 897 | 898 | ||
| 898 | function getMaxYear(rangos) { | 899 | function getMaxYear(rangos) { | ... | ... |
| ... | @@ -722,6 +722,7 @@ | ... | @@ -722,6 +722,7 @@ |
| 722 | }); | 722 | }); |
| 723 | 723 | ||
| 724 | onMount(async () => { | 724 | onMount(async () => { |
| 725 | + console.log('[SECTORES] onMount started'); | ||
| 725 | isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0; | 726 | isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0; |
| 726 | 727 | ||
| 727 | requestAnimationFrame(() => { | 728 | requestAnimationFrame(() => { |
| ... | @@ -735,10 +736,10 @@ | ... | @@ -735,10 +736,10 @@ |
| 735 | const data = await res.json(); | 736 | const data = await res.json(); |
| 736 | 737 | ||
| 737 | if (Array.isArray(data)) { | 738 | if (Array.isArray(data)) { |
| 738 | - allItems = data; | 739 | + allItems = data.filter(item => String(item.acteco) !== '0' && !String(item.acteco).startsWith('0.') && !/desconocido/i.test(item.desc_acteco || '')); |
| 739 | 740 | ||
| 740 | // Sectores = items de profundidad 1 | 741 | // Sectores = items de profundidad 1 |
| 741 | - sectores = data | 742 | + sectores = allItems |
| 742 | .filter(item => getDepth(item.acteco) === 1) | 743 | .filter(item => getDepth(item.acteco) === 1) |
| 743 | .sort((a, b) => String(a.acteco).localeCompare(String(b.acteco), undefined, { numeric: true })); | 744 | .sort((a, b) => String(a.acteco).localeCompare(String(b.acteco), undefined, { numeric: true })); |
| 744 | 745 | ||
| ... | @@ -766,6 +767,7 @@ | ... | @@ -766,6 +767,7 @@ |
| 766 | selectedYear = 2025; | 767 | selectedYear = 2025; |
| 767 | } | 768 | } |
| 768 | 769 | ||
| 770 | + console.log('[SECTORES] loading done, sectores:', sectores.length, 'allItems:', allItems.length, 'selectedYear:', selectedYear, 'layoutMounted:', layoutMounted, 'viewMode:', viewMode); | ||
| 769 | loading = false; | 771 | loading = false; |
| 770 | }); | 772 | }); |
| 771 | 773 | ||
| ... | @@ -1223,18 +1225,19 @@ | ... | @@ -1223,18 +1225,19 @@ |
| 1223 | .slice(0, 20); | 1225 | .slice(0, 20); |
| 1224 | } | 1226 | } |
| 1225 | 1227 | ||
| 1226 | - function parseDescripciones(descripcionesStr) { | 1228 | + function parseDescripciones(descs) { |
| 1227 | - if (!descripcionesStr) return []; | 1229 | + if (!descs) return []; |
| 1228 | - try { | 1230 | + let arr; |
| 1229 | - const parsed = JSON.parse(descripcionesStr); | 1231 | + if (typeof descs === 'string') { |
| 1230 | - return parsed.sort((a, b) => { | 1232 | + try { arr = JSON.parse(descs); } catch { return []; } |
| 1231 | - const maxYearA = getMaxYear(a.rangos); | 1233 | + } else { |
| 1232 | - const maxYearB = getMaxYear(b.rangos); | 1234 | + arr = Array.isArray(descs) ? descs : []; |
| 1235 | + } | ||
| 1236 | + return [...arr].sort((a, b) => { | ||
| 1237 | + const maxYearA = getMaxYear(a.gestion || a.rangos); | ||
| 1238 | + const maxYearB = getMaxYear(b.gestion || b.rangos); | ||
| 1233 | return maxYearB - maxYearA; | 1239 | return maxYearB - maxYearA; |
| 1234 | }); | 1240 | }); |
| 1235 | - } catch { | ||
| 1236 | - return []; | ||
| 1237 | - } | ||
| 1238 | } | 1241 | } |
| 1239 | 1242 | ||
| 1240 | function getMaxYear(rangos) { | 1243 | function getMaxYear(rangos) { | ... | ... |
This diff is collapsed. Click to expand it.
| 1 | <script> | 1 | <script> |
| 2 | import { onMount, tick } from 'svelte'; | 2 | import { onMount, tick } from 'svelte'; |
| 3 | + import { goto } from '$app/navigation'; | ||
| 3 | import { page } from '$app/stores'; | 4 | import { page } from '$app/stores'; |
| 4 | import * as d3 from 'd3'; | 5 | import * as d3 from 'd3'; |
| 5 | 6 | ||
| ... | @@ -142,7 +143,7 @@ | ... | @@ -142,7 +143,7 @@ |
| 142 | } | 143 | } |
| 143 | 144 | ||
| 144 | function navigateToEntity(item) { | 145 | function navigateToEntity(item) { |
| 145 | - window.location.href = `/entidad/${item.codigo}`; | 146 | + goto(`/entidad/${item.codigo}`); |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 148 | function onSearchKeydown(e) { | 149 | function onSearchKeydown(e) { | ... | ... |
| 1 | +export const ssr = false; | ||
| 2 | + | ||
| 1 | import { error } from '@sveltejs/kit'; | 3 | import { error } from '@sveltejs/kit'; |
| 2 | 4 | ||
| 3 | import { API_HOST } from '$lib/api.js'; | 5 | import { API_HOST } from '$lib/api.js'; |
| ... | @@ -17,7 +19,7 @@ export async function load({ params }) { | ... | @@ -17,7 +19,7 @@ export async function load({ params }) { |
| 17 | const clasRes = await fetch(`${API_BASE}/clasificador`); | 19 | const clasRes = await fetch(`${API_BASE}/clasificador`); |
| 18 | if (clasRes.ok) { | 20 | if (clasRes.ok) { |
| 19 | const clasificador = await clasRes.json(); | 21 | const clasificador = await clasRes.json(); |
| 20 | - const current = clasificador.find(c => c.organismo === parseInt(codigo)); | 22 | + const current = clasificador.find(c => String(c.organismo) === codigo); |
| 21 | if (current) { | 23 | if (current) { |
| 22 | // Padres: grupo y subgrupo (como objetos virtuales para navegación) | 24 | // Padres: grupo y subgrupo (como objetos virtuales para navegación) |
| 23 | padres = [ | 25 | padres = [ | ... | ... |
| ... | @@ -19,10 +19,9 @@ | ... | @@ -19,10 +19,9 @@ |
| 19 | </p> | 19 | </p> |
| 20 | 20 | ||
| 21 | <p class="p3"> | 21 | <p class="p3"> |
| 22 | - La plataforma reúne más de veinte años de información sobre ingresos y gastos | 22 | + La plataforma reúne 10 años de información sobre ingresos y gastos |
| 23 | públicos, organizada mediante los clasificadores presupuestarios oficiales y a | 23 | públicos, organizada mediante los clasificadores presupuestarios oficiales y a |
| 24 | - través de los programas y proyectos de inversión pública. Los datos se actualizan | 24 | + través de los programas y proyectos de inversión pública. |
| 25 | - semanalmente y abarcan a todas las entidades del sector público. | ||
| 26 | </p> | 25 | </p> |
| 27 | 26 | ||
| 28 | <p class="p3"> | 27 | <p class="p3"> | ... | ... |
| 1 | <script> | 1 | <script> |
| 2 | import { onMount, tick } from 'svelte'; | 2 | import { onMount, tick } from 'svelte'; |
| 3 | + import { goto } from '$app/navigation'; | ||
| 3 | import { page } from '$app/stores'; | 4 | import { page } from '$app/stores'; |
| 4 | import { get } from 'svelte/store'; | 5 | import { get } from 'svelte/store'; |
| 5 | import * as d3 from 'd3'; | 6 | import * as d3 from 'd3'; |
| ... | @@ -224,7 +225,7 @@ | ... | @@ -224,7 +225,7 @@ |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | function navigateToEntity(item) { | 227 | function navigateToEntity(item) { |
| 227 | - window.location.href = `/ubicacion/${item.codigo}`; | 228 | + goto(`/ubicacion/${item.codigo}`); |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 230 | function onSearchKeydown(e) { | 231 | function onSearchKeydown(e) { | ... | ... |
static/des.html
0 → 100644
This diff is collapsed. Click to expand it.
No preview for this file type
static/ejecucion_entidades@1.parquet
deleted
100644 → 0
No preview for this file type
static/timeline@1.parquet
deleted
100644 → 0
No preview for this file type
static/timeserie@4.parquet
deleted
100644 → 0
No preview for this file type
| 1 | -import adapter from '@sveltejs/adapter-auto'; | 1 | +import adapter from '@sveltejs/adapter-node'; |
| 2 | 2 | ||
| 3 | /** @type {import('@sveltejs/kit').Config} */ | 3 | /** @type {import('@sveltejs/kit').Config} */ |
| 4 | const config = { | 4 | const config = { |
| 5 | kit: { | 5 | kit: { |
| 6 | - // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. | ||
| 7 | - // If your environment is not supported, or you settled on a specific environment, switch out the adapter. | ||
| 8 | - // See https://svelte.dev/docs/kit/adapters for more information about adapters. | ||
| 9 | adapter: adapter() | 6 | adapter: adapter() |
| 10 | } | 7 | } |
| 11 | }; | 8 | }; | ... | ... |
| ... | @@ -377,7 +377,7 @@ Sector → Subsector → Área → Subárea → Entidad | ... | @@ -377,7 +377,7 @@ Sector → Subsector → Área → Subárea → Entidad |
| 377 | 377 | ||
| 378 | --- | 378 | --- |
| 379 | 379 | ||
| 380 | -## Tablas de Vista de Entidad | 380 | +## Tablas de Vista de Entidad" |
| 381 | 381 | ||
| 382 | ### 13. `entidad_resumen` - Resumen histórico por entidad/DA | 382 | ### 13. `entidad_resumen` - Resumen histórico por entidad/DA |
| 383 | 383 | ... | ... |
-
Please register or login to post a comment