diff --git a/frontend/src/components/TopRightControls.tsx b/frontend/src/components/TopRightControls.tsx new file mode 100644 index 0000000..ac0346e --- /dev/null +++ b/frontend/src/components/TopRightControls.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { useState } from "react"; +import { Github, MessageSquare, Download, AlertCircle, CheckCircle2 } from "lucide-react"; +import packageJson from "../../package.json"; + +export default function TopRightControls() { + const [updateStatus, setUpdateStatus] = useState<"idle" | "checking" | "available" | "uptodate" | "error">("idle"); + const [latestVersion, setLatestVersion] = useState(""); + + const currentVersion = packageJson.version; + + const checkForUpdates = async () => { + setUpdateStatus("checking"); + try { + const res = await fetch("https://api.github.com/repos/BigBodyCobain/Shadowbroker/releases/latest"); + if (!res.ok) throw new Error("Failed to fetch"); + const data = await res.json(); + + // Remove 'v' prefix if it exists to compare semver cleanly + const latest = data.tag_name?.replace('v', '') || data.name?.replace('v', ''); + const current = currentVersion.replace('v', ''); + + if (latest && latest !== current) { + setLatestVersion(latest); + setUpdateStatus("available"); + } else { + setUpdateStatus("uptodate"); + setTimeout(() => setUpdateStatus("idle"), 3000); + } + } catch (err) { + console.error("Update check failed:", err); + setUpdateStatus("error"); + setTimeout(() => setUpdateStatus("idle"), 3000); + } + }; + + return ( +
+ + + DISCUSSIONS + + + {updateStatus === "available" ? ( + + + v{latestVersion} UPDATE! + + ) : ( + + )} +
+ ); +}