fix: harden dashboard takenBy rendering

This commit is contained in:
Daniel Volz
2026-05-10 14:22:33 +02:00
parent 277fc3e686
commit ba789f9794
2 changed files with 45 additions and 4 deletions
+9 -4
View File
@@ -62,6 +62,11 @@ function findFocusTargetElement(doseId: string | null, medId: string | null): HT
return null;
}
function getDosePeople(takenBy: unknown): Array<string | null> {
const takenByArray = Array.isArray(takenBy) ? takenBy : [];
return takenByArray.length > 0 ? takenByArray : [null];
}
export function DashboardPage() {
const { t, i18n } = useTranslation();
const { user } = useAuth();
@@ -1035,7 +1040,7 @@ export function DashboardPage() {
<div className="doses-col">
{item.doses.map((dose) => {
// If no takenBy, show single checkbox; otherwise show one per person
const people = dose.takenBy.length > 0 ? dose.takenBy : [null];
const people = getDosePeople(dose.takenBy);
const allTaken = people.every((person) =>
isDoseTakenForDisplay(getDoseId(dose.id, person))
);
@@ -1358,7 +1363,7 @@ export function DashboardPage() {
<div className="doses-col">
{item.doses.map((dose) => {
const isOverdue = dose.when < Date.now() && !isEmpty;
const people = dose.takenBy.length > 0 ? dose.takenBy : [null];
const people = getDosePeople(dose.takenBy);
const allTaken = people.every((person) =>
isDoseTakenForDisplay(getDoseId(dose.id, person))
);
@@ -1443,7 +1448,7 @@ export function DashboardPage() {
const totalFutureDoses = futureDays.flatMap((d) =>
d.meds.flatMap((m) =>
m.doses.flatMap((dose) =>
dose.takenBy.length > 0 ? dose.takenBy.map((p) => `${dose.id}-${p}`) : [dose.id]
getDosePeople(dose.takenBy).map((person) => (person ? `${dose.id}-${person}` : dose.id))
)
)
);
@@ -1623,7 +1628,7 @@ export function DashboardPage() {
</div>
<div className="doses-col">
{item.doses.map((dose) => {
const people = dose.takenBy.length > 0 ? dose.takenBy : [null];
const people = getDosePeople(dose.takenBy);
const allTaken = people.every((person) =>
isDoseTakenForDisplay(getDoseId(dose.id, person))
);
@@ -165,6 +165,7 @@ const createMockAppContext = (overrides = {}) => ({
todayDay: null,
futureDays: [],
takenDoses: new Set(),
skippedDoses: new Set(),
dismissedDoses: new Set(),
markDoseTaken: vi.fn(),
undoDoseTaken: vi.fn(),
@@ -385,6 +386,41 @@ describe("DashboardPage", () => {
expect(cards.length).toBeGreaterThan(0);
});
it("renders today doses even when schedule data omits takenBy arrays", () => {
mockContextValue = createMockAppContext({
todayDay: {
dateStr: "Today",
date: new Date(),
isPast: false,
meds: [
{
medName: "Aspirin",
total: 1,
doses: [
{
id: "dose-without-taken-by",
timeStr: "09:00",
when: Date.now() + 60_000,
usage: 1,
takenBy: undefined as unknown as string[],
},
],
lastWhen: Date.now() + 60_000,
},
],
},
});
render(
<MemoryRouter>
<DashboardPage />
</MemoryRouter>
);
expect(screen.getByText(/dashboard\.schedules\.title/i)).toBeInTheDocument();
expect(screen.getByText("09:00")).toBeInTheDocument();
});
it("renders schedule days selector", () => {
render(
<MemoryRouter>