/** * MobileEditModal - Full-screen edit form for medications (mobile-optimized) * Handles new medication creation and editing existing medications */ import { useTranslation } from "react-i18next"; import type { DoseUnit, FieldErrors, FormBlister, FormIntake, FormState, Medication } from "../types"; import { DOSE_UNITS } from "../types"; import { deriveTotal } from "../utils"; // Field limits for validation const FIELD_LIMITS = { name: { max: 100 }, genericName: { max: 100 }, takenBy: { max: 50 }, notes: { max: 1000 }, }; export interface MobileEditModalProps { show: boolean; editingId: number | null; form: FormState; onFormChange: (form: FormState) => void; fieldErrors: FieldErrors; saving: boolean; formSaved: boolean; formChanged: boolean; hasValidationErrors: boolean; // TakenBy tag input takenByInput: string; onTakenByInputChange: (value: string) => void; existingPeople: string[]; onAddTakenByPerson: (person: string) => void; onRemoveTakenByPerson: (person: string) => void; onTakenByKeyDown: (e: React.KeyboardEvent) => void; // Blister helpers (legacy) onSetBlisterValue: (idx: number, field: keyof FormBlister, value: string) => void; onAddBlister: () => void; onRemoveBlister: (idx: number) => void; // Intake helpers (new - with per-intake takenBy) onSetIntakeValue: (idx: number, field: keyof FormIntake, value: string | boolean) => void; onAddIntake: (takenBy?: string) => void; onRemoveIntake: (idx: number) => void; // Value change handler for numeric fields onHandleValueChange: (field: K, value: string) => void; // Refill state (for edit mode) refillPacks: number; onRefillPacksChange: (value: number) => void; refillLoose: number; onRefillLooseChange: (value: number) => void; refillSaving: boolean; onSubmitRefill: (medId: number) => Promise; // Image handling meds: Medication[]; onUploadMedImage: (medId: number, file: File) => Promise; onDeleteMedImage: (medId: number) => Promise; // Actions onClose: () => void; onResetForm: () => void; onSaveMedication: (e: React.FormEvent) => void; } /** Calculate total pills from form state */ function deriveTotalFromForm(form: FormState) { if (form.packageType === "bottle") { // For bottle type, looseTablets is the current stock return Number(form.looseTablets) || 0; } const packCount = Number(form.packCount) || 0; const blistersPerPack = Number(form.blistersPerPack) || 0; const pillsPerBlister = Number(form.pillsPerBlister) || 1; const looseTablets = Number(form.looseTablets) || 0; return deriveTotal(packCount, blistersPerPack, pillsPerBlister, looseTablets); } export function MobileEditModal({ show, editingId, form, onFormChange, fieldErrors, saving, formSaved, formChanged, hasValidationErrors, takenByInput, onTakenByInputChange, existingPeople, onAddTakenByPerson, onRemoveTakenByPerson, onTakenByKeyDown, onSetBlisterValue, onAddBlister, onRemoveBlister, onSetIntakeValue, onAddIntake, onRemoveIntake, onHandleValueChange, refillPacks, onRefillPacksChange, refillLoose, onRefillLooseChange, refillSaving, onSubmitRefill, meds, onUploadMedImage, onDeleteMedImage, onClose, _onResetForm, onSaveMedication, }: MobileEditModalProps) { const { t } = useTranslation(); if (!show) return null; const currentMed = editingId ? meds.find((m) => m.id === editingId) : null; return (
e.stopPropagation()}>

{editingId ? t("form.editEntry") : t("form.newEntry")}

{ // Check native HTML5 validation first const formElement = e.currentTarget; if (!formElement.checkValidity()) { // Let browser show native validation messages formElement.reportValidity(); e.preventDefault(); return; } onSaveMedication(e); }} > {form.packageType === "blister" ? ( <> ) : ( <> )}

{t("form.total")}: {deriveTotalFromForm(form)} {t("common.pills")}

{/* Refill section - only shown when editing (mobile) */} {editingId && (

{t("refill.title")}

{(refillPacks > 0 || refillLoose > 0) && ( +{refillPacks * Number(form.blistersPerPack || 0) * Number(form.pillsPerBlister || 1) + refillLoose}{" "} {t("common.pills")} )}
)}