Commit Graph

79 Commits

Author SHA1 Message Date
Daniel Volz 6e85b29549 fix: align frontend refill history displays 2026-05-10 18:51:52 +02:00
Daniel Volz e55e695c88 fix: align refill report quantity semantics 2026-05-10 18:51:51 +02:00
Daniel Volz 277fc3e686 fix(refill): stabilize stock and amount package semantics 2026-05-08 11:03:25 +02:00
Daniel Volz eec1653ff4 fix(security): ship isolated JWT decorator hotfix
* fix(security): isolate dependency hotfix from github main

* fix(security): expose hotfix jwt decorators across routes

* test(e2e): restore stable app header selectors

* test(e2e): align planner and app shell checks

* test(e2e): add legacy settings page selectors

* test(e2e): align settings page contracts
2026-04-05 14:49:50 +02:00
Daniel Volz f46043970f refactor: decompose frontend state and medication dialog flows 2026-03-27 06:50:19 +01:00
Daniel Volz 8e2d7e74d2 feat: improve medication enrichment lookup
Squash merge PR #475
2026-03-25 07:03:08 +01:00
Daniel Volz 7059c25f1c fix: align stock and refill semantics
Squash merge PR #474
2026-03-25 06:49:34 +01:00
Daniel Volz b796e03bcb feat: add medication enrichment lookup to the medication editor
* feat: add medication enrichment lookup

* fix: avoid double unescape in enrichment sanitization

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-20 20:39:38 +01:00
Daniel Volz 68ab79c713 feat: enable weekday-based medication scheduling
Closes #463
2026-03-20 14:58:25 +01:00
Daniel Volz 9e224c0441 fix: improve shared schedule stock overview display 2026-03-16 21:33:55 +01:00
Daniel Volz 0f9458b7cb chore: align vite 8 and plugin-react 6 stack
* chore: align vite 8 and plugin-react 6 stack

* fix: remove array index keys from intake rows

* chore: format shared schedule test fix
2026-03-16 08:26:50 +01:00
Daniel Volz e0fb77d494 feat: embed medication overview into shared links
Closes #424
2026-03-14 20:26:17 +01:00
Daniel Volz d0837a7281 feat: stack related date fields and clarify share stock labels (#422)
* feat: stack related date fields and clarify share stock labels

* test: cover stacked date pairs and share labels
2026-03-12 21:32:56 +01:00
Daniel Volz 3fda41e501 fix: restore automatic intake auto-marking (#420) 2026-03-12 21:32:51 +01:00
Daniel Volz 105eb7bc0d feat: add shared overview and harden frontend session state (#407) 2026-03-10 06:26:03 +01:00
Daniel Volz 30c97e2f0d fix: use per-intake reminder setting as single source of truth (#384)
- Filter intakes by per-intake intakeRemindersEnabled instead of falling
  back to medication-level setting (fixes #383)
- Add SMTP delivery validation with accepted/rejected recipient checks
- Enhance email success logging with recipient, messageId, SMTP response
- Simplify MedDetailModal reminder icon logic to match backend behavior
- Sync lockfile versions to 1.18.2
2026-03-06 19:50:45 +01:00
Daniel Volz 4936929849 feat: replace hardcoded package assumptions with profile abstraction (#379) 2026-03-04 21:15:05 +01:00
Daniel Volz 56d244aa61 fix: stabilize frontend e2e selectors and auth/session reliability (#373) 2026-03-02 23:21:57 +01:00
Daniel Volz da004b5c3e fix: align frontend tube/liquid container semantics (#364)
* fix: align frontend tube/liquid container semantics

* test(frontend): fix PR #364 CI regressions
2026-03-02 00:23:32 +01:00
Daniel Volz 9e8a6315e7 fix: keep topical stock non-depleting in planner flows (#359)
* fix: keep topical stock non-depleting in planner and reports

* test: stabilize e2e selectors for updated medication semantics

* fix(backend): add missing planner translation keys
2026-02-28 23:36:52 +01:00
Daniel Volz 8aaeca6b26 feat: simplify tube stock editing UI (#357)
* feat: add package amount persistence and backend route support

* test: align backend test schemas with medication metadata fields

* fix(backend): restore intake usage normalizer for planner endpoint

* fix(backend): keep export typing compatible before liquid-unit stack step

* feat: simplify tube stock editing in desktop and mobile forms
2026-02-28 23:24:48 +01:00
Daniel Volz b009d9e158 fix: frontend nginx restart loop from invalid log_format scope (#350)
* fix: place nginx log_format in valid context

* fix: unblock required checks for nginx hotfix

* fix: restore mandatory doku files in nginx hotfix pr
2026-02-27 01:47:59 +01:00
Daniel Volz ba0ab672b9 docs: update memory and report for multi-pr delivery (#347) 2026-02-27 01:15:40 +01:00
Daniel Volz 57c998ba09 chore: update dependabot automation and agent governance (#341)
* chore: update dependabot automation and agent governance

* chore: trigger required CI checks for governance PR
2026-02-27 01:11:05 +01:00
Daniel Volz cc22f80209 fix: align frontend types and tests for react 19 (#339) 2026-02-27 01:01:48 +01:00
Daniel Volz 19ba4bb7d2 feat: add FORM_LOGIN_ENABLED auth toggle (#334) 2026-02-27 00:48:58 +01:00
Daniel Volz f0496e8ca5 fix: remove duplicate ESC handlers causing double history.back()
AboutModal, ProfileModal, and ShareDialog each had their own
useEscapeKey hook AND were handled by the global ESC handler in
App.tsx. When ESC was pressed, both fired synchronously, calling
history.back() twice — navigating past the current page instead
of just closing the modal.

Removed the per-modal useEscapeKey calls since the global handler
in App.tsx already manages ESC priority for all modals.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-25 23:50:07 +01:00
Daniel Volz d02f16af3a fix: stabilize e2e CI and local playwright workers (#321)
* fix: stabilize e2e CI and local playwright workers

* fix(ci): apply biome formatting and import order for frontend build
2026-02-25 22:15:38 +01:00
Copilot 2a9ca39c24 Allow medications with only a generic name (no commercial name required) (#311)
* Initial plan

* feat: allow generic name only for medications (frontend changes)

- Add getMedDisplayName() helper for consistent name display
- Update validation to require either commercial or generic name
- Update all display locations to use display name fallback
- Add i18n keys for nameOrGenericRequired in en.json and de.json
- Remove required attribute from commercial name field
- Update FIELD_LIMITS.name.min from 1 to 0

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* feat: allow generic name only for medications (backend changes)

- Update Zod schema to allow empty name with cross-field refinement
- Update reminder scheduler to use name || genericName for display
- Update planner routes to match medications by display name
- Update existing tests to match new validation behavior

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* fix: update placeholder text and fix FIELD_LIMITS test

- Remove "(optional)" from generic name placeholder in en/de
- Update types.test.ts to expect FIELD_LIMITS.name.min = 0

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
2026-02-25 21:29:25 +01:00
Daniel Volz 6161c14a7b fix: logo optimization, deprecated meta tag, and clipboard copy fallback (#306)
- Replace 2 MB favicon.svg (base64-PNG-in-SVG) with optimized 43 KB app-logo.png (256x256)
- Update AppHeader and AboutModal references to use new logo
- Remove SVG favicon link from index.html (PNG/ICO favicons remain)
- Fix deprecated apple-mobile-web-app-capable → mobile-web-app-capable meta tag
- Add clipboard copy fallback for non-secure contexts (LAN IP over HTTP)

Closes #303
2026-02-25 00:04:35 +01:00
Daniel Volz 96b2a0c96f feat: image upload optimization with sharp, thumbnails, and structured error codes (#304)
- Add sharp for server-side image processing (WebP conversion + thumbnails)
- New shared backend utility for image upload, optimization, and cleanup
- Return structured error codes from upload endpoints (IMAGE_TOO_LARGE, INVALID_TYPE, etc.)
- Frontend error code mapping with i18n support (EN + DE)
- MedicationAvatar tries thumbnail first, falls back to full image
- Error display in MedicationsPage, MobileEditModal, and Auth avatar upload

Closes #302
2026-02-24 23:52:59 +01:00
Daniel Volz 26475fd3d0 feat: add correlation ids and tighten frontend security headers (#299)
* feat: add correlation ids and tighten frontend security headers

* docs: remove obsolete project setup guide

* fix: restore health config flags for compatibility

* test(frontend): align auth fetch assertions with correlation headers
2026-02-24 21:21:30 +01:00
Daniel Volz ba36f67371 fix: smooth mobile edit transition and align modal validation behavior (#286)
* fix: reliable Escape key close for all modals via useEscapeKey hook

- Add useEscapeKey hook (document-level keydown listener)
- Retrofit all 12 modal/overlay components to use it
- Remove redundant overlay onKeyDown Escape handlers
- Simplify modal-content onKeyDown to plain stopPropagation
- Replace MedDetailModal's capture-phase useEffect with 3 useEscapeKey calls
- Replace SharedSchedule's inline useEffect with useEscapeKey
- Add mandatory modal rules to UI Consistency skill
- All 777 frontend + 569 backend tests pass

* fix: smooth mobile edit transition and align modal validation behavior

* fix: keep overlay keydown non-closing for Enter key

* fix: show mobile name error when validation already exists

* fix: restore app-level escape priority handling

* fix: prioritize schedule lightbox on Escape
2026-02-23 06:42:06 +01:00
Daniel Volz 2aa6b1f406 fix: prevent background scroll when any modal is open (#284)
Replace CSS-only modal-open class toggle with a shared useScrollLock
hook that uses position:fixed + scroll position save/restore. This
reliably prevents background scrolling on all browsers including
iOS Safari.

The hook supports nesting (lock counter) so stacked modals (e.g.
MedDetail → RefillModal) work correctly.

Also adds missing modal states to the scroll lock: showRefillModal,
showEditStockModal, showImageLightbox, scheduleLightboxImage.

Replaces the inline 40-line scroll lock in MobileEditModal with the
shared hook.
2026-02-22 18:40:39 +01:00
Daniel Volz 259f00e7a0 fix: unify number stepper layout and detail modal padding (#279)
Reorder stepper DOM elements (input first) and apply refill-number-stepper
class to both steppers for consistent CSS order-based layout.
Fix missing bottom padding on .med-detail-body.
2026-02-22 17:57:36 +01:00
Daniel Volz 33c1095e77 feat: add FormNumberStepper to medication edit forms (#274)
Replace plain numeric inputs with a reusable +/− stepper component in
both desktop (MedicationsPage) and mobile (MobileEditModal) edit forms.

Applied to Stock, Schedule, and Prescription tab fields. Reorder tabs
so Schedule appears before Prescription. Add responsive grid overrides
for narrow sidebar and compact schedule rows.

Fix label-hover ghost activation by placing <input> first in DOM
(CSS order restores visual [−] [value] [+] layout).

Closes #273
2026-02-22 16:49:51 +01:00
Daniel Volz 9a2d42b8b9 fix: stabilize dashboard modal and image click behavior (#267)
* feat: make medication names clickable in Dashboard dose schedule

Add click handlers to med-name-stack divs in all three dose schedule
sections (past, current/overdue, future) on DashboardPage, opening the
MedDetail modal on click.

Add early-return guards to all four modal openers in AppContext
(openMedDetail, openImageLightbox, openScheduleLightbox, openUserFilter)
to prevent duplicate pushState entries on double-click, which caused
unexpected navigation to the Medications page.

Closes #266

* fix: stabilize dashboard modal and image click handling

* fix: close medication detail on first backdrop click
2026-02-22 10:50:58 +01:00
Daniel Volz 088a6c1a05 chore: fix all Biome lint warnings and MedDetail intake bell icons (#265)
- Backend: refactor nested ternaries, remove unused imports/any types
- Frontend: fix exhaustive deps, a11y label associations, array index keys,
  empty CSS blocks, unused vars, type annotations
- MedDetail modal: fix intake schedule bell icons not rendering (use unified
  intake source with fallback), place bell inline after person name
- MedDetail modal: revert schedule rows from grid to flexbox layout

Closes #264
2026-02-22 08:52:03 +01:00
Daniel Volz afb8e5028c fix: auto-mark intakes at due time and show robot marker (#261)
* fix: auto-mark intakes at due time and show robot marker

* test: add taken_source to integration schema

* test: align e2e route schema with taken_source
2026-02-21 20:45:05 +01:00
Daniel Volz 976d7356ec feat: improve medication detail modal layout and display (#258)
Widen detail modal on desktop (711px, up from 500px) with max-width
override to beat modals-base.css specificity. Limit fullscreen mode
to actual phones (<=500px) instead of all screens <=900px. Move intake
schedule section before prescription details. Show per-intake takenBy
person and bell icon with proper warning color. Right-align time in
schedule rows. Move notes icon after label text. Replace emoji bell
icons with Lucide Bell component in SchedulePage and MobileEditModal.
Add common.on/common.off i18n keys.

Closes #254
2026-02-21 18:00:23 +01:00
Daniel Volz 943148fb49 feat: close modals with browser back button on mobile (#257)
* feat: close modals with browser back button on mobile

Create reusable useModalHistory hook that pushes history state when a
modal opens and listens for popstate to close it. Apply to ReportModal,
ClearMissedConfirm, ExportModal, ImportConfirm, and all modals using
ConfirmModal/ShareDialog/Auth/ExportModal base components. Escape key
handling was already in place for desktop.

Closes #253

* fix: update tests for renamed button labels and missing useModalHistory mock
2026-02-21 18:00:12 +01:00
Daniel Volz 94bd8bd6e8 feat: improve mobile edit modal swipe gestures and tab navigation (#256)
* feat: improve mobile edit modal swipe gestures and tab navigation

Replace React passive touch handlers with native non-passive
addEventListener via useEffect for reliable horizontal swipe blocking.
Reduce axis-lock threshold from 18-26px to 6px for more responsive
gesture detection. Remove isInteractive() guard so swipe works on
input fields. Add tab strip auto-scroll via scrollIntoView when
active tab changes. Fix vertical scrolling by changing readonly
fieldset from display:block to display:flex.

Closes #252

* fix: guard scrollIntoView for jsdom test compatibility
2026-02-21 18:00:02 +01:00
Daniel Volz 75c201cab5 fix: keep med detail stock and package values consistent (#249) 2026-02-21 15:47:44 +01:00
Daniel Volz fd3b770a81 fix: improve mobile edit modal scrolling behavior (#247) 2026-02-21 15:24:57 +01:00
Daniel Volz 612aa007aa fix: unify stock semantics across planner and scheduler (#245)
* fix: unify stock semantics across planner and scheduler

* fix: stabilize dashboard hmr and align stock helper tests
2026-02-21 15:24:53 +01:00
Daniel Volz b489e1e117 fix: keep mobile med detail actions visible while scrolling (#240) 2026-02-20 19:31:59 +01:00
Daniel Volz 052751b2ba feat: reports, timeline toggles, and stock correction improvements (#236)
* refactor(frontend): modularize styles and polish modal/ui interactions

* feat: add report workflow and timeline/settings improvements

* fix: resolve CI failures for backend typing, lint, and playwright config
2026-02-20 18:52:59 +01:00
Daniel Volz 89d565bc9d chore: fix lint errors and reduce warnings across codebase (#234)
* chore: fix lint errors and reduce warnings across codebase

- Fix noExplicitAny catches in backend routes and plugins
- Fix noNestedTernary issues in backend services
- Add keyboard event handlers for useKeyWithClickEvents in frontend
- Disable noImportantStyles rule in biome.json
- Fix formatting errors across all changed files
- Fix test file lint issues

Closes #233

* fix: restore any types in test files for TS compatibility

* fix: revert Auth.tsx dependency array changes that caused infinite re-render

* fix: null-safe user.username access in AppContext dependency array
2026-02-17 05:21:47 +01:00
Daniel Volz 779870960c fix: frontend UI polish — tooltips, planner checkbox, settings layout (#228)
- Fix mobile tooltip positioning (above icon instead of centered)
- Place planner checkbox and send-now button on same row
- Move settings tooltips beside input fields instead of overlapping
- Fix input-with-tooltip layout for narrow screens
- Add daily/everyNDays i18n keys for dose frequency display
- Fix lint formatting in page components

Closes #225
2026-02-16 21:51:51 +01:00
Daniel Volz 4b697374f6 feat: obsolete medication archiving, start date, and UI improvements (#215)
* feat: obsolete medication archiving, start date, and UI improvements

- Add soft-archive (obsolete) for medications with dedicated section and toggle
- Add medication start date field with date picker and validation
- Add obsolete/reactivate API endpoints with proper auth
- Filter obsolete meds from schedule, coverage, planner, and notifications
- Improve UserFilterModal with intake schedules, stock badges, and click-to-open
- Improve dashboard taken-by badges with per-intake bell icons
- Add Escape key support to ConfirmModal and MobileEditModal
- Fix Lightbox close button positioning near image
- Add read-only mode support for MobileEditModal
- DB migrations: 0008 (is_obsolete, obsolete_at), 0009 (medication_start_date)
- All user-facing text uses i18n keys (en + de)

* test: fix tests for obsolete medications and UI changes

- Backend: add is_obsolete, obsolete_at, medication_start_date columns to test schemas
- Backend: add test medication inserts in planner tests for active-med filtering
- Frontend: update useMedications URL to include includeObsolete param
- Frontend: fix MobileEditModal selectors and validation assertions
- Frontend: add onClearUser prop to UserFilterModal test renders
- Frontend: fix MedicationsPage and DashboardPage test assertions
2026-02-15 23:23:38 +01:00