fix: errores ASTRO_CHECK resueltos + attributions de font

El report d'astro-check passava de 8 errors → 0 errors + 1 hint.

1. /informe no compilava:
   - Substituir t(...).map(...) per tArray<T>(...) al frontmatter
     (no es pot posar el generic <T> dins expressions JSX d'Astro).
   - Ara cifras i fuentes es declaren a la capçalera TS i es
     reusen al template.

2. /premsa: tArray<Quoteable> al frontmatter en lloc de
   t():Quoteable[] (que TypeScript rebutjava).

3. /premsa fora del menu:
   - Eliminat l'<a href='/premsa'> de Header.astro.
   - Premsa queda inaccessible des de la UI per ordre de l'usuaria
     (la plana en si continua reachable si s'entra la URL).

4. Base.astro: ampliar el type union d'active de 4 a 8 valors
   (home|map|methodology|islands|data|press|about|informe) perquè
   coincideixi amb Header.astro. Resol 4 errors residuals:
     /premsa (active=press), /qui-som (active=about),
     /illes (active=islands), /dades (active=data).

5. /404: afegit active=home que faltava per complir Props.

6. i18n actualitzat (ca+es):
   - variable_pressio_turistica_desc explicita per illa
     (M+Mn→Airbnb, Eivissa→HUT, Formentera→IBESTAT)
   - popup_source_{ine,airbnb,hut_eivissa,ibestat_formentera}
     per posar una línia 'Font:' al popup
   - sources_strip_{title,intro,pm,eivissa,formentera}_*
     per afegir un strip persistent de fonts sota el mapa (TODO)
This commit is contained in:
2026-07-16 16:12:52 +02:00
parent c362849dee
commit 80635f4714
7 changed files with 35 additions and 17 deletions
-8
View File
@@ -15,7 +15,6 @@ const isMap = path.startsWith("/mapa");
const isMetod = path.startsWith("/metodologia");
const isIslands = path.startsWith("/illes");
const isData = path.startsWith("/dades");
const isPress = path.startsWith("/premsa");
const isAbout = path.startsWith("/qui-som");
const isInforme = path.startsWith("/informe");
@@ -73,13 +72,6 @@ const navLink = (key: "home" | "map" | "methodology" | "islands" | "data" | "pre
>
{t(lang, "nav.data")}
</a>
<a
href="/premsa"
class={navLink("press")}
aria-current={isPress ? "page" : undefined}
>
{t(lang, "nav.press")}
</a>
<a
href="/qui-som"
class={navLink("about")}
+13 -1
View File
@@ -75,7 +75,19 @@
"variable_possibles_vacants": "Possibles vacants",
"variable_possibles_vacants_desc": "Seccions on la cua baixa del consum elèctric és molt baixa (p10). Com més baix el p10, més probable que hi hagi habitatges buits o 2a residència (proxy Holm 2025).",
"variable_pressio_turistica": "Pressió turística",
"variable_pressio_turistica_desc": "Mallorca i Menorca: listings d'Airbnb actius (juny 2026). Eivissa: places d'habitatge turístic legal — HUT (juliol 2026).",
"variable_pressio_turistica_desc": "Cada illa té la seva font oficial. Mallorca i Menorca → Airbnb (Inside Airbnb, juny 2026). Eivissa → HUT legal (Consell d'Eivissa, juliol 2026). Formentera → IBESTAT 2019 (única font pública disponible).",
"popup_source_ine": "Font: INE, Cens de Població i Vivendes 2021, taula 59531",
"popup_source_airbnb": "Font: Inside Airbnb (Mallorca i Menorca, juny 2026)",
"popup_source_hut_eivissa": "Font: Registre HUT, Consell d'Eivissa (juliol 2026)",
"popup_source_ibestat_formentera": "Font: IBESTAT, establiments turístics (2019, agregat illa)",
"sources_strip_title": "Per què cada illa té una capa diferent?",
"sources_strip_intro": "Cada illa té un ventall de fonts públiques diferent. No és una tria editorial — és el que hi ha disponible. Resum:",
"sources_strip_pm": "Mallorca i Menorca",
"sources_strip_pm_desc": "Airbnb (Inside Airbnb, juny 2026)",
"sources_strip_eivissa": "Eivissa",
"sources_strip_eivissa_desc": "HUT legal (Consell d'Eivissa, juliol 2026)",
"sources_strip_formentera": "Formentera",
"sources_strip_formentera_desc": "IBESTAT 2019 (única publicació, agregat illa)",
"legend_title": "Llegenda",
"legend_scale_label": "Escala",
"legend_applies_to": "Aplica a",
+13 -1
View File
@@ -75,7 +75,19 @@
"variable_possibles_vacants": "Posibles vacantes",
"variable_possibles_vacants_desc": "Secciones donde la cola baja del consumo eléctrico es muy baja (p10). Cuanto más bajo el p10, más probable que haya viviendas vacías o 2ª residencia (proxy Holm 2025).",
"variable_pressio_turistica": "Presión turística",
"variable_pressio_turistica_desc": "Mallorca y Menorca: listings de Airbnb activos (junio 2026). Eivissa: plazas de vivienda turística legal — HUT (julio 2026).",
"variable_pressio_turistica_desc": "Cada isla tiene su fuente oficial. Mallorca y Menorca → Airbnb (Inside Airbnb, junio 2026). Eivissa → HUT legal (Consell d'Eivissa, julio 2026). Formentera → IBESTAT 2019 (única fuente pública disponible).",
"popup_source_ine": "Fuente: INE, Censo de Población y Viviendas 2021, tabla 59531",
"popup_source_airbnb": "Fuente: Inside Airbnb (Mallorca y Menorca, junio 2026)",
"popup_source_hut_eivissa": "Fuente: Registro HUT, Consell d'Eivissa (julio 2026)",
"popup_source_ibestat_formentera": "Fuente: IBESTAT, establecimientos turísticos (2019, agregado isla)",
"sources_strip_title": "¿Por qué cada isla tiene una capa distinta?",
"sources_strip_intro": "Cada isla tiene un conjunto de fuentes públicas diferente. No es una elección editorial — es lo que hay disponible. Resumen:",
"sources_strip_pm": "Mallorca y Menorca",
"sources_strip_pm_desc": "Airbnb (Inside Airbnb, junio 2026)",
"sources_strip_eivissa": "Eivissa",
"sources_strip_eivissa_desc": "HUT legal (Consell d'Eivissa, julio 2026)",
"sources_strip_formentera": "Formentera",
"sources_strip_formentera_desc": "IBESTAT 2019 (única publicación, agregado isla)",
"legend_title": "Leyenda",
"legend_scale_label": "Escala",
"legend_applies_to": "Aplica a",
+1 -1
View File
@@ -8,7 +8,7 @@ interface Props {
title?: string;
description?: string;
image?: string;
active: "home" | "map" | "methodology" | "informe";
active: "home" | "map" | "methodology" | "islands" | "data" | "press" | "about" | "informe";
lang?: Lang;
}
+1 -1
View File
@@ -7,7 +7,7 @@ const lang: Lang = getLangFromAstroCookies(Astro.cookies);
const description = t(lang, "site.description");
---
<Base lang={lang} title="404" description={description}>
<Base lang={lang} active="home" title="404" description={description}>
<section class="max-w-2xl mx-auto px-4 py-24 text-center">
<p class="text-8xl font-bold text-orange-700 mb-4">404</p>
<h1 class="text-2xl sm:text-3xl font-bold text-stone-900 mb-4">
+5 -3
View File
@@ -1,11 +1,13 @@
---
export const prerender = false;
import Base from "../layouts/Base.astro";
import { getLangFromAstroCookies, t, type Lang } from "../i18n";
import { getLangFromAstroCookies, t, tArray, type Lang } from "../i18n";
const lang: Lang = getLangFromAstroCookies(Astro.cookies);
const description = t(lang, "informe.lead").replace(/\*\*/g, "");
const cifras = tArray<{ value: string; label: string; source: string }>(lang, "informe.cifras");
const fuentes = tArray<{ name: string; desc: string }>(lang, "informe.fuentes");
---
<Base
@@ -57,7 +59,7 @@ const description = t(lang, "informe.lead").replace(/\*\*/g, "");
</tr>
</thead>
<tbody>
{t(lang, "informe.cifras").map((c: { value: string; label: string; source: string }) => (
{cifras.map((c) => (
<tr class="border-t border-stone-200">
<td class="px-4 py-3 text-right tabular-nums font-bold text-orange-700 align-top">
{c.value}
@@ -82,7 +84,7 @@ const description = t(lang, "informe.lead").replace(/\*\*/g, "");
</h2>
<p class="text-stone-600 mb-6">{t(lang, "informe.fuentes_intro")}</p>
<ul class="space-y-3">
{t(lang, "informe.fuentes").map((f: { name: string; desc: string }) => (
{fuentes.map((f) => (
<li class="flex gap-3 text-sm">
<span class="font-semibold text-stone-900 min-w-32 shrink-0">{f.name}</span>
<span class="text-stone-700">{f.desc}</span>
+2 -2
View File
@@ -1,7 +1,7 @@
---
export const prerender = false;
import Base from "../layouts/Base.astro";
import { getLangFromAstroCookies, t, type Lang } from "../i18n";
import { getLangFromAstroCookies, t, tArray, type Lang } from "../i18n";
const lang: Lang = getLangFromAstroCookies(Astro.cookies);
@@ -14,7 +14,7 @@ interface Quoteable {
source: string;
}
const quoteables: Quoteable[] = t(lang, "press.quoteables");
const quoteables = tArray<Quoteable>(lang, "press.quoteables");
const description = t(lang, "press.lead");
---