From aea7b753b01c40b38a267247e3c0e428569c537c Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Sun, 10 May 2026 09:36:06 +0200 Subject: [PATCH 01/10] feat: add teams page with accessible card grid Adds /teams route for all locales (es, en, ca) listing all organization teams with name, description and contact email. Includes nav menu links and WCAG-compliant markup (role="list", focus-visible, aria-label with team context, aria-labelledby on sections). Co-Authored-By: Claude Sonnet 4.6 --- src/components/TeamsPage.astro | 87 ++++++++++++++++++++++++++++++++++ src/data/teams/catering.md | 5 ++ src/data/teams/diversity.md | 5 ++ src/data/teams/merch.md | 5 ++ src/data/teams/program.md | 5 ++ src/data/teams/rrss.md | 5 ++ src/data/teams/social.md | 5 ++ src/data/teams/sponsors.md | 5 ++ src/data/teams/ticketing.md | 5 ++ src/data/teams/venue.md | 5 ++ src/data/teams/volunteers.md | 5 ++ src/data/teams/web.md | 5 ++ src/i18n/menu/ca.ts | 4 ++ src/i18n/menu/en.ts | 4 ++ src/i18n/menu/es.ts | 4 ++ src/i18n/teams/ca.ts | 5 ++ src/i18n/teams/en.ts | 5 ++ src/i18n/teams/es.ts | 5 ++ src/i18n/teams/index.ts | 9 ++++ src/pages/[lang]/teams.astro | 26 ++++++++++ 20 files changed, 204 insertions(+) create mode 100644 src/components/TeamsPage.astro create mode 100644 src/data/teams/catering.md create mode 100644 src/data/teams/diversity.md create mode 100644 src/data/teams/merch.md create mode 100644 src/data/teams/program.md create mode 100644 src/data/teams/rrss.md create mode 100644 src/data/teams/social.md create mode 100644 src/data/teams/sponsors.md create mode 100644 src/data/teams/ticketing.md create mode 100644 src/data/teams/venue.md create mode 100644 src/data/teams/volunteers.md create mode 100644 src/data/teams/web.md create mode 100644 src/i18n/teams/ca.ts create mode 100644 src/i18n/teams/en.ts create mode 100644 src/i18n/teams/es.ts create mode 100644 src/i18n/teams/index.ts create mode 100644 src/pages/[lang]/teams.astro diff --git a/src/components/TeamsPage.astro b/src/components/TeamsPage.astro new file mode 100644 index 0000000..41d6bee --- /dev/null +++ b/src/components/TeamsPage.astro @@ -0,0 +1,87 @@ +--- +import { teamsTexts } from '../i18n/teams' + +interface Props { + lang: string +} + +const { lang } = Astro.props +const t = teamsTexts[(lang || 'es') as keyof typeof teamsTexts] + +const teams = ( + Object.values(import.meta.glob('../data/teams/*.md', { eager: true })) as { + frontmatter: { name: string; description: string; contact: string } + }[] +).sort((a, b) => a.frontmatter.name.localeCompare(b.frontmatter.name)) +--- + +
+
+

+ {t.hero} +

+
+ +
+

{t.hero}

+ +
+
+ + diff --git a/src/data/teams/catering.md b/src/data/teams/catering.md new file mode 100644 index 0000000..76cd2e6 --- /dev/null +++ b/src/data/teams/catering.md @@ -0,0 +1,5 @@ +--- +name: 'Catering' +description: 'Aseguramos que nadie pase hambre en la PyConES2026, para que los asistentes puedan recargar energía entre charla y charla.' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/data/teams/diversity.md b/src/data/teams/diversity.md new file mode 100644 index 0000000..28849bc --- /dev/null +++ b/src/data/teams/diversity.md @@ -0,0 +1,5 @@ +--- +name: 'Diversidad y becas' +description: 'Hacemos que el evento sea accesible para toda la comunidad, para que nadie se quede fuera por razones económicas o de representación.' +contact: 'diversidadybecas@2026.es.pycon.org' +--- diff --git a/src/data/teams/merch.md b/src/data/teams/merch.md new file mode 100644 index 0000000..c8d0c2c --- /dev/null +++ b/src/data/teams/merch.md @@ -0,0 +1,5 @@ +--- +name: 'Merch' +description: 'Diseñamos el merchandising oficial de la PyConES 2026 para que el evento se quede contigo mucho después de que termine' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/data/teams/program.md b/src/data/teams/program.md new file mode 100644 index 0000000..d39cd69 --- /dev/null +++ b/src/data/teams/program.md @@ -0,0 +1,5 @@ +--- +name: 'Programa' +description: 'Nos encargamos de seleccionar charlas, keynotes y otras sesiones, además de la confección del horario' +contact: 'charlas@2026.es.pycon.org' +--- diff --git a/src/data/teams/rrss.md b/src/data/teams/rrss.md new file mode 100644 index 0000000..a31636c --- /dev/null +++ b/src/data/teams/rrss.md @@ -0,0 +1,5 @@ +--- +name: 'RRSS & Comms' +description: 'Gestionamos la presencia digital y la comunicación oficial de la PyConES 2026 para que nadie se pierda nada y que la comunidad Python esté siempre informada' +contact: 'comm@es.pycon.org' +--- diff --git a/src/data/teams/social.md b/src/data/teams/social.md new file mode 100644 index 0000000..cf4de31 --- /dev/null +++ b/src/data/teams/social.md @@ -0,0 +1,5 @@ +--- +name: 'Fiestas y Social' +description: 'Organizamos los momentos de conexión fuera del escenario: las fiestas y eventos sociales de la PyConES 2026 donde la comunidad Python se reúne, celebra y crea vínculos.' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/data/teams/sponsors.md b/src/data/teams/sponsors.md new file mode 100644 index 0000000..db45589 --- /dev/null +++ b/src/data/teams/sponsors.md @@ -0,0 +1,5 @@ +--- +name: 'Sponsors' +description: 'Buscamos financiación para la conferencia y aseguramos la mejor experiencia para todas las entidades patrocinadoras.' +contact: 'sponsors@2026.es.pycon.org' +--- diff --git a/src/data/teams/ticketing.md b/src/data/teams/ticketing.md new file mode 100644 index 0000000..fc4f025 --- /dev/null +++ b/src/data/teams/ticketing.md @@ -0,0 +1,5 @@ +--- +name: 'Ticketing y Acreditaciones' +description: 'Gestionamos el acceso a la PyConES 2026, desde la venta de entradas hasta la acreditación en puerta, para garantizar una experiencia ágil y sin fricciones.' +contact: 'tickets@2026.es.pycon.org' +--- diff --git a/src/data/teams/venue.md b/src/data/teams/venue.md new file mode 100644 index 0000000..53055d0 --- /dev/null +++ b/src/data/teams/venue.md @@ -0,0 +1,5 @@ +--- +name: 'Venue' +description: 'Buscamos y gestionamos el espacio perfecto para la PyConES 2026, es decir, coordinamos el lugar del evento para que todo encaje' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/data/teams/volunteers.md b/src/data/teams/volunteers.md new file mode 100644 index 0000000..b61b9b8 --- /dev/null +++ b/src/data/teams/volunteers.md @@ -0,0 +1,5 @@ +--- +name: 'Voluntarios' +description: 'Reclutamos, formamos y coordinamos al equipo de voluntarios que hace posible la PyConES 2026: las personas que están en primera línea para que todo fluya el día del evento.' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/data/teams/web.md b/src/data/teams/web.md new file mode 100644 index 0000000..b7fa0fb --- /dev/null +++ b/src/data/teams/web.md @@ -0,0 +1,5 @@ +--- +name: 'Web' +description: 'Diseñamos y mantenemos la web oficial de la PyConES 2026 para que la comunidad encuentre toda la información que necesita.' +contact: 'contacto@2026.es.pycon.org' +--- diff --git a/src/i18n/menu/ca.ts b/src/i18n/menu/ca.ts index d866503..3173a66 100644 --- a/src/i18n/menu/ca.ts +++ b/src/i18n/menu/ca.ts @@ -12,6 +12,10 @@ export const ca = { label: 'On allotjar-se', href: '/accommodation', }, + { + label: 'Equips', + href: '/teams', + }, { label: 'Diversitat i Inclusió', children: [ diff --git a/src/i18n/menu/en.ts b/src/i18n/menu/en.ts index 42e6332..f456e59 100644 --- a/src/i18n/menu/en.ts +++ b/src/i18n/menu/en.ts @@ -12,6 +12,10 @@ export const en = { label: 'Where to stay', href: '/accommodation', }, + { + label: 'Teams', + href: '/teams', + }, { label: 'Diversity and Inclusion', children: [ diff --git a/src/i18n/menu/es.ts b/src/i18n/menu/es.ts index ecd0943..9141049 100644 --- a/src/i18n/menu/es.ts +++ b/src/i18n/menu/es.ts @@ -12,6 +12,10 @@ export const es = { label: 'Dónde alojarse', href: '/accommodation', }, + { + label: 'Equipos', + href: '/teams', + }, { label: 'Diversidad e Inclusión', children: [ diff --git a/src/i18n/teams/ca.ts b/src/i18n/teams/ca.ts new file mode 100644 index 0000000..7bee452 --- /dev/null +++ b/src/i18n/teams/ca.ts @@ -0,0 +1,5 @@ +export const ca = { + title: 'Equips | PyConES 2026', + hero: 'Equips', + contact: 'Contacte', +} as const diff --git a/src/i18n/teams/en.ts b/src/i18n/teams/en.ts new file mode 100644 index 0000000..603bed1 --- /dev/null +++ b/src/i18n/teams/en.ts @@ -0,0 +1,5 @@ +export const en = { + title: 'Teams | PyConES 2026', + hero: 'Teams', + contact: 'Contact', +} as const diff --git a/src/i18n/teams/es.ts b/src/i18n/teams/es.ts new file mode 100644 index 0000000..e54fbf0 --- /dev/null +++ b/src/i18n/teams/es.ts @@ -0,0 +1,5 @@ +export const es = { + title: 'Equipos | PyConES 2026', + hero: 'Equipos', + contact: 'Contacto', +} as const diff --git a/src/i18n/teams/index.ts b/src/i18n/teams/index.ts new file mode 100644 index 0000000..e6461b7 --- /dev/null +++ b/src/i18n/teams/index.ts @@ -0,0 +1,9 @@ +import { es } from './es' +import { en } from './en' +import { ca } from './ca' + +export const teamsTexts = { + es, + en, + ca, +} as const diff --git a/src/pages/[lang]/teams.astro b/src/pages/[lang]/teams.astro new file mode 100644 index 0000000..37f141f --- /dev/null +++ b/src/pages/[lang]/teams.astro @@ -0,0 +1,26 @@ +--- +import Layout from '../../layouts/Layout.astro' +import TeamsPage from '../../components/TeamsPage.astro' + +export function getStaticPaths() { + return [{ params: { lang: 'es' } }, { params: { lang: 'en' } }, { params: { lang: 'ca' } }] +} + +const { lang } = Astro.params + +const titles = { + es: 'Equipos | PyConES 2026', + en: 'Teams | PyConES 2026', + ca: 'Equips | PyConES 2026', +} + +const title = titles[(lang || 'es') as keyof typeof titles] +--- + + +
+
+ +
+
+
From 6c90553eef5491b215cb4d4a3a84056ce60f4af4 Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Sun, 10 May 2026 09:38:22 +0200 Subject: [PATCH 02/10] fix: format code --- .gitignore | 2 ++ src/components/TeamsPage.astro | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 72e6304..deb079b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ dist/ .vscode/ *.local + +.claude diff --git a/src/components/TeamsPage.astro b/src/components/TeamsPage.astro index 41d6bee..fe830bc 100644 --- a/src/components/TeamsPage.astro +++ b/src/components/TeamsPage.astro @@ -17,10 +17,7 @@ const teams = (
-

+

{t.hero}

From ee76971433f52bd9d23ea3beb45b01fd01296db4 Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Sun, 10 May 2026 12:30:43 +0200 Subject: [PATCH 03/10] feat: group accommodation and teams under Information dropdown menu Co-Authored-By: Claude Sonnet 4.6 --- src/i18n/menu/ca.ts | 17 +++++++++++------ src/i18n/menu/en.ts | 17 +++++++++++------ src/i18n/menu/es.ts | 17 +++++++++++------ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/i18n/menu/ca.ts b/src/i18n/menu/ca.ts index 3173a66..9984634 100644 --- a/src/i18n/menu/ca.ts +++ b/src/i18n/menu/ca.ts @@ -9,12 +9,17 @@ export const ca = { href: '/location', }, { - label: 'On allotjar-se', - href: '/accommodation', - }, - { - label: 'Equips', - href: '/teams', + label: 'Informació', + children: [ + { + label: 'On allotjar-se', + href: '/accommodation', + }, + { + label: 'Equips', + href: '/teams', + }, + ], }, { label: 'Diversitat i Inclusió', diff --git a/src/i18n/menu/en.ts b/src/i18n/menu/en.ts index f456e59..1cfd85a 100644 --- a/src/i18n/menu/en.ts +++ b/src/i18n/menu/en.ts @@ -9,12 +9,17 @@ export const en = { href: '/location', }, { - label: 'Where to stay', - href: '/accommodation', - }, - { - label: 'Teams', - href: '/teams', + label: 'Information', + children: [ + { + label: 'Where to stay', + href: '/accommodation', + }, + { + label: 'Teams', + href: '/teams', + }, + ], }, { label: 'Diversity and Inclusion', diff --git a/src/i18n/menu/es.ts b/src/i18n/menu/es.ts index 9141049..703c933 100644 --- a/src/i18n/menu/es.ts +++ b/src/i18n/menu/es.ts @@ -9,12 +9,17 @@ export const es = { href: '/location', }, { - label: 'Dónde alojarse', - href: '/accommodation', - }, - { - label: 'Equipos', - href: '/teams', + label: 'Información', + children: [ + { + label: 'Dónde alojarse', + href: '/accommodation', + }, + { + label: 'Equipos', + href: '/teams', + }, + ], }, { label: 'Diversidad e Inclusión', From 07a257a44fb163bb855303c6f008b62e80f30eb1 Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Sun, 10 May 2026 12:31:20 +0200 Subject: [PATCH 04/10] feat: move venue into Information dropdown menu Co-Authored-By: Claude Sonnet 4.6 --- src/i18n/menu/ca.ts | 8 ++++---- src/i18n/menu/en.ts | 8 ++++---- src/i18n/menu/es.ts | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/i18n/menu/ca.ts b/src/i18n/menu/ca.ts index 9984634..1820209 100644 --- a/src/i18n/menu/ca.ts +++ b/src/i18n/menu/ca.ts @@ -4,13 +4,13 @@ export const ca = { label: 'Inici', href: '/', }, - { - label: 'Seu', - href: '/location', - }, { label: 'Informació', children: [ + { + label: 'Seu', + href: '/location', + }, { label: 'On allotjar-se', href: '/accommodation', diff --git a/src/i18n/menu/en.ts b/src/i18n/menu/en.ts index 1cfd85a..b03e2f8 100644 --- a/src/i18n/menu/en.ts +++ b/src/i18n/menu/en.ts @@ -4,13 +4,13 @@ export const en = { label: 'Home', href: '/', }, - { - label: 'Venue', - href: '/location', - }, { label: 'Information', children: [ + { + label: 'Venue', + href: '/location', + }, { label: 'Where to stay', href: '/accommodation', diff --git a/src/i18n/menu/es.ts b/src/i18n/menu/es.ts index 703c933..f1669d7 100644 --- a/src/i18n/menu/es.ts +++ b/src/i18n/menu/es.ts @@ -4,13 +4,13 @@ export const es = { label: 'Inicio', href: '/', }, - { - label: 'Sede', - href: '/location', - }, { label: 'Información', children: [ + { + label: 'Sede', + href: '/location', + }, { label: 'Dónde alojarse', href: '/accommodation', From 5cb5a55e09740396911343abb7f3c418281d14e5 Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Sun, 10 May 2026 12:33:30 +0200 Subject: [PATCH 05/10] fix: adjust heading hierarchy in TeamsPage Co-Authored-By: Claude Sonnet 4.6 --- src/components/TeamsPage.astro | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/TeamsPage.astro b/src/components/TeamsPage.astro index fe830bc..a03552b 100644 --- a/src/components/TeamsPage.astro +++ b/src/components/TeamsPage.astro @@ -17,13 +17,12 @@ const teams = (
-

+

{t.hero} -

+
-

{t.hero}

+ ) + } +
+ + diff --git a/src/data/jobs/_plantilla-oferta.md b/src/data/jobs/_plantilla-oferta.md new file mode 100644 index 0000000..d85718d --- /dev/null +++ b/src/data/jobs/_plantilla-oferta.md @@ -0,0 +1,12 @@ +--- +title: "Nombre del puesto" +company: "Nombre de la empresa" +location: "Remoto / Madrid / Barcelona" +type: "Full-time" +description: "Descripción breve del puesto. Explica qué harás, el equipo, el proyecto, etc." +skills: [Python, Django, PostgreSQL] +salary: "35k-50k" +apply_url: "https://ejemplo.com/careers" +tier: "gold" +draft: true +--- \ No newline at end of file diff --git a/src/data/jobs/ca/jetbrains-python-dev.md b/src/data/jobs/ca/jetbrains-python-dev.md new file mode 100644 index 0000000..e3e81ac --- /dev/null +++ b/src/data/jobs/ca/jetbrains-python-dev.md @@ -0,0 +1,12 @@ +--- +title: "Senior Python Developer" +company: "JetBrains" +location: "Remot" +type: "Full-time" +description: "Uneix-te al nostre equip per treballar en eines de desenvolupament d'última generació. Formaràs part d'un equip que crea productes utilitzats per milions de desenvolupadors a tot el món." +skills: [Python, Django, PostgreSQL, AWS] +salary: "60k-80k" +apply_url: "https://www.jetbrains.com/careers/" +tier: "gold" +draft: false +--- \ No newline at end of file diff --git a/src/data/jobs/en/fever-senior-dev.md b/src/data/jobs/en/fever-senior-dev.md new file mode 100644 index 0000000..02daca9 --- /dev/null +++ b/src/data/jobs/en/fever-senior-dev.md @@ -0,0 +1,12 @@ +--- +title: "Senior Backend Engineer" +company: "Fever" +location: "Madrid - Hybrid" +type: "Full-time" +description: "We're looking for a Senior Backend Engineer to join our backend team, with outstanding software development talent." +skills: [Python, Django, PostgreSQL, Redis, AWS, Docker, Kubernetes] +salary: "50k-70k + 10% + stock options" +apply_url: "https://careers.feverup.com/" +tier: "gold" +draft: false +--- \ No newline at end of file diff --git a/src/data/jobs/en/jetbrains-python-dev.md b/src/data/jobs/en/jetbrains-python-dev.md new file mode 100644 index 0000000..09037c4 --- /dev/null +++ b/src/data/jobs/en/jetbrains-python-dev.md @@ -0,0 +1,12 @@ +--- +title: "Senior Python Developer" +company: "JetBrains" +location: "Remote" +type: "Full-time" +description: "Join our team to work on cutting-edge developer tools. You'll be part of a team that creates products used by millions of developers worldwide." +skills: [Python, Django, PostgreSQL, AWS] +salary: "60k-80k" +apply_url: "https://www.jetbrains.com/careers/" +tier: "gold" +draft: false +--- \ No newline at end of file diff --git a/src/data/jobs/es/fever-senior-dev.md b/src/data/jobs/es/fever-senior-dev.md new file mode 100644 index 0000000..93dea41 --- /dev/null +++ b/src/data/jobs/es/fever-senior-dev.md @@ -0,0 +1,12 @@ +--- +title: "Senior Backend Engineer" +company: "Fever" +location: "Madrid - Hybrid" +type: "Full-time" +description: "We're looking for a Senior Backend Engineer to join our backend team, with outstanding software development talent demonstrated by great work results and experience." +skills: [Python, Django, PostgreSQL, Redis, AWS, Docker, Kubernetes] +salary: "50k-70k + 10% + stock options" +apply_url: "https://careers.feverup.com/" +tier: "gold" +draft: false +--- \ No newline at end of file diff --git a/src/data/jobs/es/jetbrains-python-dev.md b/src/data/jobs/es/jetbrains-python-dev.md new file mode 100644 index 0000000..ed478d6 --- /dev/null +++ b/src/data/jobs/es/jetbrains-python-dev.md @@ -0,0 +1,12 @@ +--- +title: "Senior Python Developer" +company: "JetBrains" +location: "Remoto" +type: "Full-time" +description: "Join our team to work on cutting-edge developer tools. You'll be part of a team that creates products used by millions of developers worldwide." +skills: [Python, Django, PostgreSQL, AWS] +salary: "60k-80k" +apply_url: "https://www.jetbrains.com/careers/" +tier: "gold" +draft: false +--- \ No newline at end of file diff --git a/src/i18n/jobs/ca.ts b/src/i18n/jobs/ca.ts new file mode 100644 index 0000000..4415466 --- /dev/null +++ b/src/i18n/jobs/ca.ts @@ -0,0 +1,11 @@ +export const ca = { + title: 'Ofertes de treball | PyConES 2026', + hero: 'Ofertes de treball', + subtitle: 'Les següents ofertes han estat enviades pels patrocinadors de la conferència:', + apply: 'Veure detalls', + featured: 'Destacat', + salary: 'Sou', + location: 'Ubicació', + no_jobs: 'No hi ha ofertes de treball publicades en aquest idioma.', + skills: 'Tecnologies', +} as const diff --git a/src/i18n/jobs/en.ts b/src/i18n/jobs/en.ts new file mode 100644 index 0000000..575d4c3 --- /dev/null +++ b/src/i18n/jobs/en.ts @@ -0,0 +1,11 @@ +export const en = { + title: 'Job offers | PyConES 2026', + hero: 'Job offers', + subtitle: 'The following offers have been submitted by conference sponsors:', + apply: 'View details', + featured: 'Featured', + salary: 'Salary', + location: 'Location', + no_jobs: 'No job offers published in this language.', + skills: 'Technologies', +} as const diff --git a/src/i18n/jobs/es.ts b/src/i18n/jobs/es.ts new file mode 100644 index 0000000..071e256 --- /dev/null +++ b/src/i18n/jobs/es.ts @@ -0,0 +1,11 @@ +export const es = { + title: 'Ofertas de trabajo | PyConES 2026', + hero: 'Ofertas de trabajo', + subtitle: 'Las siguientes ofertas han sido enviadas por los patrocinadores de la conferencia:', + apply: 'Ver detalles', + featured: 'Destacado', + salary: 'Salario', + location: 'Ubicación', + no_jobs: 'No hay ofertas de trabajo publicadas en este idioma.', + skills: 'Tecnologías', +} as const diff --git a/src/i18n/jobs/index.ts b/src/i18n/jobs/index.ts new file mode 100644 index 0000000..5f4de95 --- /dev/null +++ b/src/i18n/jobs/index.ts @@ -0,0 +1,9 @@ +import { es } from './es' +import { en } from './en' +import { ca } from './ca' + +export const jobsTexts = { + es, + en, + ca, +} as const diff --git a/src/i18n/menu/ca.ts b/src/i18n/menu/ca.ts index 1820209..62eb720 100644 --- a/src/i18n/menu/ca.ts +++ b/src/i18n/menu/ca.ts @@ -55,6 +55,10 @@ export const ca = { }, ], }, + { + label: 'Ofertes de treball', + href: '/jobs', + }, { label: 'Edicions Anteriors', children: [ diff --git a/src/i18n/menu/en.ts b/src/i18n/menu/en.ts index b03e2f8..40c9c92 100644 --- a/src/i18n/menu/en.ts +++ b/src/i18n/menu/en.ts @@ -55,6 +55,10 @@ export const en = { }, ], }, + { + label: 'Job offers', + href: '/jobs', + }, { label: 'Past Editions', children: [ diff --git a/src/i18n/menu/es.ts b/src/i18n/menu/es.ts index f1669d7..869fcbd 100644 --- a/src/i18n/menu/es.ts +++ b/src/i18n/menu/es.ts @@ -55,6 +55,10 @@ export const es = { }, ], }, + { + label: 'Ofertas de trabajo', + href: '/jobs', + }, { label: 'Ediciones Anteriores', children: [ diff --git a/src/pages/[lang]/jobs.astro b/src/pages/[lang]/jobs.astro new file mode 100644 index 0000000..5dbbda5 --- /dev/null +++ b/src/pages/[lang]/jobs.astro @@ -0,0 +1,27 @@ +--- +import Layout from '../../layouts/Layout.astro' +import JobsPage from '../../components/JobsPage.astro' +import { jobsTexts } from '../../i18n/jobs' + +export function getStaticPaths() { + return [{ params: { lang: 'es' } }, { params: { lang: 'en' } }, { params: { lang: 'ca' } }] +} + +const { lang } = Astro.params + +const titles = { + es: 'Ofertas de trabajo | PyConES 2026', + en: 'Job offers | PyConES 2026', + ca: 'Ofertes de treball | PyConES 2026', +} + +const title = titles[(lang || 'es') as keyof typeof titles] +--- + + +
+
+ +
+
+
From 9ddc3ce2919dc1c2836621de640ec1ea1d98a338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Itziar=20Zameza=20Garc=C3=ADa?= Date: Sun, 10 May 2026 19:36:46 +0200 Subject: [PATCH 08/10] feat: change offers to draft --- src/components/JobsPage.astro | 72 +++++++++--------------- src/data/jobs/ca/jetbrains-python-dev.md | 18 +++--- src/data/jobs/en/fever-senior-dev.md | 18 +++--- src/data/jobs/en/jetbrains-python-dev.md | 18 +++--- src/data/jobs/es/fever-senior-dev.md | 18 +++--- src/data/jobs/es/jetbrains-python-dev.md | 18 +++--- 6 files changed, 71 insertions(+), 91 deletions(-) diff --git a/src/components/JobsPage.astro b/src/components/JobsPage.astro index 2fea52a..6000b2b 100644 --- a/src/components/JobsPage.astro +++ b/src/components/JobsPage.astro @@ -59,48 +59,40 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum'

{t.no_jobs}

) : (
+

{t.hero}

{jobs.map(({ frontmatter: job }) => ( -
+

{job.title}

{job.company}

{isFeatured(job.tier) && ( - - {t.featured} - -)} + {t.featured} + )} +
+ +
+

{job.description}

+ {job.skills && job.skills.length > 0 && ( +
+

{t.skills}

+
+ {job.skills.map((skill) => ( + {skill} + ))} +
+
+ )} +
- {job.location}
@@ -108,26 +100,14 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' {job.salary && {job.salary}}
- + {t.apply} -
- + ))} ) @@ -162,4 +142,4 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' animation: none; } } - + \ No newline at end of file diff --git a/src/data/jobs/ca/jetbrains-python-dev.md b/src/data/jobs/ca/jetbrains-python-dev.md index e3e81ac..f85d7f7 100644 --- a/src/data/jobs/ca/jetbrains-python-dev.md +++ b/src/data/jobs/ca/jetbrains-python-dev.md @@ -1,12 +1,12 @@ --- -title: "Senior Python Developer" -company: "JetBrains" -location: "Remot" -type: "Full-time" +title: 'Senior Python Developer' +company: 'JetBrains' +location: 'Remot' +type: 'Full-time' description: "Uneix-te al nostre equip per treballar en eines de desenvolupament d'última generació. Formaràs part d'un equip que crea productes utilitzats per milions de desenvolupadors a tot el món." skills: [Python, Django, PostgreSQL, AWS] -salary: "60k-80k" -apply_url: "https://www.jetbrains.com/careers/" -tier: "gold" -draft: false ---- \ No newline at end of file +salary: '60k-80k' +apply_url: 'https://www.jetbrains.com/careers/' +tier: 'gold' +draft: true +--- diff --git a/src/data/jobs/en/fever-senior-dev.md b/src/data/jobs/en/fever-senior-dev.md index 02daca9..6fda4af 100644 --- a/src/data/jobs/en/fever-senior-dev.md +++ b/src/data/jobs/en/fever-senior-dev.md @@ -1,12 +1,12 @@ --- -title: "Senior Backend Engineer" -company: "Fever" -location: "Madrid - Hybrid" -type: "Full-time" +title: 'Senior Backend Engineer' +company: 'Fever' +location: 'Madrid - Hybrid' +type: 'Full-time' description: "We're looking for a Senior Backend Engineer to join our backend team, with outstanding software development talent." skills: [Python, Django, PostgreSQL, Redis, AWS, Docker, Kubernetes] -salary: "50k-70k + 10% + stock options" -apply_url: "https://careers.feverup.com/" -tier: "gold" -draft: false ---- \ No newline at end of file +salary: '50k-70k + 10% + stock options' +apply_url: 'https://careers.feverup.com/' +tier: 'gold' +draft: true +--- diff --git a/src/data/jobs/en/jetbrains-python-dev.md b/src/data/jobs/en/jetbrains-python-dev.md index 09037c4..b27081d 100644 --- a/src/data/jobs/en/jetbrains-python-dev.md +++ b/src/data/jobs/en/jetbrains-python-dev.md @@ -1,12 +1,12 @@ --- -title: "Senior Python Developer" -company: "JetBrains" -location: "Remote" -type: "Full-time" +title: 'Senior Python Developer' +company: 'JetBrains' +location: 'Remote' +type: 'Full-time' description: "Join our team to work on cutting-edge developer tools. You'll be part of a team that creates products used by millions of developers worldwide." skills: [Python, Django, PostgreSQL, AWS] -salary: "60k-80k" -apply_url: "https://www.jetbrains.com/careers/" -tier: "gold" -draft: false ---- \ No newline at end of file +salary: '60k-80k' +apply_url: 'https://www.jetbrains.com/careers/' +tier: 'gold' +draft: true +--- diff --git a/src/data/jobs/es/fever-senior-dev.md b/src/data/jobs/es/fever-senior-dev.md index 93dea41..2dff39d 100644 --- a/src/data/jobs/es/fever-senior-dev.md +++ b/src/data/jobs/es/fever-senior-dev.md @@ -1,12 +1,12 @@ --- -title: "Senior Backend Engineer" -company: "Fever" -location: "Madrid - Hybrid" -type: "Full-time" +title: 'Senior Backend Engineer' +company: 'Fever' +location: 'Madrid - Hybrid' +type: 'Full-time' description: "We're looking for a Senior Backend Engineer to join our backend team, with outstanding software development talent demonstrated by great work results and experience." skills: [Python, Django, PostgreSQL, Redis, AWS, Docker, Kubernetes] -salary: "50k-70k + 10% + stock options" -apply_url: "https://careers.feverup.com/" -tier: "gold" -draft: false ---- \ No newline at end of file +salary: '50k-70k + 10% + stock options' +apply_url: 'https://careers.feverup.com/' +tier: 'gold' +draft: true +--- diff --git a/src/data/jobs/es/jetbrains-python-dev.md b/src/data/jobs/es/jetbrains-python-dev.md index ed478d6..ca100c4 100644 --- a/src/data/jobs/es/jetbrains-python-dev.md +++ b/src/data/jobs/es/jetbrains-python-dev.md @@ -1,12 +1,12 @@ --- -title: "Senior Python Developer" -company: "JetBrains" -location: "Remoto" -type: "Full-time" +title: 'Senior Python Developer' +company: 'JetBrains' +location: 'Remoto' +type: 'Full-time' description: "Join our team to work on cutting-edge developer tools. You'll be part of a team that creates products used by millions of developers worldwide." skills: [Python, Django, PostgreSQL, AWS] -salary: "60k-80k" -apply_url: "https://www.jetbrains.com/careers/" -tier: "gold" -draft: false ---- \ No newline at end of file +salary: '60k-80k' +apply_url: 'https://www.jetbrains.com/careers/' +tier: 'gold' +draft: true +--- From 62a83ef28ac360c6c8e3c47e00a6c9731ad1343b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Itziar=20Zameza=20Garc=C3=ADa?= Date: Sun, 10 May 2026 19:47:40 +0200 Subject: [PATCH 09/10] feat: formatting --- README.md | 1 - src/components/JobsPage.astro | 27 ++++++++++++++------------- src/data/jobs/_plantilla-oferta.md | 18 +++++++++--------- src/pages/[lang]/jobs.astro | 9 ++++++++- tsconfig.json | 2 +- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ae8e554..bee518c 100644 --- a/README.md +++ b/README.md @@ -96,4 +96,3 @@ Deployment is manual and triggered from GitHub Actions: 3. Click **Run workflow** The site is deployed to GitHub Pages at `https://2026.es.pycon.org/`. - diff --git a/src/components/JobsPage.astro b/src/components/JobsPage.astro index 6000b2b..181d628 100644 --- a/src/components/JobsPage.astro +++ b/src/components/JobsPage.astro @@ -1,5 +1,6 @@ --- import { jobsTexts } from '../i18n/jobs' +import { menuTexts } from '../i18n/menu' interface Props { lang: string @@ -20,6 +21,7 @@ interface JobFrontmatter { const { lang } = Astro.props const t = jobsTexts[(lang || 'es') as keyof typeof jobsTexts] +const menuT = menuTexts[(lang || 'es') as keyof typeof menuTexts] const esJobs = Object.values(import.meta.glob('../data/jobs/es/*.md', { eager: true })) as { frontmatter: JobFrontmatter }[] const enJobs = Object.values(import.meta.glob('../data/jobs/en/*.md', { eager: true })) as { frontmatter: JobFrontmatter }[] @@ -58,11 +60,10 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' jobs.length === 0 ? (

{t.no_jobs}

) : ( -
-

{t.hero}

+
    {jobs.map(({ frontmatter: job }) => ( -
    -
    +
  • +

    {job.title}

    {job.company}

    @@ -70,7 +71,7 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' {isFeatured(job.tier) && ( {t.featured} )} -
  • +

    {job.description}

    @@ -79,15 +80,15 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' {job.skills && job.skills.length > 0 && (

    {t.skills}

    -
    +
      {job.skills.map((skill) => ( - {skill} +
    • {skill}
    • ))} -
    +
)} -
+
{job.salary}}
- + {t.apply} -
- + + ))} -
+ ) } diff --git a/src/data/jobs/_plantilla-oferta.md b/src/data/jobs/_plantilla-oferta.md index d85718d..2e1b5f6 100644 --- a/src/data/jobs/_plantilla-oferta.md +++ b/src/data/jobs/_plantilla-oferta.md @@ -1,12 +1,12 @@ --- -title: "Nombre del puesto" -company: "Nombre de la empresa" -location: "Remoto / Madrid / Barcelona" -type: "Full-time" -description: "Descripción breve del puesto. Explica qué harás, el equipo, el proyecto, etc." +title: 'Nombre del puesto' +company: 'Nombre de la empresa' +location: 'Remoto / Madrid / Barcelona' +type: 'Full-time' +description: 'Descripción breve del puesto. Explica qué harás, el equipo, el proyecto, etc.' skills: [Python, Django, PostgreSQL] -salary: "35k-50k" -apply_url: "https://ejemplo.com/careers" -tier: "gold" +salary: '35k-50k' +apply_url: 'https://ejemplo.com/careers' +tier: 'gold' draft: true ---- \ No newline at end of file +--- diff --git a/src/pages/[lang]/jobs.astro b/src/pages/[lang]/jobs.astro index 5dbbda5..1f33872 100644 --- a/src/pages/[lang]/jobs.astro +++ b/src/pages/[lang]/jobs.astro @@ -15,10 +15,17 @@ const titles = { ca: 'Ofertes de treball | PyConES 2026', } +const descriptions = { + es: 'Explora las ofertas de trabajo de los patrocinadores de PyConES 2026. Encuentra oportunidades como Python Developer, DevOps Engineer y más.', + en: 'Explore job offers from PyConES 2026 sponsors. Find opportunities like Python Developer, DevOps Engineer and more.', + ca: 'Explora les ofertes de treball dels patrocinadors de PyConES 2026. Troba oportunitats com Python Developer, DevOps Engineer i més.', +} + const title = titles[(lang || 'es') as keyof typeof titles] +const description = descriptions[(lang || 'es') as keyof typeof descriptions] --- - +
diff --git a/tsconfig.json b/tsconfig.json index 2e66b49..f520ae4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "astro/tsconfigs/base", - "include": ["src/**/*"], + "include": ["src/**/*"], "compilerOptions": { "baseUrl": ".", "paths": { From 5e56e4df98173061fd85ecd9140d6c7d204e8b0e Mon Sep 17 00:00:00 2001 From: Francesc Arpi Roca Date: Tue, 12 May 2026 08:27:58 +0200 Subject: [PATCH 10/10] fix: formater --- src/components/JobsPage.astro | 65 ++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/src/components/JobsPage.astro b/src/components/JobsPage.astro index 181d628..d4ccced 100644 --- a/src/components/JobsPage.astro +++ b/src/components/JobsPage.astro @@ -23,9 +23,15 @@ const { lang } = Astro.props const t = jobsTexts[(lang || 'es') as keyof typeof jobsTexts] const menuT = menuTexts[(lang || 'es') as keyof typeof menuTexts] -const esJobs = Object.values(import.meta.glob('../data/jobs/es/*.md', { eager: true })) as { frontmatter: JobFrontmatter }[] -const enJobs = Object.values(import.meta.glob('../data/jobs/en/*.md', { eager: true })) as { frontmatter: JobFrontmatter }[] -const caJobs = Object.values(import.meta.glob('../data/jobs/ca/*.md', { eager: true })) as { frontmatter: JobFrontmatter }[] +const esJobs = Object.values(import.meta.glob('../data/jobs/es/*.md', { eager: true })) as { + frontmatter: JobFrontmatter +}[] +const enJobs = Object.values(import.meta.glob('../data/jobs/en/*.md', { eager: true })) as { + frontmatter: JobFrontmatter +}[] +const caJobs = Object.values(import.meta.glob('../data/jobs/ca/*.md', { eager: true })) as { + frontmatter: JobFrontmatter +}[] const allJobsMap: Record = { es: esJobs, @@ -62,14 +68,18 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' ) : (
    {jobs.map(({ frontmatter: job }) => ( -
  • +
  • {job.title}

    {job.company}

    {isFeatured(job.tier) && ( - {t.featured} + + {t.featured} + )}
    @@ -82,7 +92,11 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum'

    {t.skills}

      {job.skills.map((skill) => ( -
    • {skill}
    • +
    • + + {skill} + +
    • ))}
@@ -91,9 +105,25 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum'
- {job.location}
@@ -101,10 +131,21 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' {job.salary && {job.salary}}
- + {t.apply}
@@ -143,4 +184,4 @@ const isFeatured = (tier?: string) => tier === 'gold' || tier === 'platinum' animation: none; } } - \ No newline at end of file +