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
This commit is contained in:
Daniel Volz
2026-02-15 23:23:38 +01:00
committed by GitHub
parent c47a35d642
commit 4b697374f6
38 changed files with 2042 additions and 907 deletions
+38
View File
@@ -0,0 +1,38 @@
/**
* DateInput - Custom date input that displays dates in the regional locale format.
*
* Overlays a formatted date string on top of a native <input type="date">,
* so the browser calendar popup still works but the displayed text
* uses our locale-aware formatting (e.g., 14.02.2026 for Germany).
*/
import { type InputHTMLAttributes, useCallback, useRef } from "react";
import { formatDate, getNumericLocale } from "../utils/formatters";
interface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}
export function DateInput({ value, placeholder, className, ...rest }: DateInputProps) {
const locale = getNumericLocale();
const displayValue = value ? formatDate(value, locale) : "";
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = useCallback(() => {
try {
inputRef.current?.showPicker();
} catch {
// showPicker() may throw in some browsers — fallback to focus
inputRef.current?.focus();
}
}, []);
return (
<div className={`date-input-wrapper ${className ?? ""}`} onClick={handleClick}>
<span className="date-input-display" aria-hidden="true">
{displayValue || placeholder || ""}
</span>
<input ref={inputRef} type="date" className="date-input-native" value={value} {...rest} />
</div>
);
}