import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { FRONTEND_VERSION, GITHUB_URL } from "../App"; interface UpdateCheckResult { status: "checking" | "up-to-date" | "update-available" | "error"; latestVersion?: string; lastChecked?: string; } interface AboutModalProps { isOpen: boolean; onClose: () => void; } export default function AboutModal({ isOpen, onClose }: AboutModalProps) { const { t } = useTranslation(); const [backendVersion, setBackendVersion] = useState(null); const [updateCheckResult, setUpdateCheckResult] = useState(null); // Fetch backend version and cached update result on mount useEffect(() => { if (!isOpen) return; // Fetch backend version fetch("/api/health") .then((res) => res.json()) .then((data) => setBackendVersion(data.version || "unknown")) .catch(() => setBackendVersion("unknown")); // Load cached update check result const cached = sessionStorage.getItem("updateCheckResult"); if (cached) { try { const parsed = JSON.parse(cached); if (parsed && typeof parsed === "object") { setUpdateCheckResult(parsed); } } catch { // ignore } } }, [isOpen]); async function checkForUpdates() { setUpdateCheckResult({ status: "checking" }); try { const res = await fetch(`https://api.github.com/repos/DanielVolz/medassist-ng/releases/latest`); 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; const result: UpdateCheckResult = { status: isUpToDate ? "up-to-date" : "update-available", latestVersion, lastChecked: new Date().toISOString(), }; setUpdateCheckResult(result); // Cache the result sessionStorage.setItem("updateCheckResult", JSON.stringify(result)); } catch { setUpdateCheckResult({ status: "error" }); } } if (!isOpen) return null; return (
e.stopPropagation()}>

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

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

{t("about.frontendVersion", "Frontend")} {FRONTEND_VERSION}
{t("about.backendVersion", "Backend")} {backendVersion || "..."}
{updateCheckResult && updateCheckResult.status !== "checking" && (
{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")} )} {updateCheckResult.lastChecked && ( {t("about.lastChecked", "Last checked")}: {new Date(updateCheckResult.lastChecked).toLocaleString()} )}
)}
{t("about.viewOnGitHub", "View on GitHub")}

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

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

); }