Commit Graph

439 Commits

Author SHA1 Message Date
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
8af2fc3f3b build: keep console.error/warn/info in production builds
All checks were successful
CI / update (push) Successful in 1m22s
Changed drop_console from true to ['log', 'debug'] to retain
error and warning logs for debugging while reducing bundle size.
2026-01-20 12:16:14 +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
50b0e7a70e fix: handle undefined/null input in stripHtmlTags function
All checks were successful
CI / update (push) Successful in 1m19s
Adds null check to prevent crash when recipe name or description fields are undefined.
2026-01-19 21:55:32 +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
041d415525 fix: allow arbitrary decimal values for base multiplier 2026-01-13 19:30:35 +01:00
296201eee5 fix: improve UI elements in recipe editor
All checks were successful
CI / update (push) Successful in 1m14s
- Center isBaseRecipe toggle by changing display to inline-flex
- Fix note field editing by adding textarea with bindable value
- Clear instruction step input after submission instead of restoring placeholder
- Style note textarea with transparent background and lighter placeholder text

The instruction field now properly clears on submission, while ingredient fields retain their previous values.
2026-01-13 19:14:26 +01:00
b43b45dac2 feat: add base multiplier support for recipe references
Add optional baseMultiplier field to ingredient and instruction references, allowing base recipes to be included at scaled amounts (e.g., 0.5 for half the recipe).

- Add baseMultiplier field to Recipe schema with default value of 1
- Update TypeScript types to include baseMultiplier
- Add multiplier input field to BaseRecipeSelector modal
- Apply baseMultiplier to ingredient amounts during flattening
- Combine baseMultiplier with recipe multiplier in links
- Display and allow editing baseMultiplier in recipe editor

The multiplier cascades through nested references and works alongside the standard recipe multiplier for compound scaling.
2026-01-13 19:14:10 +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
f4783bea0a chore: update CI workflow to use pnpm instead of npm
All checks were successful
CI / update (push) Successful in 1m20s
Changed deployment workflow to use pnpm with frozen lockfile to ensure
consistent dependency installation matching local development environment.
2026-01-10 17:52:02 +01:00
a822ea738c chore: update @auth/sveltekit to v1.11.1 and remove direct @auth/core dependency
Updated authentication packages to latest versions for security fixes:
- @auth/sveltekit: 1.10.0 → 1.11.1 (includes nodemailer security fix)
- @auth/core: removed from devDependencies (transitively pulled as 0.41.1)

Changed imports to use @auth/sveltekit/providers instead of @auth/core/providers
and removed unused imports from hooks.server.ts.
2026-01-10 17:49:51 +01:00
a936b736de feat: add AND/OR logic mode toggle to filter panel
All checks were successful
CI / update (push) Successful in 1m15s
- Add LogicModeToggle component to switch between AND and OR filter logic
- Enable multi-select for category and icon filters in OR mode
- Update Search component to handle both AND and OR filtering logic
- Resize Toggle component to match LogicModeToggle size (44px x 24px)
- Position logic mode toggle on the left side of filter panel
- Auto-convert arrays to single values when switching from OR to AND mode
- In OR mode: recipes match if they satisfy ANY active filter
- In AND mode: recipes must satisfy ALL active filters
2026-01-10 17:34:13 +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
8eee15d901 remove predigten 2026-01-10 15:33:21 +01:00
2c370363f5 fix: resolve recipe edit modal issues and improve dark mode visibility
All checks were successful
CI / update (push) Successful in 1m15s
- Migrate TranslationApproval and edit page to Svelte 5 runes ($props, $state, $derived)
- Fix empty modal issue by eagerly initializing editableEnglish from germanData
- Fix modal state isolation by adding language-specific modal IDs (en/de)
- Resolve cross-contamination where English modals opened German ingredient/instruction editors
- Improve button icon visibility in dark mode by setting white fill color
- Replace createEventDispatcher with callback props for Svelte 5 compatibility
2026-01-10 10:48:02 +01:00
1628f8ba23 feat: add Redis caching for recipe queries with automatic invalidation
All checks were successful
CI / update (push) Successful in 13s
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)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-07 20:25:11 +01:00
bfba0870e3 fix hover on Card not red
All checks were successful
CI / update (push) Successful in 1m11s
2026-01-05 23:50:03 +01:00
2feb8355b8 refactor: add TypeScript type annotations to fix implicit 'any' errors
Fixed 12 type errors by adding proper type annotations:

Quick Wins Completed:
- do_on_key.js: Added JSDoc types for KeyboardEvent and function parameters
- randomize.js: Added JSDoc types with generic template for array shuffling
- cookie.js: Added JSDoc types for Request API
- stripHtmlTags.ts: Added TypeScript types for string parameter

Progress: 12/1239 errors fixed (Quick Wins - Category 1 partial)

Created TODO_cleanup.md to track remaining 1227 type errors systematically.
2026-01-05 23:49:02 +01:00
f66334290a refactor: complete Svelte 5 migration to eliminate all deprecation warnings
All checks were successful
CI / update (push) Successful in 1m35s
Migrated all components and routes to Svelte 5 syntax standards:

Event Handlers:
- Updated all deprecated on:* directives to new on* attribute syntax
- Changed on:click → onclick, on:keydown → onkeydown, on:input → oninput
- Updated on:blur, on:focus, on:load, on:submit, on:cancel handlers

Reactive State:
- Added $state() declarations for all reactive variables
- Fixed non-reactive update warnings in layout and component files

Component API:
- Replaced <slot /> with {@render children()} pattern
- Added children prop to components using slots

Accessibility:
- Added id attributes to inputs and for attributes to labels
- Fixed label-control associations across forms
- Removed event listeners from non-interactive elements

HTML Fixes:
- Fixed self-closing textarea tags
- Corrected implicitly closed elements
- Proper element nesting

CSS Cleanup:
- Removed 20+ unused CSS selectors across components
- Cleaned up orphaned styles from refactoring

All vite-plugin-svelte warnings resolved. Codebase now fully compliant with Svelte 5.
2026-01-05 23:39:44 +01:00
2de51ee492 fix: eliminate layout shift in recipe search by reserving filter panel space
All checks were successful
CI / update (push) Successful in 1m10s
Changed FilterPanel from conditional rendering to always-rendered with visibility control. This prevents layout shift when JavaScript loads by reserving the space upfront while keeping it visually hidden for non-JS users.
2026-01-05 23:19:59 +01:00
ab84ffc131 fix: force white color for Login link in production with !important
All checks were successful
CI / update (push) Successful in 1m39s
The Login link was appearing light blue and nord purple when visited
in production/preview builds due to CSS specificity conflicts with
global nordtheme.css link styles. Added !important flags to enforce
white color for all link states and nord8 for hover/focus states.
2026-01-05 23:08:32 +01:00
3a2a4ec928 feat: consolidate admin features into centralized administration page
All checks were successful
CI / update (push) Successful in 1m10s
- Created administration page at /{recipeLang}/administration accessible only to rezepte_users
- Moved alt-text generator from /admin to /{recipeLang}/admin/alt-text-generator
- Added "Administration" link to user profile dropdown for rezepte_users
- Removed "Unübersetzt" link from main navigation (now accessed via administration page)
- Administration page provides card-based UI with links to:
  - Untranslated Recipes management
  - AI Alt-Text Generator
- Both features now integrated into recipe language routing structure
- Added server-side authentication to all admin routes
2026-01-05 22:54:27 +01:00
6b3aed582e fix: improve logo alignment and reduce focus area padding
All checks were successful
CI / update (push) Successful in 1m11s
- Removed 'entry' class from desktop logo to match mobile implementation
- Added left padding to nav for consistent logo alignment across viewports
- Reduces excessive padding when tabbing through logo links
2026-01-05 22:33:31 +01:00
9cec69af10 fix: ensure Login link uses consistent white styling like other header links
Updated CSS selectors to specifically target 'a.entry' instead of '.entry' to properly apply styling to the Login link. This ensures the link appears white in both light and dark modes, matching the styling of other navigation links.
2026-01-05 22:29:25 +01:00
6faa06e0e1 fix: improve text contrast in filter labels and update login button text
All checks were successful
CI / update (push) Successful in 1m12s
- Change login button text from "Log In" to "Login"
- Update filter labels (Kategorie, Icon, Tags, Saison, Favoriten) to use darker color (nord2) in light mode for better readability
- Improve placeholder text contrast in filter inputs by using lighter shade (nord4)
- Maintain light color scheme (nord6) for filter labels in dark mode
2026-01-05 17:53:01 +01:00
4ffc0940ef feat: add AI-powered alt text generation for recipe images
All checks were successful
CI / update (push) Successful in 1m10s
- 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
cc978e73b4 feat: improve accessibility and update color scheme based on PageSpeed insights
All checks were successful
CI / update (push) Successful in 1m13s
- Add aria-labels to icon-only links (add button, edit button, logo, nav toggle)
- Add main landmark element for better page structure
- Fix heading hierarchy on recipe pages (h1 → h2 → h3 progression)
- Add role="status" to loading placeholders to allow aria-label usage
- Update link colors from red to blue for better contrast in both light and dark modes
- Change hover colors from orange/red to light blue across all interactive elements
- Reduce font size of section labels (Season, Keywords) while maintaining semantic structure

These changes address PageSpeed accessibility recommendations including low-contrast text,
missing accessible names, prohibited ARIA attributes, missing landmarks, and improper
heading order.
2026-01-05 16:14:37 +01:00
4a8e6c6600 fix: use correct short_name for base recipe links in English and edit pages
All checks were successful
CI / update (push) Successful in 1m11s
- Use English short_name for base recipe links when viewing English recipes
- Fix edit page to use /rezepte/edit/<shortname> instead of /{data.lang}/edit/<shortname>
- Ensures base recipe reference links work correctly in both languages
2026-01-05 00:01:35 +01:00
8eacf1f5d0 fix: enable nested base recipe references to display correctly
All checks were successful
CI / update (push) Successful in 1m10s
- 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
8a152c5fb2 feat: add comprehensive base recipe translation support
- Add language prop to CreateIngredientList and CreateStepList components
  - Support both 'de' and 'en' with translation dictionaries
  - All UI labels now respect the lang prop

- Implement syncBaseRecipeReferences() in TranslationApproval
  - Always runs on component mount (not just for new translations)
  - Fetches English names for base recipe references
  - Merges German structure with existing English translations
  - Preserves existing translations while adding new base recipe refs

- Enhance partial translation in translation.ts
  - Handle base recipe reference fields (itemsBefore/itemsAfter, stepsBefore/stepsAfter)
  - Detect changes using JSON comparison
  - Only re-translate fields that changed
  - Ensures additional items/steps in base recipe refs are preserved during updates
2026-01-04 22:25:34 +01:00
1d4daf11ad refactor: use CreateIngredientList and CreateStepList in translation approval UI
Replaced the plain EditableIngredients and EditableInstructions components
with the styled CreateIngredientList and CreateStepList components to match
the German recipe editing UI above:

- Now displays English translation with same styling as German recipe
- Ingredients and instructions shown in familiar two-column layout
- Timing fields (preparation, baking, fermentation, cooking, total_time)
  integrated into CreateStepList component instead of separate fields
- Added getters/setters for add_info object to enable two-way binding
  between CreateStepList edits and editableEnglish data
- Removed redundant field editors for baking/fermentation since they're
  now part of CreateStepList

Translation approval UI now has consistent styling with the rest of the
edit page for a more cohesive user experience.
2026-01-04 21:35:55 +01:00
03df3b0d14 refactor: simplify translation approval UI to single-column layout
Streamlined the translation approval workflow by removing the side-by-side
German/English comparison and focusing on the English translation only:

- TranslationApproval: Removed two-column comparison grid, now shows only
  English translation in single-column layout for cleaner UI
- Added 'Vollständig neu übersetzen' button to TranslationApproval actions
  section (next to Re-translate button as requested)
- Edit page: Removed standalone 'Vollständig neu übersetzen' button from
  submit buttons, now handled within translation approval workflow
- Updated CSS to use simplified .translation-preview and .field-section
  classes instead of grid layout

The German original is still accessible above in the edit form, making
the translation approval process more focused and less cluttered.
2026-01-04 21:30:55 +01:00
95e6d78619 feat: add translation editing support for base recipe reference fields
All checks were successful
CI / update (push) Successful in 1m10s
Enhanced translation approval UI to allow editing translated text in base
recipe references:

- EditableIngredients: Added support for editing labelOverride, itemsBefore,
  and itemsAfter fields with visual distinction for base recipe references
- EditableInstructions: Added support for editing labelOverride, stepsBefore,
  and stepsAfter fields with organized sections
- TranslationApproval: Updated German side to display base recipe reference
  fields (labelOverride, items/steps before/after) in read-only view

Users can now edit all auto-translated fields in base recipe references
including additional ingredients/instructions added before or after the
base recipe content.
2026-01-04 20:54:49 +01:00
7e66445312 fix: ensure base recipe references display correctly in English and auto-translate
All checks were successful
CI / update (push) Successful in 1m11s
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
545bd97959 fix: ensure edit modals close properly on Enter and Escape
All checks were successful
CI / update (push) Successful in 1m12s
- Add setTimeout to defer modal.close() to next tick for proper Svelte binding updates
- Add HTMLDialogElement type casting with null checks for modal elements
- Add cancel event handlers to reset state when Escape is pressed
- Ensures modals close reliably when Enter is pressed to submit
- Prevents orphaned state when modals are dismissed with Escape
2026-01-04 15:28:46 +01:00
b67e2434b5 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
2696f09653 feat: add lock icons to restricted links on homepage
All checks were successful
CI / update (push) Successful in 1m10s
Add small lock icons in the top right corner of links that require authentication (streaming, family photos, cloud, shopping, family tree, transmission, documents, and audiobooks). The icons use SVG symbol references for efficient reuse and adapt to dark mode automatically.
2026-01-03 22:49:22 +01:00
efb548511f feat: add untranslated recipes page for recipe admins
All checks were successful
CI / update (push) Successful in 1m9s
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
191a1879d8 fix: sync language selector with browser back/forward navigation
All checks were successful
CI / update (push) Successful in 1m10s
Replace non-reactive window.location.pathname with SvelteKit's reactive $page store to ensure language selector updates when navigating via browser back/forward buttons.
2026-01-03 19:39:15 +01:00
72f0713ecc fix: mark favorites with isFavorite flag to prevent filter from hiding them
All checks were successful
CI / update (push) Successful in 1m10s
2026-01-03 16:16:33 +01:00