Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@
"resultsCta": "View leaderboard",
"closedEventTitle": "Event closed",
"closedEvent": "This event has ended. Thanks to everyone who took part!",
"publishedTitle": "Open to everyone",
"published": "No registration needed. Add it to your calendar and join through the link on the day.",
"publishedTitle": "Event announced",
"published": "Add it to your calendar and join through the link on the day.",
"publishedOpenTitle": "Open to everyone",
"publishedOpen": "No NaN registration needed. Add it to your calendar and join through the link on the day.",
"publishedMembersTitle": "NaN members only",
"publishedMembers": "This event is for NaN members only. If you are one, open the link, mark yourself as interested and Discord will remind you on the day.",
"publishedCta": "Join the event"
},
"alreadyRegistered": {
Expand Down
8 changes: 6 additions & 2 deletions i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@
"resultsCta": "Ver clasificación",
"closedEventTitle": "Evento cerrado",
"closedEvent": "Este evento ha terminado. ¡Gracias a todos los que habéis participado!",
"publishedTitle": "Abierto a todos",
"published": "Este evento no necesita inscripción. Apúntalo en tu calendario y entra por el enlace el día del evento.",
"publishedTitle": "Evento anunciado",
"published": "Apúntalo en tu calendario y entra por el enlace el día del evento.",
"publishedOpenTitle": "Abierto a todos",
"publishedOpen": "Este evento no necesita inscripción en NaN. Apúntalo en tu calendario y entra por el enlace el día del evento.",
"publishedMembersTitle": "Solo para la comunidad de NaN",
"publishedMembers": "Este evento es solo para miembros de NaN. Si ya eres miembro, entra por el enlace, márcate como interesado y Discord te avisará el día del evento.",
"publishedCta": "Ir al evento"
},
"alreadyRegistered": {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ export interface EventInfo {
/** Dónde se celebra (texto libre) y enlace de acceso; opcionales (SPEC v3 §3.1, B-25). */
location: string;
url: string;
/** Who the event is for (B-28): copy only, the page never enforces it. */
access: 'open' | 'members' | '';
/** Cover image (http/https, optional; B-27): shown on the public page and used as og:image. */
image_url: string;
format: EventFormat;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/eventsCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { apiBase, jsonData, ssrHeaders, type EventInfo } from './events';
/** Resumen de `GET /api/events`: los campos de la ficha que usa la página. */
export type PublicEventSummary = Pick<
EventInfo,
'slug' | 'kind' | 'name' | 'description' | 'location' | 'url' | 'image_url' | 'status' | 'dates'
'slug' | 'kind' | 'name' | 'description' | 'location' | 'url' | 'access' | 'image_url' | 'status' | 'dates'
>;

/** Ruta del feed dentro del sitio: pasa por el proxy same-origin. */
Expand Down
15 changes: 12 additions & 3 deletions src/pages/events/[slug]/_index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,18 @@ const submittedBody = closeAt ? fill(phase.submitted, { date: closeAt }) : phase
switch (ev.phase) {
case 'published':
// Informativo anunciado (B-26): no hay inscripción; el CTA es el enlace del evento si lo tiene.
panel = ev.url
? { title: phase.publishedTitle, body: phase.published, href: ev.url, cta: phase.publishedCta, tone: 'accent' }
: { title: phase.publishedTitle, body: phase.published, tone: 'accent' };
// El título y el texto dependen de `access` (B-28): "members" es solo para la comunidad,
// "open" es abierto a todos y vacío es neutro, para no anunciar como abierto lo que no lo es.
{
const copy = ev.access === 'members'
? { title: phase.publishedMembersTitle, body: phase.publishedMembers }
: ev.access === 'open'
? { title: phase.publishedOpenTitle, body: phase.publishedOpen }
: { title: phase.publishedTitle, body: phase.published };
panel = ev.url
? { ...copy, href: ev.url, cta: phase.publishedCta, tone: 'accent' }
: { ...copy, tone: 'accent' };
}
break;
case 'draft':
case 'registration':
Expand Down
2 changes: 1 addition & 1 deletion src/tests/lib/eventsCalendar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {

const ev = (over: Partial<PublicEventSummary> = {}): PublicEventSummary => ({
slug: 'taller-agentes', kind: 'workshop', name: 'Taller de agentes', description: 'Qué es un agente.',
location: 'Discord de NaN', url: '', image_url: '', status: 'closed',
location: 'Discord de NaN', url: '', access: '', image_url: '', status: 'closed',
dates: { demo_day: '2026-09-16T17:00:00Z', demo_day_end: null },
...over,
});
Expand Down
25 changes: 25 additions & 0 deletions src/tests/pages/eventsUiGuards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,28 @@ describe('event cover (B-27)', () => {
expect(base).toContain('const ogImageGeneric = !image;');
});
});

describe('event access (B-28)', () => {
const page = readFileSync(resolve(src, 'pages/events/[slug]/_index.astro'), 'utf-8');
const es = JSON.parse(readFileSync(resolve(src, '../i18n/es.json'), 'utf-8'));
const en = JSON.parse(readFileSync(resolve(src, '../i18n/en.json'), 'utf-8'));

test('the published panel picks its copy from ev.access, with a neutral fallback', () => {
expect(page).toMatch(/ev\.access === 'members'\s*\? \{ title: phase\.publishedMembersTitle, body: phase\.publishedMembers \}/);
expect(page).toMatch(/ev\.access === 'open'\s*\? \{ title: phase\.publishedOpenTitle, body: phase\.publishedOpen \}/);
expect(page).toMatch(/: \{ title: phase\.publishedTitle, body: phase\.published \}/);
});

test('both locales carry the three variants and only the open one says "everyone"', () => {
for (const dict of [es, en]) {
const phase = dict.events.phase;
for (const key of ['publishedTitle', 'published', 'publishedOpenTitle', 'publishedOpen', 'publishedMembersTitle', 'publishedMembers']) {
expect(phase[key], key).toBeTruthy();
}
expect(phase.publishedTitle).not.toMatch(/todos|everyone/i);
expect(phase.publishedMembersTitle).not.toMatch(/todos|everyone/i);
}
expect(es.events.phase.publishedOpenTitle).toBe('Abierto a todos');
expect(en.events.phase.publishedOpenTitle).toBe('Open to everyone');
});
});
Loading