From 4af3d23957f499fd0917727882a95c59644647a8 Mon Sep 17 00:00:00 2001 From: David Ascanio Date: Sat, 1 Aug 2026 17:11:55 -0300 Subject: [PATCH 1/5] git ignore --- .env | 4 ++++ .gitignore | 1 + 2 files changed, 5 insertions(+) diff --git a/.env b/.env index b746ff8..b8af0aa 100644 --- a/.env +++ b/.env @@ -23,6 +23,10 @@ DATABASE_URL="file:./dev.db" N8N_WEBHOOK_URL="https://flows2.carpa.com/webhook/news-summary" N8N_API_KEY="sk_live_JwjpTdZrLVvijCKuWylWZbUuhBm6zPDH" +# Cloudflare Email Sending +CLOUDFLARE_API_TOKEN=cfut_8Y0Tcwiv3v0K1LDK9QSvc3BjlU1lZFs1zikACgTw33977b37 +CLOUDFLARE_ACCOUNT_ID=3e689750123db91e81d3542d2930a907 + # Cloudflare Turnstile — public key (visible in frontend) TURNSTILE_SITE_KEY=0x4AAAAAAD9IYWC6HPflpneO diff --git a/.gitignore b/.gitignore index b6515b7..54c22db 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ prisma/dev.db # opencode - agentes y scripts locales (no subir a producción) opencode/ .opencode/ +.env From 861f65fd2f502a13f5d27bc837e12b8bcba2bad4 Mon Sep 17 00:00:00 2001 From: David Ascanio Date: Sat, 1 Aug 2026 18:04:12 -0300 Subject: [PATCH 2/5] contador volutanrios --- src/components/BaseHead.astro | 2 + src/layouts/MainLayout.astro | 3 +- src/pages/[locale]/contador-voluntarios.astro | 206 ++++++++++++++++++ src/pages/api/lib/googleSheets.ts | 11 + src/pages/api/voluntarios/count.ts | 21 ++ 5 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 src/pages/[locale]/contador-voluntarios.astro create mode 100644 src/pages/api/voluntarios/count.ts diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 541a678..a1ff7be 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -8,6 +8,7 @@ const { image = null, url = null, date = null, + noindex = false, } = Astro.props; const imageUrl = image ? new URL(image, Astro.site).toString() : null; @@ -20,6 +21,7 @@ const canonicalURL = new URL(url || Astro.url.pathname, Astro.site); + {noindex && } {title} diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index 1edcab3..432452b 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -8,7 +8,7 @@ import "@fontsource/poppins/700.css"; import "@fontsource-variable/kameron"; import ShareSticky from "../components/ShareSticky.vue"; import { routeTranslations } from "../i18n"; -const { title, description, image, url, date } = Astro.props; +const { title, description, image, url, date, noindex } = Astro.props; const currentLocale = Astro.currentLocale ?? "es"; const direction = currentLocale === "he" ? "rtl" : "ltr"; @@ -28,6 +28,7 @@ const isNewsPage = contentSegments.some((segment) => image={image} url={url} date={date} + noindex={noindex} /> + diff --git a/src/pages/api/lib/googleSheets.ts b/src/pages/api/lib/googleSheets.ts index 972826a..dcf8271 100644 --- a/src/pages/api/lib/googleSheets.ts +++ b/src/pages/api/lib/googleSheets.ts @@ -37,6 +37,17 @@ export async function emailExists(email: string): Promise { } +export async function getVolunteerCount(): Promise { + const result = await sheets.spreadsheets.values.get({ + spreadsheetId: SPREADSHEET_ID, + range: 'VOLUNTARIOS!B2:B', // columna nombre_completo, se llena en cada registro + valueRenderOption: 'UNFORMATTED_VALUE', + }); + + const rows = result.data.values || []; + return rows.filter((row) => row[0] !== undefined && row[0] !== '').length; +} + export async function appendToSheet(values: any[]) { try { await sheets.spreadsheets.values.append({ diff --git a/src/pages/api/voluntarios/count.ts b/src/pages/api/voluntarios/count.ts new file mode 100644 index 0000000..4cc10b3 --- /dev/null +++ b/src/pages/api/voluntarios/count.ts @@ -0,0 +1,21 @@ +import type { APIRoute } from "astro"; +import { getVolunteerCount } from "../lib/googleSheets"; + +export const prerender = false; + +export const GET: APIRoute = async () => { + try { + const count = await getVolunteerCount(); + + return Response.json( + { success: true, count }, + { headers: { "Cache-Control": "no-store" } } + ); + } catch (error) { + console.error("Error en /api/voluntarios/count:", error); + return Response.json( + { success: false, message: "Error al obtener el contador de voluntarios" }, + { status: 500 } + ); + } +}; From d40969ba44d92174533b43a118863caf2338c6ed Mon Sep 17 00:00:00 2001 From: David Ascanio Date: Sat, 1 Aug 2026 19:05:22 -0300 Subject: [PATCH 3/5] fix bug safari --- src/pages/[locale]/contador-voluntarios.astro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pages/[locale]/contador-voluntarios.astro b/src/pages/[locale]/contador-voluntarios.astro index bd6161b..aa66e22 100644 --- a/src/pages/[locale]/contador-voluntarios.astro +++ b/src/pages/[locale]/contador-voluntarios.astro @@ -95,6 +95,14 @@ const POLL_INTERVAL_MS = 10_000; .countdown { font-variant-numeric: tabular-nums; } + /* Fix para Safari/iOS: sin esto, las dos capas del dígito (actual y + siguiente) no quedan recortadas ni aisladas y se ven superpuestas. */ + .countdown > * { + overflow: clip; + isolation: isolate; + -webkit-transform: translateZ(0); + transform: translateZ(0); + } .pulse-update { animation: counter-pulse 0.5s ease-out; } From 553ddc96bee457f96b08284bf828a73c1ec4394e Mon Sep 17 00:00:00 2001 From: David Ascanio Date: Sat, 1 Aug 2026 19:13:58 -0300 Subject: [PATCH 4/5] delete counter animation --- src/pages/[locale]/contador-voluntarios.astro | 74 ++++++------------- 1 file changed, 23 insertions(+), 51 deletions(-) diff --git a/src/pages/[locale]/contador-voluntarios.astro b/src/pages/[locale]/contador-voluntarios.astro index aa66e22..50ebff1 100644 --- a/src/pages/[locale]/contador-voluntarios.astro +++ b/src/pages/[locale]/contador-voluntarios.astro @@ -45,18 +45,14 @@ const POLL_INTERVAL_MS = 10_000;
- - - + id="counter-number" + class="counter-number text-[clamp(3.5rem,16vw,9rem)] font-bold tabular-nums" + aria-hidden="true" + >0

@@ -92,19 +88,11 @@ const POLL_INTERVAL_MS = 10_000; .counter-card { animation: counter-fade-in 0.6s ease-out; } - .countdown { - font-variant-numeric: tabular-nums; + .counter-number { + display: inline-block; } - /* Fix para Safari/iOS: sin esto, las dos capas del dígito (actual y - siguiente) no quedan recortadas ni aisladas y se ven superpuestas. */ - .countdown > * { - overflow: clip; - isolation: isolate; - -webkit-transform: translateZ(0); - transform: translateZ(0); - } - .pulse-update { - animation: counter-pulse 0.5s ease-out; + .counter-number.counter-bump { + animation: counter-bump 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); } @keyframes counter-fade-in { from { @@ -116,15 +104,18 @@ const POLL_INTERVAL_MS = 10_000; transform: translateY(0) scale(1); } } - @keyframes counter-pulse { + @keyframes counter-bump { 0% { transform: scale(1); + opacity: 1; } - 30% { - transform: scale(1.06); + 35% { + transform: scale(1.12) translateY(-0.05em); + opacity: 0.55; } 100% { - transform: scale(1); + transform: scale(1) translateY(0); + opacity: 1; } } @@ -132,15 +123,12 @@ const POLL_INTERVAL_MS = 10_000;