import React, { useEffect, useState } from 'react'; import { ServerContext } from '@/state/server'; import http from '@/api/http'; import { faCube, faSync, faEyeSlash, faCog } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import classNames from 'classnames'; interface StatusData { configured: boolean; platform?: string; modpack_name?: string; current_version?: string; latest_version?: string; update_available?: boolean; last_checked?: string; detection_method?: string; is_ignored?: boolean; } interface Release { file_id: string; version: string; display_name: string; release_date?: string; } const platformIcons: Record = { curseforge: '🔥', modrinth: '🍃', technic: '⚙️', ftb: '📦', }; const ModpackVersionCard: React.FC = () => { const uuid = ServerContext.useStoreState((state) => state.server.data?.uuid); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [checking, setChecking] = useState(false); const [showCalibrate, setShowCalibrate] = useState(false); const [releases, setReleases] = useState([]); const [loadingReleases, setLoadingReleases] = useState(false); // Zero-click: load cached status on mount useEffect(() => { if (!uuid) return; http.get(`/api/client/extensions/modpackchecker/servers/${uuid}/status`) .then((res) => { setData(res.data); setError(null); }) .catch(() => setError('Unable to load modpack status.')) .finally(() => setLoading(false)); }, [uuid]); // Manual refresh const refresh = async () => { if (!uuid || checking) return; setChecking(true); setError(null); try { await http.post(`/api/client/extensions/modpackchecker/servers/${uuid}/check`); const res = await http.get(`/api/client/extensions/modpackchecker/servers/${uuid}/status`); setData(res.data); } catch { setError('Check failed. Try again.'); } setChecking(false); }; // Open calibrate dropdown const openCalibrate = async () => { if (!uuid) return; setShowCalibrate(true); setLoadingReleases(true); try { const res = await http.get(`/api/client/extensions/modpackchecker/servers/${uuid}/releases`); setReleases(res.data.releases || []); } catch { setReleases([]); } setLoadingReleases(false); }; // Select a release to calibrate const selectRelease = async (release: Release) => { if (!uuid) return; try { const res = await http.post(`/api/client/extensions/modpackchecker/servers/${uuid}/calibrate`, { file_id: release.file_id, version: release.version, }); setData((prev) => prev ? { ...prev, current_version: release.version, update_available: res.data.update_available, } : prev); } catch {} setShowCalibrate(false); }; // Ignore server const toggleIgnore = async () => { if (!uuid) return; try { const res = await http.post(`/api/client/extensions/modpackchecker/servers/${uuid}/ignore`); setData((prev) => prev ? { ...prev, is_ignored: res.data.is_ignored } : prev); } catch {} }; if (loading) return null; // Muted card for ignored servers (with Resume button) if (data?.is_ignored) { return (
{data.modpack_name || 'Modpack'} — Updates ignored
); } if (error && !data) return (
{error}
); // Calibrate dropdown (reusable) const renderCalibrateDropdown = () => (

Select your installed version:

{loadingReleases &&

Loading releases...

} {!loadingReleases && releases.length === 0 && (

No releases found

)} {releases.map((r) => ( ))}
); // Pending calibration — show "Identify Version" prompt if (data && !data.configured && data.modpack_name) { return (
{data.modpack_name} — Version unknown
{showCalibrate && renderCalibrateDropdown()}
); } const hasUpdate = data.update_available; const configured = data.configured; // Short name: "All the Mods 9 - ATM9" → "ATM9" const shortName = (data.modpack_name?.includes(' - ') ? data.modpack_name.split(' - ').pop() : data.modpack_name) || 'Modpack'; // Extract semver from version strings (e.g. "All the Mods 9-0.1.0" → "0.1.0") const extractVersion = (v?: string) => { if (!v) return '?'; const match = v.match(/[\d]+\.[\d]+[\d.]*$/); return match ? match[0] : v; }; const bgColor = hasUpdate ? 'bg-orange-500' : configured ? 'bg-cyan-500' : 'bg-gray-700'; const icon = data.platform ? (platformIcons[data.platform] || '📦') : '📦'; return (

{configured ? `${icon} ${data.modpack_name || 'Modpack'}` : 'Modpack Version'}

{configured && ( )}
{!configured && Not detected — waiting for cron} {configured && !hasUpdate && ( ✓ {shortName} — {extractVersion(data.latest_version)} )} {configured && hasUpdate && ( {shortName} {extractVersion(data.current_version)} → {extractVersion(data.latest_version)} ↑ )}
{/* Calibrate dropdown */} {showCalibrate && renderCalibrateDropdown()}
); }; export default ModpackVersionCard;