Commit Graph

66 Commits

Author SHA1 Message Date
Daniel Volz eba77c9520 fix: preserve frontend medication deep links 2026-05-10 20:25:14 +02:00
Daniel Volz 70f2392a71 fix: harden dashboard notification focus rendering 2026-05-10 15:03:23 +02:00
Daniel Volz ba789f9794 fix: harden dashboard takenBy rendering 2026-05-10 14:22:33 +02:00
Daniel Volz 277fc3e686 fix(refill): stabilize stock and amount package semantics 2026-05-08 11:03:25 +02:00
Daniel Volz 95aec8350a fix(settings): stabilize timezone edit UX and tooltip visibility (#535) 2026-04-10 22:31:22 +02:00
Daniel Volz 401228699f Add searchable timezone settings override for reminder scheduling 2026-04-10 21:08:16 +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 ad48ab6ba7 fix: prefer latest medication data when opening edit 2026-03-30 20:58:35 +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 934519767a fix: restore obsolete actions in timeline views 2026-03-16 21:39:22 +01:00
Daniel Volz 0160ef3ddf fix: restore schedule interaction correctness
* fix: restore schedule interaction correctness

* fix: use scheduled stock timing for historical doses
2026-03-14 20:49:13 +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 105eb7bc0d feat: add shared overview and harden frontend session state (#407) 2026-03-10 06:26:03 +01:00
Daniel Volz 5b6c6abb69 feat: display actual reminder schedule from server config (#386)
- Expose REMINDER_HOUR and REMINDER_MINUTES_BEFORE env values via settings API
- Add reminderHour and reminderMinutesBefore to frontend Settings interface
- Replace hardcoded i18n strings with parameterized translations
- Settings page now shows configured schedule instead of static 6:00 / 15 min
2026-03-06 19:51:19 +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 cd8263e607 fix: align desktop intake labels and form field pairing (#368)
* fix: align desktop intake labels and form field pairing

* chore: align frontend lockfile version and include remaining local changes
2026-03-02 01:33:28 +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 cc22f80209 fix: align frontend types and tests for react 19 (#339) 2026-02-27 01:01:48 +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 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 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 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 0cf1c5353e fix: notification channel toggles snap back after being enabled (#255)
* fix: notification channel toggles snap back after being enabled

The checked props for email/push notification toggles had redundant
conditions (smtpHost/shoutrrrUrl checks) that forced them to false,
causing immediate visual snap-back. Additionally, performSave()
overwrote emailEnabled/shoutrrrEnabled in local state with effective
values, disabling toggles when no SMTP host or Shoutrrr URL was set.

Remove redundant checked prop conditions (disabled attr already handles
interaction gating) and stop overwriting enabled flags in local state
after save.

Closes #250

* fix: remove leaked useModalHistory import from SettingsPage

* fix: update useSettings tests to match new toggle behavior
2026-02-21 17:59:50 +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 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 08a18fc14a fix: improve export filename and import confirmation UX (#232)
Export filename:
- Include username for multi-user/instance distinction
- Include timestamp with time (YYYYMMDD-HHMM) instead of date only
- Example: medassist-export-daniel-20260216-2108.json

Import confirmation:
- Show friendly 'Import Data?' dialog on empty instances instead of
  scary 'Replace All Data?' warning with danger button
- Only show destructive warning when there is existing data to replace
- Use primary button style for empty-state import

Closes #231
2026-02-16 22:20:20 +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
Daniel Volz a016e45ef2 feat: frontend LOG_LEVEL support via logger utility (#209)
- Inject LOG_LEVEL at build time via Vite define (__LOG_LEVEL__, default: warn)
- Create frontend logger utility (frontend/src/utils/logger.ts) mirroring backend API
- Replace all console.error calls with log.error in MedicationsPage, AppContext, Auth
- Supports levels: silent > error > warn > info > debug

Closes #205
2026-02-14 20:28:06 +01:00
Daniel Volz 150be1e114 feat: add prescription refills column to planner table and email (#207)
- Add 6th column 'Prescription refills' to frontend Planner table
- Add matching column to backend planner email (HTML + plaintext)
- Show remaining refills for meds with prescription tracking, '–' otherwise
- Add backend translations for new column header (EN + DE)
- Add frontend i18n keys for prescription refills column
- Update planner tests with medications table schema

Closes #203
2026-02-14 20:21:09 +01:00
Daniel Volz 6ff0ad2745 fix: mobile modal UX improvements (delete confirm, browser-back, z-index) (#206)
- Replace browser confirm() with ConfirmModal for delete confirmation
- Add dedicated history entry for delete dialog so browser back dismisses it
- Track unsaved-changes warning source to restore correct context on cancel
- Add overlayClassName prop to ConfirmModal for nested z-index layering
- Add .nested-confirm CSS class for proper modal stacking
- Add i18n keys for delete confirmation dialog (EN + DE)

Closes #202
2026-02-14 20:17:01 +01:00
Daniel Volz 0ffab23b6d feat: add back button in medication edit header (#201) 2026-02-14 19:22:37 +01:00
Daniel Volz 8273b07231 feat: track number of prescription repeats (#193)
* feat: track prescription repeats and refill reminders

* test: align backend and frontend suites with current prescription and UI behavior

* test: update frontend and backend expectations for latest reminders and refill flow
2026-02-14 19:07:36 +01:00
Daniel Volz edf42bb068 fix: show reminder icon per intake dose in schedule (#198)
* fix: show reminder icon per intake dose in schedule

* test: align schedule reminder icon test with intake-level flag
2026-02-14 18:53:52 +01:00
Daniel Volz 5c09f97cb3 test: improve frontend test coverage (#163)
- Export DashboardPage helper functions for testability
- Add new test files: App, SharedSchedule, AppContext, UnsavedChangesContext, useUnsavedChangesWarning
- Expand existing test coverage for Auth, MedDetailModal, MobileEditModal, DashboardPage, MedicationsPage, PlannerPage, and more
- Add edge case and error handling tests across components, hooks, and pages
2026-02-13 18:34:19 +01:00