Commit Graph
835 Commits
Author SHA1 Message Date
Paul Nothaft d04bf28808 Merge pull request #390 from Luca-Timo/feat/self-hosted-fonts
feat(branding): self-hosted webfonts with filesystem scanner
2026-05-04 23:23:04 +02:00
Luca b609a7a88c test(fonts): unit-test scanner edge cases and meta.json handling 2026-05-04 22:29:57 +02:00
Luca bd0e052b1a docs(fonts): cache rollout, stale-list note, meta.json 2026-05-04 22:28:41 +02:00
Luca 5703fcb806 fix(fonts): drop immutable Cache-Control to allow font replacement rollout 2026-05-04 22:28:17 +02:00
Luca dcff451572 feat(branding): per-family generic fallback via meta.json 2026-05-04 22:27:52 +02:00
Paul Nothaft e382aed4d1 Merge pull request #394 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 5m56s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m34s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.39.1-beta.0
v3.39.1-beta.0
2026-05-04 22:18:29 +02:00
github-actions[bot] ac05230867 chore(beta): release 3.39.1-beta.0 2026-05-04 19:37:59 +00:00
Paul Nothaft c60ab74ae2 Merge pull request #393 from the-luap/docs/contributors
docs(readme): add Contributors section with @Luca-Timo and @Rekoo-PS
2026-05-04 21:37:37 +02:00
Paul Nothaft dbe0a3055b docs(readme): add Contributors section with @Luca-Timo and @Rekoo-PS
The Acknowledgments block had a generic "thanks to all contributors"
line but no actual recognition by name. Two people in particular have
moved the project meaningfully forward and should be called out:

- @Luca-Timo — code contributor across multi-arch Docker, the external-
  URL CMS toggle, folder tree picker, admin email picker, self-hosted
  webfonts, the gallery header/banner decoupling, and typed-API
  refactors. Consistent quality.

- @Rekoo-PS — bug reporter and feedback loop. Filed the issues that
  drove the login-loop fix, gallery loading skeleton, redirection
  cleanup, mobile lightbox overhaul, admin events search-counter fix,
  photo-count column, and bulk-delete workflow. Also a BuyMeACoffee
  supporter.

Closes the implicit recognition gap and sets up the section so future
contributors can be added with a one-line PR.
2026-05-04 21:35:27 +02:00
Paul Nothaft 99392c5888 Merge pull request #392 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 6m9s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m40s
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
chore(beta): release 3.39.0-beta.0
v3.39.0-beta.0
2026-05-04 21:28:06 +02:00
github-actions[bot] 6fe1d8de9e chore(beta): release 3.39.0-beta.0 2026-05-04 19:16:41 +00:00
Paul Nothaft 1f1a856083 Merge pull request #385 from Luca-Timo/beta
feat(gallery): decouple header style from layout, add banner option
2026-05-04 21:16:13 +02:00
Paul Nothaft d0d283a13e Merge pull request #391 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 6m30s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m39s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.38.0-beta.0
v3.38.0-beta.0
2026-05-04 21:01:06 +02:00
github-actions[bot] 0a48646529 chore(beta): release 3.38.0-beta.0 2026-05-04 19:00:37 +00:00
Paul Nothaft 647aea21ae Merge pull request #389 from the-luap/feat/events-bulk-delete
feat(events): bulk delete with password confirmation (#384)
2026-05-04 21:00:06 +02:00
Paul Nothaft 7491eb21c4 Merge pull request #388 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 6m28s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 7m35s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.37.0-beta.0
v3.37.0-beta.0
2026-05-04 20:59:53 +02:00
Paul Nothaft 48d538f94f feat(events): bulk delete with password confirmation (#384)
Adds the bulk-delete half of #384 — admins can select multiple
events from the list and delete them in one batch, gated by
re-entering their password.

## Why password confirmation

Bulk delete is destructive and irreversible (cascades across 5 DB
tables and 3 filesystem paths per event). Re-entering the password
matches the pattern already used by /auth/admin/change-password and
makes accidental clicks much harder than a plain "type DELETE to
confirm" — the muscle-memory required to type your real password is
a stronger gate than typing a literal word.

## Changes

### Backend (adminEvents.js)

- Extracted the per-event cascade-delete logic into a module-private
  `deleteEventCascade(eventId, adminContext)` helper. The DELETE /:id
  route now calls it instead of inlining 60 lines of cascade — same
  behaviour, no drift between the per-event and bulk paths.
- New `POST /admin/events/bulk-delete`. Body: `{ eventIds, password }`.
  Permission: `events.delete`.
  - Validates `eventIds` array length (1–100) and that each id is an
    integer. The 100-cap keeps request time bounded; the per-event
    cascade touches DB + filesystem so 1000 events at once would risk
    timing out the request.
  - Verifies `password` against the calling admin's bcrypt hash via
    `bcrypt.compare()` (same as /auth/admin/change-password). Wrong
    password → 401 `{ error, code: 'INVALID_PASSWORD' }` and no
    events are touched.
  - Loops via `deleteEventCascade`, returns
    `{ results: { successful, failed } }` with the same shape as
    /bulk-archive so the frontend can show partial-failure feedback.
  - Logs `bulk_delete_completed` activity with totals.

### Frontend

- `events.service.ts`: `bulkDeleteEvents(eventIds, password)`.
- New `BulkDeleteModal.tsx`. Red/destructive variant of the
  bulk-archive modal:
  - Lists the events to be deleted (so the admin can verify).
  - Password input with show/hide toggle, autofocus, Enter-to-submit.
  - Inline `passwordError` prop surfaces the 401 INVALID_PASSWORD
    response without losing the modal state — admin can retry
    without re-typing the event list.
  - "Processing" state replaces the form with a spinner + "Deleting
    N events. This may take a few minutes — please don't close this
    window." (i18n) so admins know not to abandon the page during
    a slow operation.
- `EventsListPage.tsx`: "Delete Selected" button next to "Archive
  Selected" in the bulk-actions bar (red-styled to signal danger),
  bulkDeleteMutation that maps the 401 to the modal's inline error
  and any other failure to a generic toast.

### i18n

12 new keys under `events.bulkDelete.*` in all 5 locales
(en/de/nl/pt/ru): title, warning, password label/placeholder/help,
submit, processing, incorrectPassword, successAll, successPartial,
errorGeneric, plus `events.deleteSelected` for the button. Hand-
written for de; nl/pt/ru should get a native-speaker pass at some
point but read naturally.

### Verified

- `npx tsc --noEmit` clean
- `npx eslint` clean on every touched file (4 pre-existing errors in
  adminEvents.js for unused vars unrelated to this PR)
- All 5 locale JSON files parse cleanly
- `node -e "require('./src/routes/adminEvents')"` loads the module

Closes the bulk-delete half of #384. The Photos-column half lands
separately in PR #387.
2026-05-04 20:56:00 +02:00
github-actions[bot] 67999999d8 chore(beta): release 3.37.0-beta.0 2026-05-04 18:52:09 +00:00
Paul Nothaft d561db802b Merge pull request #387 from the-luap/feat/events-photos-column
feat(events): add Photos column to admin events list (#384)
2026-05-04 20:51:44 +02:00
Paul Nothaft ffb4318a1f feat(events): add Photos column to admin events list (#384)
The admin events table didn't surface how many photos each event
contained — admins had to click into the event to find out. The
backend already computes `photo_count` for every row in the
GET /admin/events list response (adminEvents.js:794-796), so this
is a frontend-only display change.

- Insert a "Photos" column between Date and Status — groups with
  the "what's in this event" info.
- Right-aligned, tabular-nums for clean numeric alignment in the
  column.
- Reuses the existing `events.photos` i18n key already shipped in
  all 5 locales for the EventDetailsPage tab list ("Fotos" / etc.) —
  no new translations needed.
- Updates the empty-state colSpan from 7 to 8.

Closes the column-add half of #384. The bulk-delete request from
the same issue lands separately.
2026-05-04 20:47:13 +02:00
Luca f410207b2d revert(branding): per-option font preview (defer to follow-up) 2026-05-04 20:39:00 +02:00
Luca e6c03e4b6e fix(nginx): proxy /fonts requests to backend 2026-05-04 20:07:13 +02:00
Luca b4f9b65f1d feat(branding): preview each font in its own face in the picker dropdown 2026-05-04 19:44:20 +02:00
Luca bac51fe69a feat(branding): self-hosted webfonts with filesystem scanner 2026-05-04 19:15:47 +02:00
Luca 894e151255 i18n(gallery): nl/ru wording polish for standard header style 2026-05-04 16:58:26 +02:00
Luca 05dadff493 fix(gallery): preserve sidebar controlsStyle on banner migration 2026-05-04 16:58:17 +02:00
Luca 91ad6bba99 style(theme-customizer): match header-style picker grid to layout picker (3 cols) 2026-05-04 15:48:12 +02:00
Luca 045e9ea486 fix(gallery): default controls to inline for every layout 2026-05-04 15:46:41 +02:00
Luca 24d727752c Merge pull request #1 from Luca-Timo/feat/decouple-gallery-header
feat(gallery): decouple header style from layout, add banner option
2026-05-04 15:30:52 +02:00
Paul Nothaft 0adec25fe7 Merge pull request #382 from Luca-Timo/refactor/external-media-types
refactor(events): type external-media list response, drop any casts
2026-05-04 14:46:35 +02:00
Luca d823dcda26 Merge branch 'beta' into refactor/external-media-types 2026-05-04 14:40:01 +02:00
Luca 0bd61be5a6 i18n(gallery): translate banner header strings (nl/pt/ru) 2026-05-04 14:34:55 +02:00
Luca aff29c91bb feat(gallery): decouple header style from layout, add banner option 2026-05-04 14:34:42 +02:00
Paul Nothaft 4d99eb672d Merge pull request #383 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 6m15s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m31s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.36.0-beta.0
v3.36.0-beta.0
2026-05-04 13:44:35 +02:00
github-actions[bot] 66281f9790 chore(beta): release 3.36.0-beta.0 2026-05-04 11:33:17 +00:00
Paul Nothaft 3fe8e61bd1 Merge pull request #379 from Luca-Timo/feat/admin-email-picker
feat(events): prefill admin email + admin picker on event creation
2026-05-04 13:32:53 +02:00
Paul Nothaft 06f2b75ec3 Merge pull request #381 from the-luap/chore/external-folder-picker-types
chore(events): type FolderTreeNode entries with ExternalEntry
2026-05-04 13:31:11 +02:00
Luca ffbb0e659f refactor(events): type external-media list response, drop any casts 2026-05-04 12:28:46 +02:00
Paul Nothaft 98c6f6cf06 chore(events): type FolderTreeNode entries with ExternalEntry
Follow-up to PR #378 — drops the (e: any) / (d: any) casts in the
external-folder-tree picker. ExternalEntry is already exported from
externalMedia.service.ts; the call site just wasn't using it.

- Import the type alongside the service.
- Annotate the dirs filter callback so `e.type` is the union 'dir' |
  'file' instead of any.
- Drop the (d: any) annotation from the map — TypeScript infers
  ExternalEntry from the typed `dirs` array.

No behaviour change, no test impact. `npx tsc --noEmit` clean,
`npx eslint` clean.
2026-05-04 12:24:21 +02:00
Paul Nothaft bfd7169fc4 Merge pull request #380 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 5m41s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m35s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.35.0-beta.0
v3.35.0-beta.0
2026-05-04 12:21:35 +02:00
github-actions[bot] 7e4f1acb88 chore(beta): release 3.35.0-beta.0 2026-05-04 10:21:13 +00:00
Paul Nothaft cdd40acb45 Merge pull request #378 from Luca-Timo/beta
feat(events): tree view for external media folder picker
2026-05-04 12:20:54 +02:00
Luca 40d23e24cb i18n(events): translate admin email picker strings (nl/pt/ru) 2026-05-04 12:10:23 +02:00
Luca ee56b6762f feat(events): prefill admin email + admin picker on event creation 2026-05-04 12:10:23 +02:00
Luca bd42ee1ce0 fix(events): match scrollbar to theme in external folder tree picker 2026-05-04 11:30:46 +02:00
Luca 954ab00495 i18n(events): translate external folder picker strings (nl/pt/ru) 2026-05-04 11:02:00 +02:00
Luca f927b09c70 feat(events): tree view for external media folder picker 2026-05-04 11:01:49 +02:00
Paul Nothaft 048870804f Merge pull request #377 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (linux/amd64, ubuntu-latest) (push) Failing after 5m54s
Build and Push Docker Images / build-frontend (linux/amd64, ubuntu-latest) (push) Failing after 6m42s
Build and Push Docker Images / build-backend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build and Push Docker Images / merge-frontend (push) Has been cancelled
Build and Push Docker Images / summary (push) Has been cancelled
chore(beta): release 3.34.2-beta.0
v3.34.2-beta.0
2026-05-04 09:15:29 +02:00
github-actions[bot] 13e3a05386 chore(beta): release 3.34.2-beta.0 2026-05-04 07:14:40 +00:00
Paul Nothaft 3ab8a64a24 Merge pull request #376 from the-luap/fix/ffmpeg-on-alpine
fix(docker): install system ffmpeg on Alpine, drop broken bundled binary
2026-05-04 09:14:16 +02:00