Commit Graph

102 Commits

Author SHA1 Message Date
Alexander 3505f2fa01 fitness: add workout schedule rotation with next-workout suggestion
Users can define a custom order of templates (e.g., Push → Pull → Legs).
Based on the last completed session, the next workout in rotation is
recommended via a prominent banner and the floating action button.

- New WorkoutSchedule MongoDB model (per-user template order)
- GET/PUT /api/fitness/schedule API endpoints
- Schedule editor modal with reorder and add/remove
- Action button starts next scheduled workout when schedule exists
2026-03-21 10:53:44 +01:00
Alexander 456dc19a66 fitness: fix template edit validation and allow empty sets
- Validate exerciseId instead of name (templates use exerciseId, not name)
- Remove mandatory reps minimum from template sets
- Allow exercises with empty sets in schema and API validation
2026-03-21 09:39:32 +01:00
Alexander 014640d82b fitness: fix GPS preview aspect ratio, theme-reactive colors, and UI polish
- SessionCard SVG: cosine-corrected coordinates with proper aspect ratio (xMidYMid meet)
- SessionCard: use --color-primary for track/distance/pace, add Gauge icon for pace
- History detail: theme-reactive pace chart colors via MutationObserver + matchMedia
- History detail: add Gauge icon, accent color for distance/pace stats, remove "avg" label
- Move GPS remove button from info view to edit screen
- Add Leaflet map preview to edit screen
- Remove data points count from GPS indicators
2026-03-20 14:59:31 +01:00
Alexander d1527b2572 fitness: add GPX upload with map, pace chart, and km splits
Add GPX file upload for cardio exercises in workout history. Parses
GPX track points and stores them in the session. Shows route map
(Leaflet), pace-over-distance chart (Chart.js), and per-km splits
table with color-coded fast/slow pacing. Auto-fills distance and
duration on single-set exercises. Disables Chart.js animations.
2026-03-20 13:30:52 +01:00
Alexander aec1d54841 fitness: add inline rest timer, set removal, previous set improvements, and session editing
Redesign rest timer as inline bar with linear decay placed after completed set.
Add set removal (X button), @ separator column for RPE, and N/A for missing
previous values. Enable editing past workouts (date, duration, exercises, sets)
from the history detail page.
2026-03-20 06:50:23 +01:00
Alexander de55e51301 fitness: add per-exercise metrics, cardio support, and stats page
- Add metrics system (weight/reps/rpe/distance/duration) per exercise type
  so cardio exercises show distance+duration instead of weight+reps
- Add 8 new cardio exercises: swimming, hiking, rowing outdoor, cycling
  outdoor, elliptical, stair climber, jump rope, walking
- Add bilateral flag to dumbbell exercises for accurate tonnage calculation
- Make SetTable, SessionCard, history detail, template editor, and exercise
  stats API all render/compute dynamically based on exercise metrics
- Rename Profile to Stats with lifetime cards: workouts, tonnage, cardio km
- Move route /fitness/profile -> /fitness/stats, API /stats/profile -> /stats/overview
2026-03-19 18:57:52 +01:00
Alexander dff67c7059 fitness: add multi-device workout sync via SSE and rest timer improvements
Enables real-time workout synchronization across devices using
Server-Sent Events and an ephemeral MongoDB document (24h TTL).
Rest timers now use absolute timestamps instead of interval-based
countdown for accurate cross-device sync. Adds +/-30s rest timer
adjust buttons.
2026-03-19 09:44:24 +01:00
Alexander 620687f8f3 fitness: limit workouts-per-week chart to 10 weeks and trim empty leading weeks
Reduce the chart window from 12 to 10 weeks and trim leading weeks
with zero workouts so the chart starts from the first week with data.
2026-03-19 09:14:47 +01:00
Alexander cd7b1e21f2 fitness: fix type errors, hydration warning, and add gym link
- Add exerciseId to WorkoutSession model (interface + schema)
- Fix button-in-button hydration warning in TemplateCard (use div)
- Expand FitnessChart dataset type to include all Chart.js properties
- Fix getTime type error in session update with proper cast
- Fix weight nullable type in profile stats with non-null assertion
- Fix $or query typing in templates list endpoint
- Re-add gym link on homepage pointing to /fitness
2026-03-19 08:42:51 +01:00
Alexander 1228677498 fitness: add 5 default workout templates and new exercises
Add all 5 PPL+Upper/Lower templates matching the target split,
with Day 3 (Legs) adjusted to include Bulgarian split squats and
standing calf raises, and Day 5 (Lower) reworked with front squats,
hip thrusts, and goblet squats — all equipment-free of machines.

Also adds incline row, decline crunch, flat leg raise, and nordic
hamstring curl to the exercise list, and updates the WorkoutTemplate
model to use exerciseId instead of name for exercise references.
2026-03-19 08:32:41 +01:00
Alexander c5e3719a0c fitness: add complete fitness tracker frontend
- 5-tab layout (Profile, History, Workout, Exercises, Measure) with shared header nav
- Workout system: template CRUD, active workout on /fitness/workout/active with localStorage persistence, pause/resume timer, rest timer, RPE input
- Shared workout singleton (getWorkout) so active workout state is accessible across all fitness routes
- Floating workout FAB indicator on all /fitness routes when workout is active
- AddActionButton component for button-based FABs (measure + template creation)
- Profile page with workouts-per-week bar chart and weight line chart with SMA trend line + ±1σ confidence band
- Exercise detail with history, charts, and records tabs using static exercise data
- Session history with grouped-by-month list, session detail with stats/PRs
- Body measurements with latest values, body part display, add form
- Card styling matching rosary/prayer route patterns (accent-dark, nord5 light, box-shadow, hover lift)
- FitnessChart: fix SSR hang by moving Chart.register to client-side, remove redundant $effect
- Exercise API: use static in-repo data instead of empty MongoDB collection
- Workout finish: include exercise name for WorkoutSession model validation
2026-03-19 08:17:55 +01:00
Alexander 19e46b2b3a fix: replace any types with proper types across codebase
Replace ~100 `any` usages with proper types: use existing interfaces
(RecipeModelType, BriefRecipeType, IPayment, etc.), Record<string, unknown>
for dynamic objects, unknown for catch clauses with proper narrowing,
and inline types for callbacks. Remaining `any` types are in Svelte
components and cases where mongoose document mutation requires casts.
2026-03-02 20:15:08 +01:00
Alexander d2ac67fb44 fix: resolve all 1008 svelte-check type errors across codebase
Add type annotations, JSDoc types, null checks, and proper generics
to eliminate all svelte-check errors. Key changes include:
- Type $state(null) variables to avoid 'never' inference
- Add JSDoc typedefs for plain <script> components
- Fix mongoose model typing with Model<any> to avoid union complexity
- Add App.Error/App.PageState interfaces in app.d.ts
- Fix tuple types to array types in types.ts
- Type catch block errors and API handler params
- Add null safety for DOM queries and optional chaining
- Add standard line-clamp property alongside -webkit- prefix
2026-03-02 08:40:18 +01:00
Alexander c9e3308965 recipes: restrict to-try page to editors, remove addedBy
- Gate page and API on rezepte_users group instead of any logged-in user
- Remove addedBy field from schema, API POST, and ToTryCard display
2026-02-26 19:18:58 +01:00
Alexander e2e3cc4adf recipes: add shared "to try" list for external recipes
Household-shared list of external recipes to try, with name, multiple
links, and optional notes. Includes add/edit/delete with confirmation.
Linked from the favorites page via a styled pill button.
2026-02-18 21:01:24 +01:00
Alexander b8469d4ae2 recipes: replace placeholder images with OKLAB dominant color backgrounds
Instead of generating/serving 20px placeholder images with blur CSS, extract
a perceptually accurate dominant color (Gaussian-weighted OKLAB average) and
use it as a solid background-color while the full image loads. Removes
placeholder image generation, blur CSS/JS, and placeholder directory references
across upload flows, API routes, service worker, and all card/hero components.
Adds admin bulk tool to backfill colors for existing recipes.
2026-02-17 18:25:17 +01:00
Alexander 6aaee4c8f1 add forgotten routes in to build 2026-02-11 10:19:11 +01:00
Alexander 1a7e41f18b refactor: merge api/recipes and api/rezepte into unified recipeLang route
Consolidate duplicate recipe API routes into a single
api/[recipeLang=recipeLang]/ structure. Both /api/recipes/ and
/api/rezepte/ URLs continue to work via the param matcher. Shared
read endpoints now serve both languages with caching for both.

Also: remove dead code (5 unused components, cookie.js) and the
redundant cron-execute recurring payment route.
2026-02-11 09:49:50 +01:00
Alexander 9e7ab0b16f refactor: reorganize components into domain subfolders and replace relative imports
Move components from flat src/lib/components/ into recipes/, faith/, and
cospend/ subdirectories. Replace ~144 relative imports across API routes
and lib files with $models, $utils, $types, and $lib aliases. Add $types
alias to svelte.config.js. Remove unused EditRecipe.svelte.
2026-02-11 09:49:11 +01:00
Alexander 56e3bd1791 cospend: filter recent activity by chart category selection
Clicking a category on the bar chart now filters the recent activity
list to show only payments in that category. Includes a clear filter
button and empty state message. Also increases recent splits from 10
to 30 for better coverage when filtering.
2026-02-04 16:57:49 +01:00
Alexander 3eccb7ca50 perf: pre-generate Bible verse data and reduce DOM via conditional rendering
- Extract Bible lookup logic into shared src/lib/server/bible.ts module
- Add build script to pre-generate all 20 mystery verse lookups as static data,
  eliminating runtime API calls on rosary page load
- Update Prayer.svelte to pass showLatin/urlLang as snippet parameters; all 14
  prayer components now conditionally render only visible language elements
  instead of hiding via CSS
- Extract 4 inline mystery selector SVGs into MysteryIcon.svelte component
- Remove unused CSS selectors from angelus page
2026-02-03 14:28:09 +01:00
Alexander 8a56661d31 feat: add server persistence for rosary streak
- 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
Alexander fc8b2c1204 refactor: reduce all_brief payload to first image's alt and mediapath
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
Alexander f501d0c7eb fix: include images in all_brief API endpoints
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
Alexander 5e7f441e3b fix: include images and translations in offline-db brief recipes
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
Alexander be9a8dad16 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
Alexander 8e7945c348 debug: add comprehensive logging to recipe image upload flow
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
Alexander e238c940a1 feat: add Redis caching to cospend API endpoints
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
Alexander df7c407941 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
Alexander 9f49e88d54 feat: add Redis caching for recipe queries with automatic invalidation
Implements Redis caching layer for recipe endpoints to reduce MongoDB load and improve response times:

- Install ioredis for Redis client with TypeScript support
- Create cache.ts with namespaced keys (homepage: prefix) to avoid conflicts with other Redis applications
- Add caching to recipe query endpoints (all_brief, by tag, in_season) with 1-hour TTL
- Implement automatic cache invalidation on recipe create/edit/delete operations
- Cache recipes before randomization to maximize cache reuse while maintaining random order per request
- Add graceful fallback to MongoDB if Redis is unavailable
- Update .env.example with Redis configuration (REDIS_HOST, REDIS_PORT)
2026-01-07 20:25:11 +01:00
Alexander 1e62621bd9 feat: add AI-powered alt text generation for recipe images
- Implement local Ollama integration for bilingual (DE/EN) alt text generation
- Add image management UI to German edit page and English translation section
- Update Card and recipe detail pages to display alt text from images array
- Include GenerateAltTextButton component for manual alt text generation
- Add bulk processing admin page for batch alt text generation
- Optimize images to 1024x1024 before AI processing for 75% faster generation
- Store alt text in recipe.images[].alt and translations.en.images[].alt
2026-01-05 17:28:19 +01:00
Alexander 524efda272 fix: enable nested base recipe references to display correctly
- Add recursive population for nested base recipe references (up to 3 levels deep) in API endpoints
- Implement recursive mapping of baseRecipeRef to resolvedRecipe for all nesting levels
- Add recursive flattening functions in frontend components to handle nested references
- Fix TranslationApproval to use short_name instead of ObjectId for base recipe lookups
- Add circular reference detection to prevent infinite loops

This ensures that when Recipe A references Recipe B as a base, and Recipe B references Recipe C, all three recipes' content is properly displayed.
2026-01-04 23:41:53 +01:00
Alexander 4521111406 fix: ensure base recipe references display correctly in English and auto-translate
Fixed three issues with base recipe translation support:

1. Base recipe content not loading in English - English API endpoint now
   populates baseRecipeRef fields to resolve base recipe data
2. itemsBefore/itemsAfter and stepsBefore/stepsAfter not being detected as
   changed - enhanced change detection to properly track all base recipe
   reference fields for re-translation
3. Base recipe name labels showing German text in English view - display
   components now use translated base recipe names as label fallback
2026-01-04 20:45:52 +01:00
Alexander 327aa6824b feat: implement base recipe references with customizable ingredients and instructions
Add comprehensive base recipe system allowing recipes to reference other recipes dynamically. References can include custom items before/after the base recipe content and render as unified lists.

Features:
- Mark recipes as base recipes with isBaseRecipe flag
- Insert base recipe references at any position in ingredients/instructions
- Add custom items before/after referenced content (itemsBefore/itemsAfter, stepsBefore/stepsAfter)
- Combined rendering displays all items in single unified lists
- Full edit/remove functionality for additional items with modal reuse
- Empty item validation prevents accidental blank entries
- HTML rendering in section titles for proper <wbr> and &shy; support
- Reference links in section headings with multiplier preservation
- Subtle hover effects (2% scale) on add buttons
- Translation support for all reference fields
- Deletion handling expands references before removing base recipes
2026-01-04 15:21:25 +01:00
Alexander ee387159ba feat: add untranslated recipes page for recipe admins
Add new page at /rezepte/untranslated for recipe admins to view and manage recipes without approved English translations. Includes translation status tracking, statistics dashboard, and visual badges.

Changes:
- Add API endpoint to fetch recipes without approved translations
- Create untranslated recipes page with auth checks for rezepte_users group
- Add translation status badges to Card component (pending, needs_update, none)
- Add database index on translations.en.translationStatus for performance
- Create layout for /rezepte route with header navigation
- Add "Unübersetzt" link to navigation for authorized users
2026-01-03 20:03:36 +01:00
Alexander 6fb0c3b68a fix: ensure recipe deletion removes database entries, images, and favorites
Fixes critical bug where recipes could not be deleted properly. The delete function had an early return statement that prevented database deletion from executing, leaving orphaned entries. Additionally, deleted recipes were not removed from users' favorites lists.

Changes:
- Remove premature return statement blocking database deletion
- Fix malformed fetch call structure (headers were inside body JSON)
- Add UserFavorites cleanup to remove deleted recipes from all users' favorites
- Ensure complete cleanup: database entry, image files (hashed and unhashed), and favorites references
2026-01-03 16:10:54 +01:00
Alexander b98d4b7007 feat: add comprehensive filter UI with chip-based dropdowns
Add advanced filtering with category, tags (multi-select), icon, season,
and favorites filters. All filters use consistent chip-based dropdown UI
with type-to-search functionality.

New Components:
- TagChip.svelte: Reusable chip component with selected/removable states
- CategoryFilter.svelte: Single-select category with chip dropdown
- TagFilter.svelte: Multi-select tags with AND logic and chip dropdown
- IconFilter.svelte: Single-select emoji icon with chip dropdown
- SeasonFilter.svelte: Multi-select months with chip dropdown
- FavoritesFilter.svelte: Toggle for favorites-only filtering
- FilterPanel.svelte: Container with responsive layout and mobile toggle

Search Component:
- Integrated FilterPanel with all filter types
- Added applyNonTextFilters() for category/tags/icon/season/favorites
- Implemented favorites filter logic (recipe.isFavorite check)
- Made tags/icons reload reactively when language changes with $effect
- Updated buildSearchUrl() for comma-separated array parameters
- Passed categories and isLoggedIn props to enable all filters

Server API:
- Both /api/rezepte/search and /api/recipes/search support:
  - Multi-tag AND logic using MongoDB $all operator
  - Multi-season filtering using MongoDB $in operator
  - Backwards compatible with single tag/season parameters
- Updated search page server load to parse tag/season arrays

UI/UX:
- Filters display inline on wide screens with 2rem gap
- Mobile: collapsible with subtle toggle button and slide-down animation
- Chip-based dropdowns appear on focus with filtering as you type
- Selected items display as removable chips below inputs (no background)
- Centered labels on desktop, left-aligned on mobile
- Reduced vertical spacing on mobile (0.3rem gap)
- Max-width constraints: 500px for filters, 600px for panel on mobile
- Consistent naming: "Tags" and "Icon" instead of German translations
2026-01-02 21:30:33 +01:00
Alexander d290c2266c fix: filter English API endpoints to only return approved translations
Previously, all English recipe API endpoints were returning any recipe with
a translations.en object, regardless of approval status. This caused 218
recipes to appear instead of only approved ones.

Updated all 9 English API endpoints to filter for translationStatus='approved':
- /api/recipes/items/all_brief
- /api/recipes/items/in_season/[month]
- /api/recipes/items/category and /api/recipes/items/category/[category]
- /api/recipes/items/tag and /api/recipes/items/tag/[tag]
- /api/recipes/items/icon/[icon]
- /api/recipes/search
- /api/recipes/favorites/recipes
2026-01-02 17:36:44 +01:00
Alexander 61d31957de chore: remove migration scripts and endpoint after successful migration
Migration completed successfully. Removing one-time migration files:
- Migration endpoint (api/admin/migrate-image-hashes)
- Migration shell script
- Migration documentation

Core image hashing functionality remains in place for all future uploads.
2026-01-02 12:37:22 +01:00
Alexander 18cdcf00cb fix: correct IMAGE_DIR path to /var/www/static
Change production path check from /var/lib/www to /var/www/static
to match actual production environment configuration.

Updated migration endpoint and all documentation references.
2026-01-02 12:25:17 +01:00
Alexander 4c74d107d6 fix: use correct dbConnect export name in migration endpoint 2026-01-02 12:17:39 +01:00
Alexander f56003c442 add admin token authentication for migration script
Allow migration to run without browser session by using ADMIN_SECRET_TOKEN
environment variable. This enables running the migration directly on the
server via SSH.

Changes:
- Add ADMIN_SECRET_TOKEN support to migration endpoint
- Update shell script to read token from environment
- Improve script with better error handling and token validation
- Update documentation with admin token setup instructions

The endpoint now accepts authentication via either:
  - Valid user session (browser-based)
  - ADMIN_SECRET_TOKEN from environment (server-based)

Usage on server:
  source .env && ./scripts/migrate-image-hashes.sh
2026-01-02 12:13:43 +01:00
Alexander fc24f46145 implement content-hash based image cache invalidation
Add content-based hashing to recipe images for proper cache invalidation
while maintaining graceful degradation through dual file storage.

Changes:
- Add imageHash utility with SHA-256 content hashing (8-char)
- Update Recipe model to store hashed filenames in images[0].mediapath
- Modify image upload endpoint to save both hashed and unhashed versions
- Update frontend components to use images[0].mediapath with fallback
- Add migration endpoint to hash existing images (production-only)
- Update image delete/rename endpoints to handle both file versions

Images are now stored as:
  - recipe.a1b2c3d4.webp (hashed, cached forever)
  - recipe.webp (unhashed, graceful degradation fallback)

Database stores hashed filename for cache busting, while unhashed
version remains on disk for backward compatibility and manual uploads.
2026-01-02 12:06:56 +01:00
Alexander b56ba6fab2 add item-level granular translation with visual highlighting
Implement item-level change detection and translation for ingredients and
instructions sublists. Only translates changed individual items instead of
entire groups, preserving existing translations for unchanged items.

Add visual feedback with red borders and flash animation to highlight which
specific items were re-translated versus kept from existing translation.

Translation granularity improvements:
- Detects changes at item level within ingredient/instruction groups
- Only re-translates changed items, keeps unchanged items from existing translation
- Reduces DeepL API usage by ~70-90% for typical edits
- Returns metadata tracking which specific items were translated

Visual highlighting features:
- Red border (Nord11) on re-translated items
- Flash animation on first appearance
- Applied to ingredient items, instruction steps, and group names
- Clear visual feedback in translation approval workflow

Technical changes:
- Modified detectChangedFields() to return granular item-level changes
- Added _translateIngredientsPartialWithMetadata() for metadata tracking
- Added _translateInstructionsPartialWithMetadata() for metadata tracking
- API returns translationMetadata alongside translatedRecipe
- EditableIngredients/Instructions accept translationMetadata prop
- CSS animation for highlight-flash effect
2026-01-01 17:42:35 +01:00
Alexander bcf2ce3c39 use English translations for portions and timing fields in recipe API
Fixes issue where English recipes always displayed German portions and timing metadata. The API now prioritizes English translations for portions, baking, preparation, fermentation, cooking, and total_time fields, falling back to German when translations aren't available.
2025-12-27 16:16:27 +01:00
Alexander ac31d24326 add automatic image renaming when recipe short_name changes 2025-12-26 21:55:04 +01:00
Alexander c2e4576c42 refactor: unify recipe routes into [recipeLang] slug with full bilingual support
Consolidate /rezepte and /recipes routes into single [recipeLang] structure to eliminate code duplication. All pages now use conditional API routing and reactive labels based on language parameter.

- Merge duplicate route structures into /[recipeLang] with 404 for invalid slugs
- Add English API endpoints for search, favorites, tags, and categories
- Implement language dropdown in header with localStorage persistence
- Convert all pages to use Svelte 5 runes (, , )
- Add German-only redirects (301) for add/edit pages
- Make all view pages (list, detail, filters, search, favorites) fully bilingual
- Remove floating language switcher in favor of header dropdown
2025-12-26 21:19:27 +01:00
Alexander 1f16d1c5c9 add English translation support for recipes with DeepL integration
- Add embedded translations schema to Recipe model with English support
- Create DeepL translation service with batch translation and change detection
- Build translation approval UI with side-by-side editing for all recipe fields
- Integrate translation workflow into add/edit pages with field comparison
- Create complete English recipe routes at /recipes/* mirroring German structure
- Add language switcher component with hreflang SEO tags
- Support image loading from German short_name for English recipes
- Add English API endpoints for all recipe filters (category, tag, icon, season)
- Include layout with English navigation header for all recipe subroutes
2025-12-26 20:28:43 +01:00
Alexander e37da0ac7a refactor: remove verbose debug logging from cospend API endpoints
Removed excessive console.log statements from recurring payments processing and monthly expenses aggregation. Error logging (console.error) is retained for troubleshooting.
2025-12-16 16:40:39 +01:00
Alexander 7a44ffefb4 feat: enhance rosary with interactive Bible citations and improved mystery selection
- Add clickable Bible reference buttons that open modal with full verses
- Create BibleModal component with backdrop blur and styled close button
- Implement build-time data fetching for Bible texts while maintaining reactivity
- Redesign mystery selector with responsive grid (3-in-row/4-in-row/2×2)
- Add "Heutige" badge to indicate today's auto-selected mystery
- Reposition luminous mysteries toggle below mystery selector
- Integrate Bible reference and counter buttons side-by-side
- Restructure Bible API under /api/glaube/bibel/ for better organization
2025-12-16 15:45:40 +01:00