diff --git a/frontend/src/components/MedDetailModal.tsx b/frontend/src/components/MedDetailModal.tsx
index 2952b6d..637be46 100644
--- a/frontend/src/components/MedDetailModal.tsx
+++ b/frontend/src/components/MedDetailModal.tsx
@@ -215,10 +215,8 @@ export function MedDetailModal({
const currentFullBlisters = Math.max(0, stock.fullBlisters);
const currentPartialPills = Math.max(0, stock.openBlisterPills);
const currentLoosePills = Math.max(0, stock.loosePills);
- const pillsPerPack = Math.max(1, selectedMed.blistersPerPack * selectedMed.pillsPerBlister);
- const remainingPacks = Math.max(0, Math.ceil(Math.max(0, currentStock) / pillsPerPack));
const stockDisplayTotal =
- selectedMed.packageType === "bottle" ? (selectedMed.totalPills ?? packageSize) : Math.max(0, currentStock);
+ selectedMed.packageType === "bottle" ? (selectedMed.totalPills ?? packageSize) : Math.max(0, structuralMax);
const maxPartialPills = Math.min(
Math.max(0, selectedMed.pillsPerBlister),
Math.max(0, structuralMax - Math.max(0, editStockFullBlisters) * selectedMed.pillsPerBlister)
@@ -763,7 +761,7 @@ export function MedDetailModal({
<>
{t("modal.packs")}
- {remainingPacks}
+ {selectedMed.packCount}
{t("modal.blistersPerPack")}
@@ -971,44 +969,45 @@ export function MedDetailModal({
)}
)}
- {/* Footer */}
-
-
-
-
+
+ {/* Footer */}
+
+
+
+
+ {onOpenMedicationEdit && (
+
- {onOpenMedicationEdit && (
-
- )}
- {onOpenEditStockModal && (
-
- )}
- {selectedMed.blisters.length > 0 && (
-
- )}
-
+ )}
+ {onOpenEditStockModal && (
+
+ )}
+ {selectedMed.blisters.length > 0 && (
+
+ )}
diff --git a/frontend/src/styles.css b/frontend/src/styles.css
index 5292cb8..1f8e022 100644
--- a/frontend/src/styles.css
+++ b/frontend/src/styles.css
@@ -4684,7 +4684,7 @@ button.has-validation-error {
position: relative;
z-index: 1;
padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
- margin: 0 -2rem;
+ margin: 0;
}
/* Mobile devices can report wide CSS viewports (e.g., 768px in device emulation).
@@ -4912,7 +4912,7 @@ button.has-validation-error {
justify-content: center;
flex-wrap: wrap;
gap: 0.75rem;
- margin: 0 -1.5rem;
+ margin: 0;
}
.med-detail-footer > button {
@@ -4969,9 +4969,8 @@ button.has-validation-error {
margin: 0;
padding-left: 1rem;
padding-right: 1rem;
- position: sticky;
- bottom: 0;
- z-index: 5;
+ position: relative;
+ z-index: 1;
}
}
diff --git a/frontend/src/test/components/MedDetailModal.test.tsx b/frontend/src/test/components/MedDetailModal.test.tsx
index d958add..e1baee5 100644
--- a/frontend/src/test/components/MedDetailModal.test.tsx
+++ b/frontend/src/test/components/MedDetailModal.test.tsx
@@ -216,6 +216,32 @@ describe("MedDetailModal", () => {
const body = document.querySelector(".med-detail-body");
expect(body).toBeInTheDocument();
});
+
+ it("shows configured pack count in package details, independent from current stock", () => {
+ const medWithConfiguredPacks: Medication = {
+ ...mockMedication,
+ packCount: 11,
+ blistersPerPack: 5,
+ pillsPerBlister: 5,
+ };
+
+ const lowCurrentStockCoverage: Coverage = {
+ ...mockCoverage,
+ medsLeft: 47,
+ };
+
+ render(
+
+ );
+
+ const packsLabel = screen.getByText(/modal\.packs/i);
+ const packsValue = packsLabel.closest(".med-detail-item")?.querySelector(".med-detail-value");
+ expect(packsValue?.textContent).toBe("11");
+ });
});
describe("MedDetailModal without coverage", () => {
@@ -744,7 +770,7 @@ describe("MedDetailModal stock overflow warning", () => {
vi.clearAllMocks();
});
- it("does not show overflow warning icon with live stock denominator", () => {
+ it("shows overflow warning icon when stock exceeds blister package capacity", () => {
const overflowCoverage: Coverage = {
name: "Test Med",
medsLeft: 49,
@@ -756,9 +782,9 @@ describe("MedDetailModal stock overflow warning", () => {
render();
- // Live denominator uses current stock, so overflow warning is not shown in detail row.
+ // For blister meds, denominator is package capacity (not current stock), so overflow is shown.
const warningIcon = document.querySelector(".info-tooltip.tooltip-align-left.warning-text");
- expect(warningIcon).not.toBeInTheDocument();
+ expect(warningIcon).toBeInTheDocument();
});
it("does not show warning icon when stock is within package capacity", () => {