Commit Graph

297 Commits

Author SHA1 Message Date
52ae9659b8 angelus: align styling with other faith routes
All checks were successful
CI / update (push) Successful in 1m22s
2026-02-02 23:13:02 +01:00
58a0496ff3 rosary: add missing saint Michael prayer
All checks were successful
CI / update (push) Successful in 1m22s
2026-02-02 23:08:20 +01:00
0d2e33d84d angelus: add missing Ave Maria
All checks were successful
CI / update (push) Successful in 1m23s
2026-02-02 22:59:11 +01:00
b94a6bbb87 prayers: add angelus link
All checks were successful
CI / update (push) Successful in 1m22s
2026-02-02 22:51:51 +01:00
660a1b0539 prayers: add search and individual prayer pages
All checks were successful
CI / update (push) Successful in 1m22s
- Add SearchInput component for reusable search UI
- Add search functionality to prayers list with two-tier results:
  - Primary matches (name/searchTerms) shown first
  - Secondary matches (text content) shown after with reduced opacity
- Add individual prayer pages with language-appropriate slugs
  (e.g., /glaube/gebete/ave-maria, /faith/prayers/hail-mary)
- Make prayer cards clickable to navigate to individual pages
- Fix language visibility for prayers without Latin (BruderKlaus, Joseph)
- Add Prayer wrapper to MichaelGebet for consistent styling
- Use CSS columns for masonry layout with dynamic reordering
2026-02-02 22:22:56 +01:00
8699bef209 move glaube higher up in main LinksGrid
All checks were successful
CI / update (push) Successful in 1m21s
2026-02-02 20:47:10 +01:00
95d3be8b82 prayers: bow-emphasis only for main language 2026-02-02 20:39:11 +01:00
82db2c9e50 angelus: cleaner and now in Header
All checks were successful
CI / update (push) Successful in 1m25s
2026-02-02 16:59:25 +01:00
69293c39f9 prayers: add English translations for all prayer components
Add official Catholic English translations to all prayer components
for /faith/* routes. Prayer names on /faith/prayers are now displayed
in English. Remove unused Angelus.svelte component.
2026-02-02 16:39:40 +01:00
1a5117e8d0 faith: add bilingual routes /glaube ↔ /faith
Add language toggle support for faith pages similar to recipes.
Routes now work in both German and English:
- /glaube ↔ /faith
- /glaube/gebete ↔ /faith/prayers
- /glaube/rosenkranz ↔ /faith/rosary
- /glaube/angelus ↔ /faith/angelus
2026-02-02 16:15:51 +01:00
924ce386d5 rosary: server-side streak fetch, remove aggressive polling
All checks were successful
CI / update (push) Successful in 1m29s
- Fetch streak data in +page.server.ts for logged-in users via API
- Initialize store once with server data, sync only runs once
- Only poll for reconnection in PWA mode when offline with pending changes
- Extract FireEffect to separate component with burst animation
- Convert StreakAura/StreakCounter to Svelte 5 runes ($props, $state, $derived)
- Fix SSR flash by using server data for initial render
2026-02-01 13:50:33 +01:00
01fd067eda rosary: cleaner light mode
All checks were successful
CI / update (push) Successful in 1m20s
2026-01-31 16:12:18 +01:00
58fd2b89d2 rosary: fade-in shadow removed
All checks were successful
CI / update (push) Successful in 1m21s
2026-01-31 15:53:59 +01:00
17b0fb9275 remove jukit garbage 2026-01-31 10:12:45 +01:00
45b0f5f2a6 rosary: less colourful mystery selector
All checks were successful
CI / update (push) Successful in 1m28s
2026-01-30 15:47:58 +01:00
7f4a8eec8b rosary: cleanup
All checks were successful
CI / update (push) Successful in 1m28s
2026-01-30 15:36:13 +01:00
daa801e14a fix logged in state broken on rosary due to prerendering
All checks were successful
CI / update (push) Successful in 1m21s
2026-01-30 12:47:28 +01:00
a58e52c891 feat: add server persistence for rosary streak
All checks were successful
CI / update (push) Successful in 1m21s
- Add RosaryStreak MongoDB model for logged-in users
- Add /api/glaube/rosary-streak GET/POST endpoints
- Sync streak to server when logged in, merge local/server data
- Auto-sync when coming back online (PWA offline support)
- Falls back to localStorage for guests
2026-01-30 12:37:01 +01:00
06477d656a feat: add streak counter to rosary page
Track daily rosary prayer streaks using localStorage. Shows consecutive
days prayed and disables button if already prayed today.
2026-01-30 12:36:55 +01:00
bff86041fd prayers: add Confiteor
All checks were successful
CI / update (push) Successful in 1m24s
2026-01-30 08:40:29 +01:00
53ad393541 refactor: reduce all_brief payload to first image's alt and mediapath
All checks were successful
CI / update (push) Successful in 1m20s
Only include the necessary image fields for Card.svelte instead of
the entire images array to reduce API response size.
2026-01-29 14:22:57 +01:00
308d9c6dac fix: include images in all_brief API endpoints
All checks were successful
CI / update (push) Successful in 1m23s
Card.svelte uses recipe.images[0].mediapath for the hashed image path,
but the all_brief endpoints weren't fetching the images field, causing
new recipes to fall back to short_name.webp instead of the correct path.
2026-01-29 13:40:33 +01:00
763edb35c3 fix: include images and translations in offline-db brief recipes
All checks were successful
CI / update (push) Successful in 1m26s
The offline sync wasn't caching thumbnails because the images field
was missing from the MongoDB projection. Also add translations for
caching English recipe __data.json URLs.
2026-01-29 10:18:23 +01:00
c86a734da0 feat: extend PWA offline support to all recipe routes and glaube pages
- Add offline support for category, tag, icon list pages
- Add offline support for favorites page (stores locally for offline)
- Add offline support for season list page
- Cache root page and glaube pages for offline access
- Dynamically discover glaube routes at build time using Vite glob
- Add db functions for getAllCategories, getAllTags, getAllIcons
- Pre-cache __data.json for all category, tag, icon, season subroutes
- Update service worker to cache glaube and root page responses
2026-01-29 09:57:58 +01:00
9ff30b28cd feat: add PWA offline support for recipe pages
- Add service worker with caching for build assets, static files, images, and pages
- Add IndexedDB storage for recipes (brief and full data)
- Add offline-db API endpoint for bulk recipe download
- Add offline sync button component in header
- Add offline-shell page for direct navigation fallback
- Pre-cache __data.json for client-side navigation
- Add +page.ts universal load functions with IndexedDB fallback
- Add PWA manifest and icons for installability
- Update recipe page to handle missing data gracefully
2026-01-28 21:38:33 +01:00
ee2aff46a1 perf: preload crosses font on glaube pages
All checks were successful
CI / update (push) Successful in 1m29s
Add preload hint to fetch the crosses.woff2 font early,
improving First Contentful Paint on /glaube routes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 10:35:04 +01:00
3cc962f454 refactor: reduce DOM nesting and simplify templates
- Remove nested .wrapper div in recipe page using CSS Grid with full-bleed background
- Consolidate multiplier forms in IngredientsPage into single form
- Simplify fermentation conditionals in InstructionsPage with optional chaining
- Use conditional rendering instead of visibility wrapper in Search
- Remove unnecessary dialog wrapper in TitleImgParallax
2026-01-25 20:24:48 +01:00
5824993b18 refactor: simplify Card HTML and extract search filter composable
All checks were successful
CI / update (push) Successful in 1m23s
- Remove unnecessary wrapper divs in Card component (.card_anchor, .div_div_image)
- Flatten Card HTML from 4 levels to 2 levels of nesting
- Create reusable createSearchFilter composable in $lib/js/searchFilter.svelte.ts
- Apply search filter composable to category, tag, and favorites pages
2026-01-25 14:48:55 +01:00
63e9b3de21 Move more CSS styling to a global css files to reduce bundle size
All checks were successful
CI / update (push) Successful in 2m53s
2026-01-23 15:37:32 +01:00
f3b92e8b1a refactor: clean up recipe routes and reduce bundle size
- Eliminate duplicate API fetch in recipe page by passing item from
  server load to universal load instead of fetching twice
- Replace cheerio with simple regex in stripHtmlTags, removing ~200KB
  dependency
- Refactor multiplier buttons in IngredientsPage to use loop instead
  of 5 repeated form elements
- Move /rezepte/untranslated to /[recipeLang]/admin/untranslated and
  delete legacy /rezepte/ layout files
2026-01-23 15:04:58 +01:00
ab2a6c9158 feat: add page titles to recipe and glaube routes
All checks were successful
CI / update (push) Successful in 1m20s
- Add titles to category, tag, icon, season routes
- Add bilingual support (German/English) for recipe route titles
- Use consistent "Bocken Recipes" / "Bocken Rezepte" branding
- Change English tagline from "Bocken's Recipes" to "Bocken Recipes"
- Add titles to /glaube and /glaube/gebete pages
- Make tips-and-tricks page language-aware
2026-01-20 19:54:33 +01:00
e366b44bba fix: include server load data in universal load for recipe page title
The +page.server.ts fetches recipe data and strips HTML tags server-side
to avoid bundling cheerio in the client. However, the universal load in
+page.ts wasn't including this data in its return value.

Fixed by:
1. Having +page.server.ts fetch the recipe directly (since it runs before
   +page.ts and can't access its data via parent())
2. Adding the `data` parameter to +page.ts and spreading it in the return

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 19:44:52 +01:00
2b3aae8087 fix: append image to FormData before submission in use:enhance
The image upload broke because formData.append() was being called in the
async callback of use:enhance, which runs AFTER the form submission.
Moved the append call to the outer function which runs BEFORE submission.

Also cleaned up debug console.log statements from CardAdd.svelte.
2026-01-20 19:37:16 +01:00
1bf4f4cbcd debug: add client-side logging for recipe image upload
All checks were successful
CI / update (push) Successful in 1m22s
Add console logging in the browser to track image selection and form
submission:
- Log when user selects an image file in CardAdd component
- Log file validation steps (MIME type, size)
- Log form submission and FormData preparation
- Log whether image is being appended to form

This helps diagnose if the issue is client-side (image not selected/sent)
or server-side (image not received/processed).
2026-01-20 17:04:33 +01:00
a5e8edf5f1 fix: remove unused CSS selectors from payments edit page
Remove .split-details and .personal-amount CSS selectors that were not
being used in the markup, eliminating build warnings.
2026-01-20 12:30:52 +01:00
d62315ad01 debug: add comprehensive logging to recipe image upload flow
All checks were successful
CI / update (push) Successful in 1m23s
Add detailed console logging throughout the image upload pipeline to help
diagnose upload issues:
- Log file metadata and validation steps in imageValidation.ts
- Log image processing and file saving operations in imageProcessing.ts
- Log form data and processing steps in recipe add page action
- Log API request details and upload progress in img/add endpoint

All logs are prefixed with component name ([ImageValidation], [ImageProcessing],
[RecipeAdd], [API:ImgAdd]) for easy filtering and debugging.
2026-01-20 12:27:03 +01:00
180bdb4aaa fix: restore rosary counter functionality with Svelte 5 reactivity
The Ave Maria counter was not updating the visualization when clicked.
Fixed by wrapping decadeCounters in $state() for proper reactivity tracking
and correcting data-section attributes to use template literals instead of
string literals in the decade loop.
2026-01-20 12:03:23 +01:00
5598b19ec9 perf: optimize bundle size and add build optimizations
All checks were successful
CI / update (push) Successful in 1m23s
- Move HTML stripping to server-side to remove cheerio from client bundle (247KB reduction)
- Add terser minification with console/debugger removal
- Enable manual code chunking for chart.js and auth libraries
- Convert TTF fonts to WOFF2 format (~900KB savings)
- Enable brotli/gzip precompression in adapter
- Update CSS to prefer WOFF2 with TTF fallback
2026-01-19 21:46:10 +01:00
a48ae3ff3c refactor: defer recipe image upload until form submission
Changed recipe image upload behavior to only process images when the
form is submitted, rather than immediately on file selection. This
prevents orphaned image files when users abandon the form.

Changes:
- CardAdd.svelte: Preview only, store File object instead of uploading
- Created imageProcessing.ts: Shared utility for image processing
- Add/edit page clients: Use selected_image_file instead of filename
- Add/edit page servers: Process and save images during form submission
- Images are validated, hashed, and saved in multiple formats on submit

Benefits:
- No orphaned files from abandoned forms
- Faster initial file selection experience
- Server-side image processing ensures security validation
- Cleaner architecture with shared processing logic
2026-01-15 14:18:52 +01:00
5fae01c06d feat: use checksummed filenames for recipe images and clean up old files
All checks were successful
CI / update (push) Successful in 1m13s
Updated recipe image handling to use checksummed filenames for proper
cache busting. When uploading a new image during recipe edit, old image
files (both hashed and unhashed versions) are now properly deleted from
all directories (full, thumb, placeholder).

Changes:
- CardAdd.svelte: Use checksummed filename from upload response
- Edit page server: Add deleteRecipeImage() helper to remove old images
- Edit page server: Delete old images when new image is uploaded
2026-01-15 13:57:06 +01:00
ae32db7dfd feat: improve settlement display and add split recalculation to payment edit
All checks were successful
CI / update (push) Successful in 1m13s
Settlement Display Improvements:
- Redesigned settlement cards with distinct visual style
- Added gradient background and colored top border stripe
- Centered layout with prominent amount display
- Added settlement badge with icon
- Responsive vertical layout on mobile devices
- Fixed overflow issues on small screens

Payment Edit Enhancements:
- Added automatic split recalculation when amount changes
- Implemented editable personal amounts for personal_equal split method
- Real-time validation showing total personal and remainder
- Live split preview with automatic updates
- Support for all split methods: equal, full, personal_equal, proportional
- Foreign currency support with exchange rate recalculation
- Safeguards against infinite recalculation loops
- Improved UI with split method info display
- Responsive design for mobile devices
2026-01-13 20:03:13 +01:00
baa3f3e533 feat: add Redis caching to cospend API endpoints
All checks were successful
CI / update (push) Successful in 1m21s
Implement comprehensive caching for all cospend routes to improve performance:

Cache Implementation:
- Balance API: 30-minute TTL for user balances and global balances
- Debts API: 15-minute TTL for debt breakdown calculations
- Payments List: 10-minute TTL with pagination support
- Individual Payment: 30-minute TTL for payment details

Cache Invalidation:
- Created invalidateCospendCaches() helper function
- Invalidates user balances, debts, and payment lists on mutations
- Applied to payment create, update, and delete operations
- Applied to recurring payment execution (manual and cron)
2026-01-13 19:45:11 +01:00
db5d326fa2 fix: ensure isBaseRecipe checkbox submits correctly and use styled Toggle component
All checks were successful
CI / update (push) Successful in 1m12s
- Add hidden input to properly serialize isBaseRecipe boolean as "true"/"false" string
- Replace plain HTML checkbox with Toggle component for consistent styling
- Checkbox values don't submit when unchecked; hidden input ensures value is always sent
2026-01-13 15:33:22 +01:00
5ca044c79f fix: ensure recipe translations save properly by awaiting DOM updates before form submission
All checks were successful
CI / update (push) Successful in 1m13s
Previously, when users approved or skipped translations in the recipe forms, the translation data wasn't being saved to the database. This was caused by a timing issue where the form was submitted before Svelte had updated the DOM with the hidden inputs containing the translation data.

Fixed by using tick() to wait for pending state changes to be applied before submitting the form.
2026-01-13 15:24:37 +01:00
0dc950c824 fix: prevent infinite effect loop in recipe translation workflow
All checks were successful
CI / update (push) Successful in 1m14s
Convert recipe data functions to $derived reactive variables to prevent
infinite $effect loops. Previously, calling functions inline in component
props created new objects on every reactive check, causing the
TranslationApproval component's syncBaseRecipeReferences $effect to run
continuously, resulting in the translation workflow hanging.
2026-01-13 15:12:16 +01:00
0a49e20c02 refactor: migrate recipe forms to SvelteKit actions with secure image upload
Refactor recipe add/edit routes from client-side fetch to proper SvelteKit
form actions with progressive enhancement and comprehensive security improvements.

**Security Enhancements:**
- Implement 5-layer image validation (file size, MIME type, extension, magic bytes, Sharp structure)
- Replace insecure base64 JSON encoding with FormData for file uploads
- Add file-type@19 dependency for magic bytes validation
- Validate actual file type via magic bytes to prevent file type spoofing

**Progressive Enhancement:**
- Forms now work without JavaScript using native browser submission
- Add use:enhance for improved client-side UX when JS is available
- Serialize complex nested data (ingredients/instructions) via JSON in hidden fields
- Translation workflow integrated via programmatic form submission

**Bug Fixes:**
- Add type="button" to all interactive buttons in CreateIngredientList and CreateStepList
  to prevent premature form submission when clicking on ingredients/steps
- Fix SSR errors by using season_local state instead of get_season() DOM query
- Fix redirect handling in form actions (redirects were being caught as errors)
- Fix TranslationApproval to handle recipes without images using null-safe checks
- Add reactive effect to sync editableEnglish.images with germanData.images length
- Detect and hide 150x150 placeholder images in CardAdd component

**Features:**
- Make image uploads optional for recipe creation (use placeholder based on short_name)
- Handle three image scenarios in edit: keep existing, upload new, rename on short_name change
- Automatic image file renaming across full/thumb/placeholder directories when short_name changes
- Change detection for partial translation updates in edit mode

**Technical Changes:**
- Create imageValidation.ts utility with comprehensive file validation
- Create recipeFormHelpers.ts for data extraction, validation, and serialization
- Refactor /api/rezepte/img/add endpoint to use FormData instead of base64
- Update CardAdd component to upload via FormData immediately with proper error handling
- Use Image API for placeholder detection (avoids CORS issues with fetch)
2026-01-13 15:12:07 +01:00
deac9e3d1f fix: update event handlers to Svelte 5 syntax in add page and rosary counter
Fixes issues where translation buttons and rosary bead counter were not working
due to incomplete Svelte 5 migration. Updated parent components to use new
callback prop syntax (onapproved/onskipped/oncancelled) and lowercase onclick
handlers to match child component expectations.

- Fix TranslationApproval event handlers in recipe add page
- Fix CounterButton onclick prop in rosary page
2026-01-13 12:59:06 +01:00
bc170abcdf fix: add category and favorites filters to all recipe pages
- Move categories logic into Search component for centralization
- Add isLoggedIn prop to SeasonLayout and IconLayout components
- Fix FilterPanel CSS to properly handle hidden favorites filter
- Fix FavoritesFilter to trigger onToggle when checkbox changes
- Update Search effect to track all filter states (category, tags, icon, season, favorites)
- Hide favorites filter on favorites page while maintaining proper grid layout
- All filters now work consistently across entire site
2026-01-10 17:20:00 +01:00
7ab3482850 fix: resolve Svelte 5 migration warnings and improve accessibility
All checks were successful
CI / update (push) Successful in 2m2s
- Fix state_referenced_locally warnings by extracting initial values to constants
- Remove unused CSS selectors (subheading, header-actions, back-actions)
- Add ARIA roles and keyboard handlers to settlement options
- Add a11y ignore comment for custom checkbox implementation
2026-01-10 17:05:39 +01:00
5c8605c690 feat: complete Svelte 5 migration across entire application
All checks were successful
CI / update (push) Successful in 2m8s
Migrated all components and routes from Svelte 4 to Svelte 5 syntax:

- Converted export let → $props() with generic type syntax
- Replaced createEventDispatcher → callback props
- Migrated $: reactive statements → $derived() and $effect()
- Updated two-way bindings with $bindable()
- Fixed TypeScript syntax: added lang="ts" to script tags
- Converted inline type annotations to generic parameter syntax

- Updated deprecated event directives to Svelte 5 syntax:
  - on:click → onclick
  - on:submit → onsubmit
  - on:change → onchange

- Converted deprecated <slot> elements → {@render children()}
- Updated slot props to Snippet types
- Fixed season/icon selector components with {#snippet} blocks

- Fixed non-reactive state by converting let → $state()
- Fixed infinite loop in EnhancedBalance by converting $effect → $derived
- Fixed Chart.js integration by converting $state proxies to plain arrays
- Updated cospend dashboard and payment pages with proper reactivity

- Migrated 20+ route files from export let data → $props()
- Fixed TypeScript type annotations in page components
- Updated reactive statements in error and cospend routes

- Removed invalid onchange attribute from Toggle component
- Fixed modal ID isolation in CreateIngredientList/CreateStepList
- Fixed dark mode button visibility in TranslationApproval
- Build now succeeds with zero deprecation warnings

All functionality tested and working. No breaking changes to user experience.
2026-01-10 16:20:50 +01:00