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
This commit is contained in:
Daniel Volz
2026-02-20 18:52:59 +01:00
committed by GitHub
parent 89d565bc9d
commit 052751b2ba
74 changed files with 8815 additions and 4027 deletions
+98 -13
View File
@@ -76,7 +76,7 @@
"emptyStock_other": "{{count}} Medikamente leer",
"lowWarning": "{{count}} Medikament kritisch niedrig",
"lowWarning_other": "{{count}} Medikamente kritisch niedrig",
"waitingFirstCheck": "Warte auf erste Prüfung",
"waitingFirstCheck": "Warte auf die erste Prüfung",
"type": "Typ",
"typeStock": "Bestand",
"typeIntake": "Einnahme",
@@ -152,14 +152,16 @@
}
},
"form": {
"editEntry": "Medikament bearbeiten",
"viewEntry": "Medikament ansehen",
"editEntry": "Bearbeiten",
"viewEntry": "Ansehen",
"newEntry": "Neues Medikament",
"badge": "Packungen + lose Tabletten",
"sections": {
"general": "Allgemein",
"stock": "Bestand & Dosis",
"prescription": "Rezept"
"stock": "Package",
"prescription": "Rezept",
"prescriptionAndRefill": "Rezept & Nachfüllen",
"schedule": "Einnahme"
},
"commercialName": "Handelsname",
"genericName": "Wirkstoff",
@@ -175,7 +177,7 @@
"loosePills": "Lose Tabletten",
"pillWeight": "Dosis pro Tablette",
"total": "Gesamt (Tabletten)",
"medicationStartDate": "Medikations-Startdatum",
"medicationStartDate": "Startdatum der Medikation",
"expiryDate": "Ablaufdatum",
"notes": "Notizen",
"medicationImage": "Medikamentenbild",
@@ -240,7 +242,7 @@
"stockReminders": "Bestands-Erinnerungen",
"intakeReminders": "Einnahme-Erinnerungen",
"prescriptionReminders": "Rezept-Erinnerungen",
"enableHint": "Aktivieren Sie mindestens einen Kanal, um Benachrichtigungen zu erhalten.",
"enableHint": "Aktiviere mindestens einen Kanal, um Benachrichtigungen zu erhalten.",
"skipTakenDoses": "Keine Erinnerungen für genommene Dosen",
"skipTakenDosesTooltip": "Sende keine Einnahme-Erinnerungen für Dosen, die heute bereits als genommen markiert wurden",
"repeatReminders": "Wiederholte Erinnerungen für verpasste Dosen",
@@ -279,7 +281,7 @@
"automatic": "Automatisch",
"automaticDesc": "Bestand wird automatisch anhand des Einnahmeplans reduziert",
"manual": "Manuell",
"manualDesc": "Bestand wird nur reduziert wenn Dosen als genommen markiert werden",
"manualDesc": "Bestand wird nur reduziert, wenn Dosen als genommen markiert werden",
"thresholds": "Schwellenwerte",
"criticalStockDays": "Kritisch (Tage)",
"criticalStockTooltip": "Bestand unter diesem Wert ist kritisch und erfordert sofortige Aufmerksamkeit",
@@ -287,10 +289,22 @@
"lowStockTooltip": "Bestand unter diesem Wert bedeutet, dass bald nachbestellt werden sollte",
"highStockDays": "Hoch (Tage)",
"highStockTooltip": "Bestand über diesem Wert bedeutet, dass du gut versorgt bist",
"thresholdValidation": "Werte müssen sein: Kritisch < Niedrig < Hoch",
"thresholdValidation": "Werte müssen wie folgt sein: Kritisch < Niedrig < Hoch",
"shareStockStatus": "Bestand auf geteilten Links anzeigen",
"shareStockStatusDesc": "Bestandsstatus (Normal/Niedrig/Kritisch) und farbige Rahmen auf geteilten Zeitplan-Links für Einnahme-Nutzer anzeigen"
},
"timeline": {
"title": "Allgemeine UI",
"upcomingSection": "Bevorstehender Zeitplan",
"upcomingTodayOnly": "Nur heute anzeigen",
"upcomingTodayOnlyDesc": "Vergangene und zukünftige Tage ausblenden und im Dashboard nur den heutigen Zeitplan anzeigen.",
"dashboardSectionOrder": "Dashboard-Layout",
"swapDashboardSections": "Bevorstehenden Zeitplan vor Medikamentenübersicht anzeigen",
"swapDashboardSectionsDesc": "Wenn aktiviert, wird der Bereich mit bevorstehenden Einnahmen über der Medikamentenübersicht angezeigt.",
"sharedSection": "Geteilter Zeitplan",
"shareScheduleTodayOnly": "Geteilte Links zeigen nur heute",
"shareScheduleTodayOnlyDesc": "Vergangene und zukünftige Tage in geteilten Zeitplänen ausblenden und nur heutige Einträge zeigen."
},
"stockReminder": {
"title": "Bestands-Erinnerung",
"description": "Bestands-Erinnerungen aktivieren",
@@ -349,7 +363,8 @@
},
"dose": {
"takenBy": "eingenommen von",
"markAsTaken": "Als eingenommen markieren"
"markAsTaken": "Als eingenommen markieren",
"take": "Nehmen"
},
"auth": {
"login": "Anmelden",
@@ -377,7 +392,7 @@
"checkEmail": "E-Mail überprüfen",
"resetEmailSent": "Falls ein Konto mit dieser E-Mail existiert, haben wir einen Link zum Zurücksetzen gesendet.",
"passwordReset": "Passwort zurückgesetzt",
"passwordResetSuccess": "Ihr Passwort wurde zurückgesetzt. Weiterleitung zur Anmeldung...",
"passwordResetSuccess": "Dein Passwort wurde zurückgesetzt. Weiterleitung zur Anmeldung...",
"profileUpdated": "Profil erfolgreich aktualisiert",
"rememberMe": "Angemeldet bleiben",
"localAccount": "Lokales Konto",
@@ -414,7 +429,7 @@
"maxLength": "Maximal {{max}} Zeichen ({{current}}/{{max}})",
"tooLong": "{{current}}/{{max}} Zeichen"
},
"saved": "Gespeichert",
"saved": "Gespeichert",
"save": "Speichern",
"back": "Zurück",
"cancel": "Abbrechen",
@@ -476,7 +491,7 @@
}
},
"exportImport": {
"title": "Daten Export / Import",
"title": "Datenexport / -import",
"description": "Sichere deine Daten oder übertrage sie auf ein anderes Gerät.",
"exportTitle": "Export",
"exportDesc": "Lade alle deine Daten als JSON-Datei herunter.",
@@ -540,11 +555,19 @@
},
"editStock": {
"title": "Bestand korrigieren",
"buttonLabel": "Bestand/Angebrochene Blister korrigieren",
"hint": "Dies ist für die Korrektur von Bestandsabweichungen. Für normale Bestandsänderungen nutze 'Nachfüllen'.",
"totalPills": "Gesamte Tabletten",
"fullBlisters": "Volle Blister",
"partialBlisterPills": "Angebrochener Blister",
"loosePills": "Lose Tabletten",
"pillsPerBlister": "(je {{count}} Tabletten)",
"packageSize": "Packungsgröße: {{count}} Tabletten",
"packageSizeBreakdown": "{{packCount}} x {{sizePerPack}} Tabletten Packung = {{total}} Tabletten",
"currentComposition": "Aktueller Bestand: {{fullBlisters}} volle Blister + {{partialPills}} angebrochen + {{loosePills}} lose = {{total}} Tabletten",
"maxExceeded": "Die maximale Packungsgröße beträgt {{count}} Tabletten. Werte wurden begrenzt.",
"decreaseValue": "Wert verringern",
"increaseValue": "Wert erhöhen",
"currentTotal": "Aktueller Bestand",
"newTotal": "Neuer Bestand",
"difference": "Differenz",
@@ -569,5 +592,67 @@
"copyright": "© {{year}} Daniel Volz",
"madeWith": "Mit ❤️ erstellt für besseres Gesundheitsmanagement",
"techStack": "Entwickelt mit React, Fastify & SQLite"
},
"report": {
"button": "Bericht",
"title": "Medikamentenbericht",
"description": "Erstelle ein Dokument mit detaillierten Medikamenteninformationen für deinen Arzt oder deine persönlichen Unterlagen.",
"selectAll": "Alle auswählen",
"deselectAll": "Alle abwählen",
"activeMeds": "Aktive Medikamente",
"obsoleteMeds": "Obsolete Medikamente",
"format": "Format",
"formatTxt": "Klartext (.txt)",
"formatMd": "Markdown (.md)",
"formatPdf": "PDF (Drucken)",
"generate": "Erstellen",
"generating": "Wird erstellt...",
"noSelection": "Wähle mindestens ein Medikament aus",
"filterByPerson": "Bericht für",
"allPeople": "Alle Personen",
"docTitle": "Medikamentenbericht",
"docGenerated": "Erstellt am",
"docGeneral": "Allgemein",
"docCommercialName": "Handelsname",
"docGenericName": "Wirkstoff",
"docTakenBy": "Eingenommen von",
"docStartDate": "Startdatum",
"docObsoleteSince": "Obsolet seit",
"docStatus": "Status",
"docStatusActive": "Aktiv",
"docStatusObsolete": "Obsolet",
"docPackage": "Verpackung",
"docPackageType": "Verpackungsart",
"docBlister": "Blisterpackung",
"docBottle": "Pillendose",
"docPacks": "Packungen",
"docBlistersPerPack": "Blister pro Packung",
"docPillsPerBlister": "Tabletten pro Blister",
"docTotalCapacity": "Gesamtkapazität",
"docCurrentStock": "Aktueller Bestand",
"docLoosePills": "Lose Tabletten",
"docDose": "Dosis",
"docDosePerPill": "Dosis pro Tablette",
"docExpiryDate": "Ablaufdatum",
"docNotes": "Notizen",
"docIntakeSchedule": "Einnahmeplan",
"docIntakeEntry": "{{usage}} Tablette(n) alle {{every}} Tag(e) ab {{start}}",
"docIntakeTakenBy": "eingenommen von {{person}}",
"docIntakeReminder": "Erinnerung aktiv",
"docPrescription": "Rezept",
"docAuthorizedRefills": "Genehmigte Nachfüllungen",
"docRemainingRefills": "Verbleibende Nachfüllungen",
"docPrescriptionExpiry": "Rezeptablauf",
"docIntakeHistory": "Einnahme-Verlauf",
"docDosesTaken": "Eingenommene Dosen",
"docDosesDismissed": "Verworfene Dosen",
"docFirstDose": "Erste Dosis",
"docLastDose": "Letzte Dosis",
"docRefillHistory": "Nachfüll-Verlauf",
"docRefillEntry": "{{date}}: +{{packs}} Packungen, +{{loose}} Tabletten",
"docRefillPrescription": "(Rezept-Nachfüllung)",
"docNoRefills": "Keine Nachfüllungen erfasst",
"docNoDoses": "Keine Dosen erfasst",
"docPrintInstruction": "Nutze die Druckfunktion deines Browsers (Strg+P / ⌘P) um als PDF zu speichern."
}
}
+99 -14
View File
@@ -70,10 +70,10 @@
"inDays_one": "in {{days}} day",
"inDays_other": "in {{days}} days",
"noRemindersNeeded": "No reminders needed",
"needRefill": "{{count}} med needs refill",
"needRefill_other": "{{count}} meds need refill",
"emptyStock": "{{count}} med is empty",
"emptyStock_other": "{{count}} meds are empty",
"needRefill": "{{count}} medication needs refill",
"needRefill_other": "{{count}} medications need refill",
"emptyStock": "{{count}} medication is empty",
"emptyStock_other": "{{count}} medications are empty",
"lowWarning": "{{count}} medication running critically low",
"lowWarning_other": "{{count}} medications running critically low",
"waitingFirstCheck": "Waiting for first check",
@@ -84,10 +84,10 @@
"channelEmail": "Email",
"channelPush": "Push",
"channelBoth": "Email + Push",
"criticalMeds": "{{count}} medication critical",
"criticalMeds_other": "{{count}} medications critical",
"lowMeds": "{{count}} medication low",
"lowMeds_other": "{{count}} medications low",
"criticalMeds": "{{count}} medication is critical",
"criticalMeds_other": "{{count}} medications are critical",
"lowMeds": "{{count}} medication is low",
"lowMeds_other": "{{count}} medications are low",
"prescriptionNeeds": "Prescription low",
"prescriptionLowMeds": "{{count}} prescription low",
"prescriptionLowMeds_other": "{{count}} prescriptions low",
@@ -152,14 +152,16 @@
}
},
"form": {
"editEntry": "Edit medication",
"viewEntry": "View medication",
"editEntry": "Edit",
"viewEntry": "View",
"newEntry": "New medication",
"badge": "Packs + loose pills",
"sections": {
"general": "General",
"stock": "Stock & Dose",
"prescription": "Prescription"
"stock": "Package",
"prescription": "Prescription",
"prescriptionAndRefill": "Rx & Refill",
"schedule": "Schedule"
},
"commercialName": "Commercial Name",
"genericName": "Generic Name",
@@ -291,6 +293,18 @@
"shareStockStatus": "Show Stock on Shared Links",
"shareStockStatusDesc": "Show stock status (Normal/Low/Critical) and colored borders on shared schedule links for intake users"
},
"timeline": {
"title": "General UI",
"upcomingSection": "Upcoming Schedule",
"upcomingTodayOnly": "Show only today",
"upcomingTodayOnlyDesc": "Hide past and future days and show only today's schedule on the dashboard.",
"dashboardSectionOrder": "Dashboard Layout",
"swapDashboardSections": "Show Upcoming Schedules before Medication Overview",
"swapDashboardSectionsDesc": "When enabled, the dashboard prioritizes the upcoming schedule section above the medication overview section.",
"sharedSection": "Shared Schedule",
"shareScheduleTodayOnly": "Shared links show only today",
"shareScheduleTodayOnlyDesc": "Hide past and future days on shared schedule links and show only today's entries."
},
"stockReminder": {
"title": "Stock Reminder",
"description": "Enable stock reminders",
@@ -349,7 +363,8 @@
},
"dose": {
"takenBy": "taken by",
"markAsTaken": "Mark as taken"
"markAsTaken": "Mark as taken",
"take": "Take"
},
"auth": {
"login": "Login",
@@ -414,7 +429,7 @@
"maxLength": "Maximum {{max}} characters ({{current}}/{{max}})",
"tooLong": "{{current}}/{{max}} characters"
},
"saved": "Saved",
"saved": "Saved",
"save": "Save",
"back": "Back",
"cancel": "Cancel",
@@ -540,11 +555,19 @@
},
"editStock": {
"title": "Correct Stock",
"buttonLabel": "Correct Stock/Partial Blister",
"hint": "This is for correcting stock discrepancies. For regular stock changes, use 'Refill'.",
"totalPills": "Total pills",
"fullBlisters": "Full blisters",
"partialBlisterPills": "Partial blister",
"loosePills": "Loose pills",
"pillsPerBlister": "({{count}} pills each)",
"packageSize": "Package size: {{count}} pills",
"packageSizeBreakdown": "{{packCount}} x {{sizePerPack}} pills Pack = {{total}} pills",
"currentComposition": "Current stock: {{fullBlisters}} full blisters + {{partialPills}} partial + {{loosePills}} loose = {{total}} pills",
"maxExceeded": "Maximum package size is {{count}} pills. Values were capped.",
"decreaseValue": "Decrease value",
"increaseValue": "Increase value",
"currentTotal": "Current total",
"newTotal": "New total",
"difference": "Difference",
@@ -569,5 +592,67 @@
"copyright": "© {{year}} Daniel Volz",
"madeWith": "Made with ❤️ for better health management",
"techStack": "Built with React, Fastify & SQLite"
},
"report": {
"button": "Report",
"title": "Medication Report",
"description": "Generate a document with detailed medication information for your doctor or personal records.",
"selectAll": "Select all",
"deselectAll": "Deselect all",
"activeMeds": "Active Medications",
"obsoleteMeds": "Obsolete Medications",
"format": "Format",
"formatTxt": "Plain Text (.txt)",
"formatMd": "Markdown (.md)",
"formatPdf": "PDF (Print)",
"generate": "Generate",
"generating": "Generating...",
"noSelection": "Select at least one medication",
"filterByPerson": "Report for",
"allPeople": "Everyone",
"docTitle": "Medication Report",
"docGenerated": "Generated on",
"docGeneral": "General",
"docCommercialName": "Commercial Name",
"docGenericName": "Generic Name",
"docTakenBy": "Taken by",
"docStartDate": "Start Date",
"docObsoleteSince": "Obsolete Since",
"docStatus": "Status",
"docStatusActive": "Active",
"docStatusObsolete": "Obsolete",
"docPackage": "Package",
"docPackageType": "Package Type",
"docBlister": "Blister Pack",
"docBottle": "Pill Bottle",
"docPacks": "Packs",
"docBlistersPerPack": "Blisters per pack",
"docPillsPerBlister": "Pills per blister",
"docTotalCapacity": "Total capacity",
"docCurrentStock": "Current stock",
"docLoosePills": "Loose pills",
"docDose": "Dose",
"docDosePerPill": "Dose per pill",
"docExpiryDate": "Expiry Date",
"docNotes": "Notes",
"docIntakeSchedule": "Intake Schedule",
"docIntakeEntry": "{{usage}} pill(s) every {{every}} day(s) from {{start}}",
"docIntakeTakenBy": "taken by {{person}}",
"docIntakeReminder": "reminder enabled",
"docPrescription": "Prescription",
"docAuthorizedRefills": "Authorized refills",
"docRemainingRefills": "Remaining refills",
"docPrescriptionExpiry": "Prescription expiry",
"docIntakeHistory": "Intake History",
"docDosesTaken": "Doses taken",
"docDosesDismissed": "Doses dismissed",
"docFirstDose": "First dose",
"docLastDose": "Last dose",
"docRefillHistory": "Refill History",
"docRefillEntry": "{{date}}: +{{packs}} packs, +{{loose}} pills",
"docRefillPrescription": "(prescription refill)",
"docNoRefills": "No refills recorded",
"docNoDoses": "No doses recorded",
"docPrintInstruction": "Use your browser's Print function (Ctrl+P / ⌘P) to save as PDF."
}
}