diff --git a/frontend/index.html b/frontend/index.html index 5d05918..4d5a586 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,7 +6,6 @@ MedAssist-ng - @@ -14,7 +13,7 @@ - + diff --git a/frontend/public/app-logo.png b/frontend/public/app-logo.png new file mode 100644 index 0000000..45e608c Binary files /dev/null and b/frontend/public/app-logo.png differ diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg deleted file mode 100755 index bf28082..0000000 --- a/frontend/public/favicon.svg +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/components/AboutModal.tsx b/frontend/src/components/AboutModal.tsx index ff37a68..28c4cb4 100644 --- a/frontend/src/components/AboutModal.tsx +++ b/frontend/src/components/AboutModal.tsx @@ -73,7 +73,7 @@ export default function AboutModal({ isOpen, onClose }: AboutModalProps) {
- MedAssist-ng + MedAssist-ng

{t("about.appName", "MedAssist-ng")}

{t("about.description", "Personal medication tracking and reminder app")}

diff --git a/frontend/src/components/AppHeader.tsx b/frontend/src/components/AppHeader.tsx index cc7a213..0ac47ec 100644 --- a/frontend/src/components/AppHeader.tsx +++ b/frontend/src/components/AppHeader.tsx @@ -73,7 +73,7 @@ export function AppHeader({ onOpenProfile, onOpenAbout }: AppHeaderProps) { return (
- MedAssist-ng + MedAssist-ng

{pageInfo.eyebrow}

{pageInfo.title}

diff --git a/frontend/src/hooks/useShare.ts b/frontend/src/hooks/useShare.ts index 8308f0e..40b079b 100644 --- a/frontend/src/hooks/useShare.ts +++ b/frontend/src/hooks/useShare.ts @@ -106,10 +106,40 @@ export function useShare(): UseShareReturn { const copyShareLink = useCallback(() => { if (shareLink) { - navigator.clipboard.writeText(shareLink); - setShareCopied(true); - log.debug("[ShareDialog] Share link copied to clipboard"); - setTimeout(() => setShareCopied(false), 2000); + if (navigator.clipboard?.writeText) { + navigator.clipboard.writeText(shareLink).then( + () => { + setShareCopied(true); + log.debug("[ShareDialog] Share link copied to clipboard"); + setTimeout(() => setShareCopied(false), 2000); + }, + () => { + // Clipboard API blocked (non-secure context / permissions) + fallbackCopyToClipboard(shareLink); + } + ); + } else { + fallbackCopyToClipboard(shareLink); + } + } + + function fallbackCopyToClipboard(text: string) { + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + try { + document.execCommand("copy"); + setShareCopied(true); + log.debug("[ShareDialog] Share link copied via fallback"); + setTimeout(() => setShareCopied(false), 2000); + } catch { + log.warn("[ShareDialog] Clipboard copy failed — not in secure context"); + } finally { + document.body.removeChild(textarea); + } } }, [shareLink]); diff --git a/frontend/src/test/hooks/useShare.test.ts b/frontend/src/test/hooks/useShare.test.ts index 76146c1..494de38 100644 --- a/frontend/src/test/hooks/useShare.test.ts +++ b/frontend/src/test/hooks/useShare.test.ts @@ -14,7 +14,7 @@ describe("useShare", () => { mockAlert = vi.fn(); global.alert = mockAlert; - mockClipboard = { writeText: vi.fn() }; + mockClipboard = { writeText: vi.fn().mockResolvedValue(undefined) }; Object.defineProperty(navigator, "clipboard", { value: mockClipboard, writable: true, @@ -237,7 +237,7 @@ describe("useShare", () => { result.current.setShareLink("http://localhost:5173/share/test-token"); }); - act(() => { + await act(async () => { result.current.copyShareLink(); });