Skip to content

feat(speakers): add Mia + multi-locale data + TS/lucide dep fixes (v1.12.0)#207

Merged
francescarpi merged 10 commits into
mainfrom
feat/mia
Jun 25, 2026
Merged

feat(speakers): add Mia + multi-locale data + TS/lucide dep fixes (v1.12.0)#207
francescarpi merged 10 commits into
mainfrom
feat/mia

Conversation

@francescarpi

@francescarpi francescarpi commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Resumen

PR hacia v1.12.0. Tres features de producto + un pase de dependencias que cerró issues de tipado.

1. Refactor de data: speakers y jobs multiidioma sin carpetas

Reemplaza la estructura data/speakers/{ca,es,en}/ y data/jobs/{ca,es,en}/ (que duplicaba el frontmatter 3× por archivo) por un único .md por entrada con los campos multiidioma como objetos anidados:

  • description: { ca, es, en } en speakers
  • description: { ca, es, en } y location: { ca, es, en } en jobs

Beneficio: agregar un link, un cambio de salary, etc. se hace 1 vez, no 3. Bug latente arreglado: fever-senior-dev no tenía versión ca (caía al fallback en ES) y la description de ES estaba en inglés. Ambos traducidos.

Bonus: IJob extraído a src/types/jobs.ts (estaba inline en el componente). TLocale centralizado en src/types/locale.ts.

2. feat: añadir a Mia Bajić como segunda ponente plenaria

src/data/speakers/mia.md con 8 enlaces sociales y descripción traducida a los 3 idiomas. Esto obligó a ampliar el sistema de iconos sociales para soportar 4 tipos nuevos (youtube, spotify, applepodcasts, rss). De paso se arregló un mismatch silencioso: TSpeakerLinkType y SocialIconName declaraban 4-6 tipos pero diego.md ya usaba bluesky y twitter (funcionaba por duck-typing de Astro, sin aria-label). Ahora soportan los 10.

3. UI: grid 4 columnas para los iconos sociales

Con 8 íconos en flex, quedaban muy pegados. Cambio mínimo en SpeakerCard.astro: el <ul> pasa de flex a grid grid-cols-4. Diego (5 íconos) y futuros speakers también se ven en grid, manteniendo consistencia visual.

4. Dependencias y tipos (3 commits posteriores)

  • fix(types): re-export TLocale from types/jobs — la CI marcaba un error de tipado en el import de JobsPage.astro que no se había detectado en local.
  • chore(deps): revert @lucide/astro to ^0.577.0 — la rama probaba un upgrade a 1.x que removió los iconos de marca (Github, Twitter, Linkedin, Instagram, Youtube). Forzar a emoji era regresión visual, así que se pineó a 0.577.x.
  • fix(types): adapt to typescript 6.0 stricter checks — el upgrade de TS 5.9 → 6.0 + fontsource introdujo 15 errors nuevos en astro check (keys dinámicas en SectionCTAs, side-effect CSS imports, i18n ahora possibly undefined, StatusIcon index access). Todos adaptados con casts/non-null assertions/declaration file. Cero cambios de comportamiento.

Cambios

  • 18 archivos borrados (3 speakers + 15 jobs viejos) + 6 carpetas vacías eliminadas
  • 10 archivos nuevos (1 speaker, 5 jobs, 1 type, 1 photo, 1 locale, 1 fontsource.d.ts)
  • 13 archivos modificados (3 componentes, 2 pages, 2 layouts, 1 i18n, 2 icons, 3 types, package.json, pnpm-lock.yaml)
  • Total: 41 files changed, +883/-873

Commits

144f3f0 fix(types): adapt to typescript 6.0 stricter checks
7b0b352 chore(deps): revert @lucide/astro to ^0.577.0
9080d1e fix(types): re-export TLocale from types/jobs
5ce3a13 chore: version 1.12.0
646dcbd feat(speakers): add Mia and support 6 new social platforms
2b556e5 refactor(data): consolidate speakers and jobs markdown per locale

Para verificar

  • pnpm dev y navegar /es, /en, /ca
  • Home → sección speakers: Diego (5 íconos) y Mia (8 íconos en grid 4×2)
  • /jobs → 3 ofertas de Rover visibles (Fever y JetBrains con draft: true)
  • DevTools → a11y: cada link tiene aria-label propio

Capturas

image

Notas

  • El componente SectionCTAs.astro (CTAs 🔍 revisores y 🤝 sponsors en la home) renderiza con textos vacíos porque las keys cta.reviewers.* y cta.sponsors.* nunca se agregaron a home.ts. Bug pre-existente, fuera de scope de este PR. Lo dejé documentado en el commit de TS fixes.
  • Build local: pnpm build ✅ 25 páginas. pnpm astro check ✅ 0 errors. pnpm format ✅ sin cambios.

Checklist

  • pnpm format sin cambios
  • pnpm astro check 0 errors
  • pnpm build OK (25 páginas)
  • TypeScript: TSpeakerLinkType ahora honesto con lo que se usa
  • Verificación visual pendiente

Replace per-locale folders (ca/, es/, en/) with a single markdown
file per entry holding translations inline. Only the description
(and location, for jobs) were actually multi-locale; everything
else (name, company, links, salary, skills, tier, etc.) was
duplicated noise and a desync hazard.

- src/data/speakers/diego.md: single file with descriptions: { ca, es, en }
- src/data/jobs/*.md: 5 consolidated files with location and
  description as Record<TLocale, string>
- src/data/{speakers,jobs}/{ca,es,en}/: removed (18 .md + 6 dirs)
- src/types/locale.ts: shared TLocale type
- src/types/jobs.ts: new IJob + TJobTier, extracted from inline
  JobFrontmatter in JobsPage.astro
- src/types/speakers.ts: ISpeaker.descriptions replaces description
- SectionSpeakers.astro, SpeakerCard.astro, JobsPage.astro:
  single import.meta.glob per data dir, removed allSpeakersMap
  and allJobsMap, fields resolved by lang at render time

Template _plantilla-oferta.md is preserved and excluded from the
jobs glob via the !(_*).md pattern.

Bonus: fever-senior-dev/es description was left in English
(masked by draft:true), translated to Spanish. Missing ca
translation for fever-senior-dev added.
Add mia.md as the second plenary speaker with 8 social links.
Extend the icon system to support the new link types she uses:
youtube, spotify, applepodcasts, rss. Also fix the silent
mismatch in TSpeakerLinkType and SocialIconName that already
omitted bluesky and twitter (used in diego.md and rendered
through duck-typing without an aria-label fallback).

- src/types/speakers.ts: TSpeakerLinkType grows from 4 to 10
- src/lib/icons/types.ts: SocialIconName grows to match
- src/lib/icons/mappings/social.ts: 4 new mappings
  - youtube -> Youtube + play emoji fallback
  - spotify -> Headphones (no Lucide native) + headphones emoji
  - applepodcasts -> Podcast (no Lucide native) + mic emoji
  - rss -> Rss + antenna emoji
- src/i18n/home.ts: 6 new aria_* keys per language (es, en, ca)
- src/components/home/SpeakerCard.astro: ariaForLink switch
  cast extended
- src/components/home/SpeakerCard.astro: social <ul> switched
  from flex to grid grid-cols-4 so multi-link cards don't crowd
- src/data/speakers/mia.md: new, with descriptions in es/en/ca
  (en original, es/ca translated). 'web' link type renamed to
  'website' to match the existing icon mapping
@francescarpi francescarpi self-assigned this Jun 24, 2026
@francescarpi francescarpi requested a review from itziarZG June 24, 2026 18:39
@francescarpi francescarpi changed the title feat(speakers): add Mia + 6 new social platforms + data refactor (v1.12.0) Add Mia + 6 new social platforms + data refactor (v1.12.0) Jun 24, 2026
astro check failed in CI with ts(2459): Module '../types/jobs'
declares 'TLocale' locally, but it is not exported. JobsPage.astro
imports TLocale from there for the locale resolution. Fix with a
re-export so the type is reachable through the public API of
types/jobs.ts.
@lucide/astro 1.x removed brand icons (Github, Twitter, Linkedin,
Instagram, Youtube). Forcing the project to render those via the
emoji fallback path is a visual regression we don't want, so we
pin to the previous 0.577.x line that still ships them.
The typescript bump from 5.9 to 6.0 made several previously-silent
patterns fail astro check. 15 errors, none caused by the Mia refactor,
all from the strictness increase of TS 6.0 plus the way some side-
effect CSS imports and dynamic i18n keys are typed.

- src/components/home/SectionCTAs.astro: cast 't' to Record<string,
  string> so dynamic keys (cta.reviewers.*, cta.sponsors.*) that
  aren't yet in src/i18n/home.ts don't error. The empty strings
  they currently resolve to are a pre-existing content gap, out
  of scope for this commit.
- src/types/fontsource.d.ts: new ambient module declaration for
  @fontsource-variable/* CSS side-effect imports, so Layout.astro
  keeps importing them without TS 6.0 complaining about missing
  types.
- src/components/icons/StatusIcon.astro: cast the index access
  on statusLabels with 'as keyof typeof statusLabels' since
  AvailableIconName is broader than the labels object.
- src/layouts/components/Header/components/LanguagePicker.astro
  and src/pages/index.astro: non-null assertion on 'i18n' from
  astro:config/client (TS 6.0 narrows it to possibly undefined).
@francescarpi francescarpi changed the title Add Mia + 6 new social platforms + data refactor (v1.12.0) feat(speakers): add Mia + multi-locale data + TS/lucide dep fixes (v1.12.0) Jun 24, 2026
Lucide is deprecating brand icons (Github, Twitter, Linkedin, Instagram)
in upcoming versions. Migrated all 11 SocialIconName mappings to inline
SVGs loaded via import.meta.glob with ?raw query, preserving currentColor
inheritance and keeping the <SocialIcon platform="..." /> API intact.

- Added src/lib/icons/assets/ with 11 normalized SVGs
- Added registry index.ts with extractInner helper for set:html rendering
- Extended IconMappingWithFallback with optional svg?: string field
- Unified website handling in SpeakerCard (removed Globe from lucide)
- Icon.astro now renders raw SVGs inline when mapping.svg is present
First of two upgrade steps (5→6, then 6→7). The codebase was audited
for HTML validity and whitespace dependencies before this bump:
no <div> inside <p>, no <a> inside <a>, no adjacent inline elements
without explicit space.

Astro 6 brings Vite 7, Zod 4, Shiki 4 and Node 22+ requirement.
This project already runs on Node 24 (.nvmrc) and doesn't use content
collections, Shiki APIs, or server adapters, so the impact is minimal.

Verified: astro check passes 0/0/0 (was 0/0/2 hints in v5), dev server
returns 200 on /es/ with social icons, view transitions and i18n
hreflang tags all rendering correctly.
Astro 7 brings Vite 8 and the new Rust-based compiler as default.
The Rust compiler is stricter about invalid HTML, so a pre-flight
audit was done on the codebase: 0 occurrences of <div> inside <p>,
0 <a> inside <a>, 0 <button> inside <button>. Result: Rust compiler
accepts all 10 pages (3 locales + 7 sections) without errors.

compressHTML: true is set explicitly in astro.config.mjs to keep
the v6 whitespace behavior (the v7 default of 'jsx' strips spaces
between inline elements, which would be a visual change for any
adjacent inline markup added in the future).

Peer warning from @lucide/astro 1.21.0 (peer: ^4 || ^5 || ^6) is
expected and non-blocking: the package works at runtime, the maintainer
just hasn't bumped the peer range to include ^7 yet. Will resolve
itself when @lucide/astro publishes a new version.

Verified: astro check 0/0/0, all 10 pages return 200, social icons
with currentColor render correctly, ClientRouter + hreflang + i18n
all working.
@francescarpi francescarpi merged commit 829ae6b into main Jun 25, 2026
1 check passed
@francescarpi francescarpi deleted the feat/mia branch June 25, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant