From b8048d24f680492da37a93b686ca2df1790cbe0e Mon Sep 17 00:00:00 2001 From: isUnknown Date: Tue, 21 Apr 2026 16:27:30 +0200 Subject: [PATCH] =?UTF-8?q?Jauge=20offset=2062,=20onglet=20mensuel=20renom?= =?UTF-8?q?m=C3=A9,=20d=C3=A9duction=2066%=20sur=20boutons=20libres,=20cha?= =?UTF-8?q?mps=20label=20noir/vert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 52 +++++++++++++++++++++++++++++++++++++ assets/js/donation.js | 10 +++++++ assets/js/donorbox-gauge.js | 2 +- en/index.php | 4 +-- index.php | 6 ++--- 5 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..32b16e7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,52 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project overview + +Static PHP site for the Index NGO donation/support campaign (`soutenir.index.ngo`). No build step — PHP files are served directly. The site has two language versions: French (`index.php`) and English (`en/index.php`). + +## Architecture + +### Content flow + +All editorial content is managed via a **Kirby CMS** running in a separate repo (`/Users/adrienpayet/Documents/code/en-cours/index/main/`). The static site fetches content from the Kirby API and caches it locally: + +``` +Kirby CMS (main repo) → /support-content?lang=fr → includes/cache.php → index.php +``` + +- **`includes/config.php`** — API URL, token, cache TTL constants +- **`includes/cache.php`** — `getContent(lang)` function: serves cache if fresh (<5 min), otherwise fetches from Kirby API via curl, falls back to stale cache +- **`cache/`** — stores `content.fr.json` and `content.en.json` + +### Kirby backend (separate repo) + +- **Blueprint**: `/Users/adrienpayet/Documents/code/en-cours/index/main/site/blueprints/pages/support.yml` — defines all editable fields for the support page +- **API route**: `/Users/adrienpayet/Documents/code/en-cours/index/main/site/config/routes/support-content.php` — builds and returns the JSON response consumed by this site; uses `->inline()` on writer fields + +When adding a new dynamic field: add it to the blueprint, expose it in the API route, then consume `$data['fieldName']` in the PHP templates. + +### Donation gauge + +- **`api/donorbox-proxy.php`** — server-side proxy to Donorbox API (Basic Auth). Paginates through all active plans to get `recurring_donors_count`. Caches result in `api/cache/donorbox_data.json` (5 min). +- **`assets/js/donorbox-gauge.js`** — calls the proxy, adds `RECURRING_DONORS_OFFSET` to the real count, updates the gauge CSS variable `--pourcent` and the displayed number. Also sets up 5-minute auto-refresh. + +`RECURRING_DONORS_OFFSET` is defined at the top of `donorbox-gauge.js` and represents historic/offline supporters added to the live Donorbox count. + +### Donation pad + +**`assets/js/donation.js`** — IIFE that: +- Dynamically generates all donation buttons (amounts, after-tax calculations) on `DOMContentLoaded` +- Contains `TRANSLATIONS` object for FR/EN static strings in the donation pad +- Generates Donorbox redirect URLs with UTM passthrough +- Handles monthly/one-off tab switching + +Static strings in the donation pad (e.g. "Avec déduction fiscale de 66 %") live in the `TRANSLATIONS` object in this file, not in Kirby. + +## Key conventions + +- **Writer fields in Kirby**: use `->inline()` in the API route to get inline HTML without block wrappers. For multiline text (e.g. a title with a `
`), use a `writer` field with `nodes: false` and `buttons: false` — this preserves line breaks. In the API route, use `->inline()` which converts newlines to `
` tags; do **not** use `nl2br()`. +- **`heroHeading` field**: rendered with `` (no `htmlspecialchars`) because it contains trusted HTML from the writer field. +- **Language**: `document.documentElement.lang` drives JS translations. FR page sets `lang="fr"`, EN page sets `lang="en"`. +- **Cache invalidation**: delete files in `cache/` to force a fresh fetch from Kirby. diff --git a/assets/js/donation.js b/assets/js/donation.js index f5c335c..bee9cdb 100644 --- a/assets/js/donation.js +++ b/assets/js/donation.js @@ -14,11 +14,13 @@ afterTax: 'Soit {amount} € après impôts', perMonth: '€/mois', withTaxReduction: 'Avec 66 % de déduction fiscale', + chooseAmount: 'Choisissez votre montant', }, en: { afterTax: 'That is {amount} € after tax', perMonth: '€/month', withTaxReduction: 'With 66 % tax deduction', + chooseAmount: 'Choose your amount', }, }; @@ -115,6 +117,10 @@ window.open(generateDonorboxUrl(amount, false), '_blank'); }); } else { + button.innerHTML = ` +

${translate('chooseAmount')}

+

${translate('withTaxReduction')}

+ `; button.addEventListener('click', () => { window.open(generateDonorboxUrl(null, false), '_blank'); }); @@ -144,6 +150,10 @@ window.open(generateDonorboxUrl(amount, true), '_blank'); }); } else { + button.innerHTML = ` +

${translate('chooseAmount')}

+

${translate('withTaxReduction')}

+ `; button.addEventListener('click', () => { window.open(generateDonorboxUrl(null, true), '_blank'); }); diff --git a/assets/js/donorbox-gauge.js b/assets/js/donorbox-gauge.js index fde403a..5fe2373 100644 --- a/assets/js/donorbox-gauge.js +++ b/assets/js/donorbox-gauge.js @@ -2,7 +2,7 @@ const DONORBOX_CONFIG = { proxyUrl: '/api/donorbox-proxy.php', }; -const RECURRING_DONORS_OFFSET = 98; +const RECURRING_DONORS_OFFSET = 62; const GOAL_SUPPORTERS = 500; async function fetchDonorboxData() { diff --git a/en/index.php b/en/index.php index 6f24182..38fd841 100644 --- a/en/index.php +++ b/en/index.php @@ -70,8 +70,8 @@ $data = getContent('en');

- -
+ +

diff --git a/index.php b/index.php index e043712..18d2da5 100644 --- a/index.php +++ b/index.php @@ -70,8 +70,8 @@ $data = getContent('fr');

- -
+ +

@@ -131,7 +131,7 @@ $data = getContent('fr');