From 8b3dbbd53225108a12d516016ca1c90e564ce7d5 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Thu, 27 Aug 2026 12:20:36 +0200 Subject: [PATCH 01/20] implement getActive method for active banners --- src/repositories/banners.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/repositories/banners.ts b/src/repositories/banners.ts index b90f1461..8b6ae3de 100644 --- a/src/repositories/banners.ts +++ b/src/repositories/banners.ts @@ -46,6 +46,34 @@ class BannerRepository { ); } + public async getActive(): Promise { + const now = Date.now(); + return await this.db + .prepare( + `SELECT + title, + content, + cta_text AS ctaText, + cta_link AS ctaLink, + starts_at AS startsAt, + ends_at AS endsAt, + date_created AS dateCreated + FROM banners + WHERE starts_at <= ? AND ends_at >= ? + ORDER BY date_created DESC`, + ) + .bind(now, now) + .all() + .then((data) => + data.results.map((r) => ({ + ...r, + startsAt: new Date(r.startsAt), + endsAt: new Date(r.endsAt), + dateCreated: new Date(r.dateCreated), + })), + ); + } + public async create(banner: BannerRecord): Promise { const result = await this.db .prepare( From 4476b819fbf8b47a56c5267655053b96cb2d7e6f Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Thu, 27 Aug 2026 12:24:12 +0200 Subject: [PATCH 02/20] render active banners --- src/pages/[...locale]/index.astro | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index 7a13c1d8..3fb284db 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -13,6 +13,7 @@ import HomeBanner from "../../components/home/HomeBanner.svelte"; // import Stories from "../../components/home/Stories.svelte"; // import Resources from "../../components/home/Resources.astro"; import { isSupportedLocale } from "../../i18n/locales"; +import { bannerRepository } from "../../repositories/banners"; const { locale } = Astro.params; @@ -21,21 +22,27 @@ if (locale && !isSupportedLocale(locale)) { } const { t, lang } = Astro.locals; + +const activeBanners = await bannerRepository.getActive(); --- -
- -
+ {activeBanners.length > 0 && ( +
+ {activeBanners.map((banner) => ( + + ))} +
+ )} From 0df450435ed44f93a3b3fe112186c52f1541aa39 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Thu, 27 Aug 2026 12:38:04 +0200 Subject: [PATCH 03/20] update handleDateSelect to match current system time --- src/components/admin/comm/banners/BannersForm.svelte | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/admin/comm/banners/BannersForm.svelte b/src/components/admin/comm/banners/BannersForm.svelte index 365ded06..f85b84eb 100644 --- a/src/components/admin/comm/banners/BannersForm.svelte +++ b/src/components/admin/comm/banners/BannersForm.svelte @@ -23,6 +23,11 @@ let fieldErrors: FieldErrors = $state({}); + function handleDateSelect(date: Date) { + const now = new Date(); + date.setHours(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds()); + } + async function submit() { fieldErrors = {}; @@ -105,6 +110,7 @@ placeholder={$t("pages.admin.comm.banners.fields.startDatePlaceholder")} error={fieldErrors.startsAt && $t(fieldErrors.startsAt, { date: formatDate(new Date(), $locale) })} + onInput={handleDateSelect} /> From c4eda6db2235436e97a96ad423139bd07bea96a5 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Thu, 27 Aug 2026 12:42:19 +0200 Subject: [PATCH 04/20] add translation keys for banners --- src/i18n/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 810fba65..d2f2c095 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -27,7 +27,7 @@ "expectedUrl": "No es una URL" }, "date": { - "greaterThan": "La fecha debe ser mayor que {{ date }}" + "greaterThan": "La fecha debe ser igual o mayor que el {{ date }}" }, "file": { "maxAllowedSize": "Tamaño máximo permitido {{ size }}", From 22bc9285e6759c518e416814c4561c7ffac9c55e Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Thu, 27 Aug 2026 12:47:06 +0200 Subject: [PATCH 05/20] format --- .../admin/comm/banners/BannersForm.svelte | 2 +- src/pages/[...locale]/index.astro | 30 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/components/admin/comm/banners/BannersForm.svelte b/src/components/admin/comm/banners/BannersForm.svelte index f85b84eb..be60e5cd 100644 --- a/src/components/admin/comm/banners/BannersForm.svelte +++ b/src/components/admin/comm/banners/BannersForm.svelte @@ -110,7 +110,7 @@ placeholder={$t("pages.admin.comm.banners.fields.startDatePlaceholder")} error={fieldErrors.startsAt && $t(fieldErrors.startsAt, { date: formatDate(new Date(), $locale) })} - onInput={handleDateSelect} + onInput={handleDateSelect} /> - {activeBanners.length > 0 && ( -
- {activeBanners.map((banner) => ( - - ))} -
- )} + { + activeBanners.length > 0 && ( +
+ {activeBanners.map((banner) => ( + + ))} +
+ ) + } From f1af9aed3bf0a16e67a629dc86dff56d94d05093 Mon Sep 17 00:00:00 2001 From: Pep Villalonga Date: Mon, 31 Aug 2026 13:10:24 +0200 Subject: [PATCH 06/20] fix: persist banner dismissal in a cookie --- src/components/home/HomeBanner.stories.svelte | 2 ++ src/components/home/HomeBanner.svelte | 12 +++++++++++- src/pages/[...locale]/index.astro | 9 ++++++++- src/repositories/banners.ts | 5 ++++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/home/HomeBanner.stories.svelte b/src/components/home/HomeBanner.stories.svelte index d8116a37..6d71aa1c 100644 --- a/src/components/home/HomeBanner.stories.svelte +++ b/src/components/home/HomeBanner.stories.svelte @@ -8,6 +8,7 @@ title: "Library/HomeBanner", tags: ["autodocs"], args: { + id: 1, title: "Discover the best campaigns", description: "Join thousands of investors and find the perfect opportunity for your portfolio.", @@ -23,6 +24,7 @@ + import { getCookie, setCookie } from "../../utils/cookies"; import Close from "../icons/navigation/Close.svelte"; import Button from "../library/buttons/Button.svelte"; import Title from "../library/typography/Title.svelte"; + const CLOSED_BANNERS_COOKIE = "goteo-banners-closed"; + interface Props { + id: number; title: string; description: string; ctaText: string; @@ -12,12 +16,18 @@ onClose?: () => void; } - let { title, description, ctaText, ctaLink, closeAriaLabel, onClose }: Props = $props(); + let { id, title, description, ctaText, ctaLink, closeAriaLabel, onClose }: Props = $props(); let visible = $state(true); function handleClose() { visible = false; + + const closed = (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); + if (!closed.includes(String(id))) { + setCookie(CLOSED_BANNERS_COOKIE, [...closed, id].join(",")); + } + if (onClose) onClose(); } diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index ab862fe4..01c24dea 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -23,7 +23,13 @@ if (locale && !isSupportedLocale(locale)) { const { t, lang } = Astro.locals; -const activeBanners = await bannerRepository.getActive(); +const closedBanners = (Astro.cookies.get("goteo-banners-closed")?.value ?? "") + .split(",") + .filter(Boolean); + +const activeBanners = (await bannerRepository.getActive()).filter( + (banner) => !closedBanners.includes(String(banner.id)), +); --- @@ -34,6 +40,7 @@ const activeBanners = await bannerRepository.getActive();
{activeBanners.map((banner) => ( { + public async create(banner: Omit): Promise> { const result = await this.db .prepare( `INSERT INTO banners (title, content, cta_text, cta_link, starts_at, ends_at, date_created) From 6f69605b4d30078bcb558f3b9eb66a0f917fb21e Mon Sep 17 00:00:00 2001 From: Pep Villalonga Date: Mon, 31 Aug 2026 13:10:37 +0200 Subject: [PATCH 07/20] fix: make banner close button circular --- src/components/home/HomeBanner.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/home/HomeBanner.svelte b/src/components/home/HomeBanner.svelte index 58aede36..4c497f95 100644 --- a/src/components/home/HomeBanner.svelte +++ b/src/components/home/HomeBanner.svelte @@ -77,7 +77,7 @@ From e5ca2683fff0a95d6092b8bfc8c0e67e0bc251d3 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Mon, 31 Aug 2026 23:15:49 +0200 Subject: [PATCH 08/20] fix: normalizer banner start/end dates --- .../admin/comm/banners/BannersForm.svelte | 21 ++++++++++++++----- src/utils/dates.ts | 21 +++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/components/admin/comm/banners/BannersForm.svelte b/src/components/admin/comm/banners/BannersForm.svelte index be60e5cd..d2000761 100644 --- a/src/components/admin/comm/banners/BannersForm.svelte +++ b/src/components/admin/comm/banners/BannersForm.svelte @@ -2,7 +2,7 @@ import { actions } from "astro:actions"; import { locale, t } from "../../../../i18n/store"; - import { formatDate } from "../../../../utils/dates"; + import { endOfDay, formatDate, startOfDay } from "../../../../utils/dates"; import ActionableButton from "../../../library/buttons/ActionableButton.svelte"; import DateInput from "../../../library/inputs/DateInput.svelte"; import TextArea from "../../../library/inputs/TextArea.svelte"; @@ -23,9 +23,20 @@ let fieldErrors: FieldErrors = $state({}); - function handleDateSelect(date: Date) { + function normalizeDate(field: "startsAt" | "endsAt", date: Date) { const now = new Date(); - date.setHours(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds()); + const isToday = + date.getFullYear() === now.getFullYear() && + date.getMonth() === now.getMonth() && + date.getDate() === now.getDate(); + + // Ends always run to the end of their day. Start dates run from their + // midnight, except when the day is today the current time is used so it + // passes the "no earlier than now" validation. DateInput binds the same + // object, so the normalized time is applied in place. + const normalized = field === "endsAt" ? endOfDay(date) : isToday ? now : startOfDay(date); + + date.setTime(normalized.getTime()); } async function submit() { @@ -110,7 +121,7 @@ placeholder={$t("pages.admin.comm.banners.fields.startDatePlaceholder")} error={fieldErrors.startsAt && $t(fieldErrors.startsAt, { date: formatDate(new Date(), $locale) })} - onInput={handleDateSelect} + onInput={(date) => normalizeDate("startsAt", date)} /> normalizeDate("endsAt", date)} />
diff --git a/src/utils/dates.ts b/src/utils/dates.ts index 7e17e017..b290015e 100644 --- a/src/utils/dates.ts +++ b/src/utils/dates.ts @@ -10,6 +10,27 @@ export function formatDate(date: Date, locale: Locale) { return date.toLocaleDateString(locale, options); } +/** + * The first instant of the day for the given date (midnight, 00:00). + * @param date The date to normalize + * @returns A new Date set to the start of the given day + */ +export function startOfDay(date: Date): Date { + return new Date(date.getFullYear(), date.getMonth(), date.getDate()); +} + +/** + * The last instant of the day for the given date (23:59:59.999). + * Derived from the start of the following day rather than hardcoding the end-of-day time. + * @param date The date to normalize + * @returns A new Date set to the end of the given day + */ +export function endOfDay(date: Date): Date { + // Start of the next day, minus a single millisecond + const nextDay = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1); + return new Date(nextDay.getTime() - 1); +} + /** * Get a date `n` ms from now * @param offset Milliseconds since now until future date From 916c81fefeea8cb59233b5e5543db0038abab304 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Mon, 31 Aug 2026 23:23:04 +0200 Subject: [PATCH 09/20] fix: date greaterThan key --- src/i18n/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 9556aaba..dc85c962 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -27,7 +27,7 @@ "expectedUrl": "No es una URL" }, "date": { - "greaterThan": "La fecha debe ser igual o mayor que el {{ date }}" + "greaterThan": "La fecha debe ser mayor que el {{ date }}" }, "file": { "maxAllowedSize": "Tamaño máximo permitido {{ size }}", From 4a4054d0af5daea55936717de72c5e49292b13c3 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Mon, 31 Aug 2026 23:40:03 +0200 Subject: [PATCH 10/20] extract HomeBanners --- src/components/home/HomeBanners.astro | 28 +++++++++++++++++++++++++++ src/pages/[...locale]/index.astro | 19 ++---------------- 2 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 src/components/home/HomeBanners.astro diff --git a/src/components/home/HomeBanners.astro b/src/components/home/HomeBanners.astro new file mode 100644 index 00000000..68eedb80 --- /dev/null +++ b/src/components/home/HomeBanners.astro @@ -0,0 +1,28 @@ +--- +import HomeBanner from "./HomeBanner.svelte"; +import type { BannerRecord } from "../../repositories/banners"; + +interface Props { + banners: BannerRecord[]; +} + +const { banners } = Astro.props; +const { t } = Astro.locals; +--- + +{ + banners.length > 0 && ( +
+ {banners.map((banner) => ( + + ))} +
+ ) +} diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index ab862fe4..85ee71c9 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -8,7 +8,7 @@ import Stats from "../../components/home/Stats.astro"; import FeaturedPromoters from "../../components/home/FeaturedPromoters.astro"; import Blog from "../../components/home/Blog.astro"; import Matchfunding from "../../components/home/Matchfunding.astro"; -import HomeBanner from "../../components/home/HomeBanner.svelte"; +import Banners from "../../components/home/HomeBanners.astro"; // Disabled sections, re-enable the import along with the component below: // import Stories from "../../components/home/Stories.svelte"; // import Resources from "../../components/home/Resources.astro"; @@ -29,22 +29,7 @@ const activeBanners = await bannerRepository.getActive(); - { - activeBanners.length > 0 && ( -
- {activeBanners.map((banner) => ( - - ))} -
- ) - } + From 1cb3bc408f0cb1ff9f2cd9dd3766a4dfe6d8eea9 Mon Sep 17 00:00:00 2001 From: Angel Di Pinto Date: Tue, 1 Sep 2026 13:12:38 +0200 Subject: [PATCH 11/20] refactor: convert HomeBanners to svelte --- src/components/home/HomeBanners.astro | 28 -------------------------- src/components/home/HomeBanners.svelte | 26 ++++++++++++++++++++++++ src/pages/[...locale]/index.astro | 4 ++-- 3 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 src/components/home/HomeBanners.astro create mode 100644 src/components/home/HomeBanners.svelte diff --git a/src/components/home/HomeBanners.astro b/src/components/home/HomeBanners.astro deleted file mode 100644 index 68eedb80..00000000 --- a/src/components/home/HomeBanners.astro +++ /dev/null @@ -1,28 +0,0 @@ ---- -import HomeBanner from "./HomeBanner.svelte"; -import type { BannerRecord } from "../../repositories/banners"; - -interface Props { - banners: BannerRecord[]; -} - -const { banners } = Astro.props; -const { t } = Astro.locals; ---- - -{ - banners.length > 0 && ( -
- {banners.map((banner) => ( - - ))} -
- ) -} diff --git a/src/components/home/HomeBanners.svelte b/src/components/home/HomeBanners.svelte new file mode 100644 index 00000000..6376e3a1 --- /dev/null +++ b/src/components/home/HomeBanners.svelte @@ -0,0 +1,26 @@ + + +{#if banners.length > 0} +
+ {#each banners as banner} + + {/each} +
+{/if} diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index 85ee71c9..2d91b411 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -8,7 +8,7 @@ import Stats from "../../components/home/Stats.astro"; import FeaturedPromoters from "../../components/home/FeaturedPromoters.astro"; import Blog from "../../components/home/Blog.astro"; import Matchfunding from "../../components/home/Matchfunding.astro"; -import Banners from "../../components/home/HomeBanners.astro"; +import Banners from "../../components/home/HomeBanners.svelte"; // Disabled sections, re-enable the import along with the component below: // import Stories from "../../components/home/Stories.svelte"; // import Resources from "../../components/home/Resources.astro"; @@ -29,7 +29,7 @@ const activeBanners = await bannerRepository.getActive(); - + From d5f7bd7e603cc62f27328b2880119fcf9c976293 Mon Sep 17 00:00:00 2001 From: OlivierSchulbaum Date: Tue, 1 Sep 2026 15:40:49 +0200 Subject: [PATCH 12/20] New translations es.json (Catalan) [ci skip] --- src/i18n/locales/ca.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/i18n/locales/ca.json b/src/i18n/locales/ca.json index 2e088f25..011b6ee0 100644 --- a/src/i18n/locales/ca.json +++ b/src/i18n/locales/ca.json @@ -1775,6 +1775,10 @@ "modal": { "title": "Anunci publicat el {{date}}", "description": "Aquí pots veure com era l'anunci" + }, + "deleteModal": { + "title": "Voleu suprimir aquest anunci?", + "description": "L'anunci se suprimirà permanentment i desapareixerà de l'historial. Aquesta acció no es pot desfer." } } } From e0e6940f5e2c3288a1e396bbc9c0687e4eb37027 Mon Sep 17 00:00:00 2001 From: OlivierSchulbaum Date: Tue, 1 Sep 2026 15:40:51 +0200 Subject: [PATCH 13/20] New translations es.json (English) [ci skip] --- src/i18n/locales/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 6ccbfebd..835bdbe5 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1775,6 +1775,10 @@ "modal": { "title": "Announcement published on {{date}}", "description": "Here you can see what the announcement looked like" + }, + "deleteModal": { + "title": "Delete this announcement?", + "description": "The announcement will be permanently deleted and disappear from the history. This action cannot be undone." } } } From f8b46471981f658c07e93609b76c487b73ebec02 Mon Sep 17 00:00:00 2001 From: Pep Villalonga Date: Wed, 2 Sep 2026 13:57:55 +0200 Subject: [PATCH 14/20] fix: restore banner dismissal in HomeBanners --- src/components/home/HomeBanner.svelte | 11 +++++++---- src/components/home/HomeBanners.svelte | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/home/HomeBanner.svelte b/src/components/home/HomeBanner.svelte index 4c497f95..80d4c0be 100644 --- a/src/components/home/HomeBanner.svelte +++ b/src/components/home/HomeBanner.svelte @@ -7,7 +7,8 @@ const CLOSED_BANNERS_COOKIE = "goteo-banners-closed"; interface Props { - id: number; + /** Omit to render a throwaway preview: closing it won't persist a dismissal. */ + id?: number; title: string; description: string; ctaText: string; @@ -23,9 +24,11 @@ function handleClose() { visible = false; - const closed = (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); - if (!closed.includes(String(id))) { - setCookie(CLOSED_BANNERS_COOKIE, [...closed, id].join(",")); + if (id !== undefined) { + const closed = (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); + if (!closed.includes(String(id))) { + setCookie(CLOSED_BANNERS_COOKIE, [...closed, id].join(",")); + } } if (onClose) onClose(); diff --git a/src/components/home/HomeBanners.svelte b/src/components/home/HomeBanners.svelte index 6376e3a1..08351b53 100644 --- a/src/components/home/HomeBanners.svelte +++ b/src/components/home/HomeBanners.svelte @@ -13,8 +13,9 @@ {#if banners.length > 0}
- {#each banners as banner} + {#each banners as banner (banner.id)} Date: Thu, 3 Sep 2026 11:02:19 +0200 Subject: [PATCH 15/20] fix: solve PR mistakes --- src/components/home/HomeBanner.stories.svelte | 2 -- src/components/home/HomeBanner.svelte | 17 ++----------- src/components/home/HomeBanners.svelte | 24 ++++++++++++++++--- src/pages/[...locale]/index.astro | 8 +------ 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/components/home/HomeBanner.stories.svelte b/src/components/home/HomeBanner.stories.svelte index 6d71aa1c..d8116a37 100644 --- a/src/components/home/HomeBanner.stories.svelte +++ b/src/components/home/HomeBanner.stories.svelte @@ -8,7 +8,6 @@ title: "Library/HomeBanner", tags: ["autodocs"], args: { - id: 1, title: "Discover the best campaigns", description: "Join thousands of investors and find the perfect opportunity for your portfolio.", @@ -24,7 +23,6 @@ - import { getCookie, setCookie } from "../../utils/cookies"; import Close from "../icons/navigation/Close.svelte"; import Button from "../library/buttons/Button.svelte"; import Title from "../library/typography/Title.svelte"; - const CLOSED_BANNERS_COOKIE = "goteo-banners-closed"; - interface Props { - /** Omit to render a throwaway preview: closing it won't persist a dismissal. */ - id?: number; title: string; description: string; ctaText: string; @@ -17,21 +12,13 @@ onClose?: () => void; } - let { id, title, description, ctaText, ctaLink, closeAriaLabel, onClose }: Props = $props(); + let { title, description, ctaText, ctaLink, closeAriaLabel, onClose }: Props = $props(); let visible = $state(true); function handleClose() { visible = false; - - if (id !== undefined) { - const closed = (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); - if (!closed.includes(String(id))) { - setCookie(CLOSED_BANNERS_COOKIE, [...closed, id].join(",")); - } - } - - if (onClose) onClose(); + onClose?.(); } diff --git a/src/components/home/HomeBanners.svelte b/src/components/home/HomeBanners.svelte index 08351b53..75d73d3e 100644 --- a/src/components/home/HomeBanners.svelte +++ b/src/components/home/HomeBanners.svelte @@ -1,26 +1,44 @@ -{#if banners.length > 0} +{#if visibleBanners.length > 0}
- {#each banners as banner (banner.id)} + {#each visibleBanners as banner (banner.id)} handleClose(banner.id)} /> {/each}
diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index ace5ab63..2d91b411 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -23,13 +23,7 @@ if (locale && !isSupportedLocale(locale)) { const { t, lang } = Astro.locals; -const closedBanners = (Astro.cookies.get("goteo-banners-closed")?.value ?? "") - .split(",") - .filter(Boolean); - -const activeBanners = (await bannerRepository.getActive()).filter( - (banner) => !closedBanners.includes(String(banner.id)), -); +const activeBanners = await bannerRepository.getActive(); --- From 8b8774707f23fff3fdc75de14ce7df435241ac33 Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Thu, 3 Sep 2026 12:08:22 +0200 Subject: [PATCH 16/20] fix: remove console logs on banners repo --- src/repositories/banners.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/repositories/banners.ts b/src/repositories/banners.ts index f9ac5ef9..a18e0537 100644 --- a/src/repositories/banners.ts +++ b/src/repositories/banners.ts @@ -36,8 +36,6 @@ class BannerRepository { .all() .then((data) => data.results.map((r) => { - console.log(r); - return { ...r, startsAt: new Date(r.startsAt), @@ -94,8 +92,6 @@ class BannerRepository { ) .run(); - console.log(result); - return banner; } } From f64d5a7fdea2ef9913819a6a3a67f038d7274a8d Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Thu, 3 Sep 2026 12:11:58 +0200 Subject: [PATCH 17/20] fix: no-op of date normalization previous to action call --- .../admin/comm/banners/BannersForm.svelte | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/admin/comm/banners/BannersForm.svelte b/src/components/admin/comm/banners/BannersForm.svelte index d2000761..4aabdcb2 100644 --- a/src/components/admin/comm/banners/BannersForm.svelte +++ b/src/components/admin/comm/banners/BannersForm.svelte @@ -23,7 +23,15 @@ let fieldErrors: FieldErrors = $state({}); - function normalizeDate(field: "startsAt" | "endsAt", date: Date) { + let startsAt = $state(new Date()); + let endsAt = $state(new Date()); + + /** + * Normalize a date field to the human expected true datetime + * @param field + * @param date + */ + function normalizeDate(field: "startsAt" | "endsAt", date: Date): Date { const now = new Date(); const isToday = date.getFullYear() === now.getFullYear() && @@ -37,6 +45,8 @@ const normalized = field === "endsAt" ? endOfDay(date) : isToday ? now : startOfDay(date); date.setTime(normalized.getTime()); + + return date; } async function submit() { @@ -116,21 +126,23 @@
normalizeDate("startsAt", date)} + onInput={(date) => (startsAt = normalizeDate("startsAt", date))} /> normalizeDate("endsAt", date)} + onInput={(date) => (endsAt = normalizeDate("endsAt", date))} />
From d5eb97e840af852a94f2b1fb102700d43dd501cc Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Thu, 3 Sep 2026 12:15:00 +0200 Subject: [PATCH 18/20] feat: get closed banners as soon as component loads client-side --- src/components/home/HomeBanners.svelte | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/home/HomeBanners.svelte b/src/components/home/HomeBanners.svelte index 75d73d3e..bdd5ab18 100644 --- a/src/components/home/HomeBanners.svelte +++ b/src/components/home/HomeBanners.svelte @@ -4,6 +4,7 @@ import { getCookie, setCookie } from "../../utils/cookies"; import type { BannerRecord } from "../../repositories/banners"; + import { onMount } from "svelte"; const CLOSED_BANNERS_COOKIE = "goteo-banners-closed"; @@ -15,8 +16,16 @@ let closed = $state([]); + function getClosed() { + return (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); + } + + onMount(() => { + closed = getClosed(); + }) + $effect(() => { - closed = (getCookie(CLOSED_BANNERS_COOKIE) ?? "").split(",").filter(Boolean); + closed = getClosed(); }); let visibleBanners = $derived(banners.filter((banner) => !closed.includes(String(banner.id)))); From 09dcefddc6f5434b97223add7d20f70b2f94afb2 Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Thu, 3 Sep 2026 12:59:40 +0200 Subject: [PATCH 19/20] fix: code style issues by prettier --- src/components/home/HomeBanners.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/home/HomeBanners.svelte b/src/components/home/HomeBanners.svelte index bdd5ab18..d34d0d2a 100644 --- a/src/components/home/HomeBanners.svelte +++ b/src/components/home/HomeBanners.svelte @@ -1,10 +1,11 @@