From cc22f802095e8dd692a2849dafb2c2121903bfc1 Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Fri, 27 Feb 2026 01:01:48 +0100 Subject: [PATCH] fix: align frontend types and tests for react 19 (#339) --- frontend/package-lock.json | 54 ++++++++----------- frontend/package.json | 8 +-- frontend/src/components/MedicationAvatar.tsx | 5 +- frontend/src/components/MobileEditModal.tsx | 10 ++-- frontend/src/components/SharedSchedule.tsx | 4 +- frontend/src/context/AppContext.tsx | 22 ++++++-- frontend/src/pages/DashboardPage.tsx | 2 +- frontend/src/pages/MedicationsPage.tsx | 3 ++ frontend/src/pages/dashboard-helpers.ts | 9 ++-- .../src/test/components/Lightbox.test.tsx | 2 +- .../test/components/MedDetailModal.test.tsx | 8 +-- .../test/components/MobileEditModal.test.tsx | 4 +- .../test/components/UserFilterModal.test.tsx | 1 + frontend/src/test/context/AppContext.test.tsx | 1 + .../src/test/hooks/useMedications.test.ts | 15 +++++- frontend/src/test/hooks/useRefill.test.ts | 12 +++-- frontend/src/test/hooks/useSettings.test.ts | 4 +- frontend/src/test/hooks/useShare.test.ts | 10 +++- frontend/src/test/setup.ts | 2 +- frontend/src/test/utils/formatters.test.ts | 2 + frontend/src/test/utils/ics.test.ts | 11 ++-- frontend/src/test/utils/schedule.test.ts | 47 +++++++++++++++- frontend/src/utils/stock.ts | 4 +- 23 files changed, 166 insertions(+), 74 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e237a7e..700dd7d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,8 +11,8 @@ "i18next": "^25.8.13", "i18next-browser-languagedetector": "^8.2.1", "lucide-react": "^0.575.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-i18next": "^15.4.1", "react-router-dom": "^7.13.1", "zod": "^4.3.6" @@ -24,8 +24,8 @@ "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/node": "^25.3.0", - "@types/react": "^18.3.4", - "@types/react-dom": "^18.3.0", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", "@types/react-router-dom": "^5.3.3", "@vitejs/plugin-react": "^5.1.4", "@vitest/coverage-v8": "^4.0.18", @@ -1788,32 +1788,24 @@ "undici-types": "~7.18.0" } }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/react": { - "version": "18.3.27", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", - "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "dev": true, "license": "MIT", "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.2.2" + "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", "dev": true, "license": "MIT", "peerDependencies": { - "@types/react": "^18.0.0" + "@types/react": "^19.2.0" } }, "node_modules/@types/react-router": { @@ -2967,9 +2959,9 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -2979,16 +2971,16 @@ } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.2.0" } }, "node_modules/react-i18next": { @@ -3156,9 +3148,9 @@ } }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" diff --git a/frontend/package.json b/frontend/package.json index 785165d..c1b7382 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,8 +30,8 @@ "i18next": "^25.8.13", "i18next-browser-languagedetector": "^8.2.1", "lucide-react": "^0.575.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-i18next": "^15.4.1", "react-router-dom": "^7.13.1", "zod": "^4.3.6" @@ -43,8 +43,8 @@ "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/node": "^25.3.0", - "@types/react": "^18.3.4", - "@types/react-dom": "^18.3.0", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", "@types/react-router-dom": "^5.3.3", "@vitejs/plugin-react": "^5.1.4", "@vitest/coverage-v8": "^4.0.18", diff --git a/frontend/src/components/MedicationAvatar.tsx b/frontend/src/components/MedicationAvatar.tsx index 2dd679c..68acda5 100644 --- a/frontend/src/components/MedicationAvatar.tsx +++ b/frontend/src/components/MedicationAvatar.tsx @@ -2,7 +2,7 @@ // MedicationAvatar Component // ============================================================================= -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; export type MedicationAvatarProps = { name: string; @@ -12,8 +12,11 @@ export type MedicationAvatarProps = { export function MedicationAvatar({ name, imageUrl, size = "sm" }: MedicationAvatarProps) { const [thumbFailed, setThumbFailed] = useState(false); + const previousImageUrlRef = useRef(imageUrl); useEffect(() => { + if (previousImageUrlRef.current === imageUrl) return; + previousImageUrlRef.current = imageUrl; setThumbFailed(false); }, [imageUrl]); diff --git a/frontend/src/components/MobileEditModal.tsx b/frontend/src/components/MobileEditModal.tsx index 97f5682..d0ce8c2 100644 --- a/frontend/src/components/MobileEditModal.tsx +++ b/frontend/src/components/MobileEditModal.tsx @@ -96,9 +96,9 @@ export function MobileEditModal({ onAddTakenByPerson, onRemoveTakenByPerson, onTakenByKeyDown, - _onSetBlisterValue, - _onAddBlister, - _onRemoveBlister, + onSetBlisterValue: _onSetBlisterValue, + onAddBlister: _onAddBlister, + onRemoveBlister: _onRemoveBlister, onSetIntakeValue, onAddIntake, onRemoveIntake, @@ -108,7 +108,7 @@ export function MobileEditModal({ onDeleteMedImage, imageUploadError, onClose, - _onResetForm, + onResetForm: _onResetForm, onSaveMedication, }: MobileEditModalProps) { const { t } = useTranslation(); @@ -402,7 +402,7 @@ export function MobileEditModal({