import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { FRONTEND_VERSION, GITHUB_URL } from "../App"; interface UpdateCheckResult { status: "up-to-date" | "update-available" | "error"; latestVersion?: string; } interface AboutModalProps { isOpen: boolean; onClose: () => void; } export default function AboutModal({ isOpen, onClose }: AboutModalProps) { const { t } = useTranslation(); const [isChecking, setIsChecking] = useState(false); const [updateCheckResult, setUpdateCheckResult] = useState(null); // ESC is handled by the global handler in App.tsx to avoid double history.back() // Reset check result when modal opens so stale results are never shown useEffect(() => { if (isOpen) { setUpdateCheckResult(null); } }, [isOpen]); async function checkForUpdates() { setIsChecking(true); const minDelay = new Promise((resolve) => setTimeout(resolve, 1000)); try { const [res] = await Promise.all([ fetch(`https://api.github.com/repos/DanielVolz/medassist-ng/releases/latest`), minDelay, ]); if (!res.ok) throw new Error("Failed to fetch"); const data = await res.json(); const latestVersion = (data.tag_name || "").replace(/^v/, ""); const currentVersion = FRONTEND_VERSION.replace(/^v/, ""); const isUpToDate = latestVersion === currentVersion; setUpdateCheckResult({ status: isUpToDate ? "up-to-date" : "update-available", latestVersion, }); } catch { setUpdateCheckResult({ status: "error" }); } finally { setIsChecking(false); } } if (!isOpen) return null; return (
{ if (e.key !== "Escape") e.stopPropagation(); }} >
e.stopPropagation()} onKeyDown={(e) => { if (e.key !== "Escape") e.stopPropagation(); }} >
MedAssist-ng

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

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

{t("about.version", "Version")} {FRONTEND_VERSION}
{updateCheckResult && (
{updateCheckResult.status === "up-to-date" && ( ✓ {t("about.upToDate", "You are up to date!")} )} {updateCheckResult.status === "update-available" && ( ⬆ {t("about.updateAvailable", "Update available")}:{" "} v{updateCheckResult.latestVersion} {t("about.downloadUpdate", "Download")} )} {updateCheckResult.status === "error" && ( ⚠ {t("about.checkFailed", "Could not check for updates")} )}
)}
{t("about.viewOnGitHub", "View on GitHub")}

{t("about.copyright", "© {{year}} Daniel Volz", { year: new Date().getFullYear() })}

{t("about.license", "GPL-3.0 License")}

); }