Files
zone/app.js
2026-02-22 22:15:43 +00:00

250 lines
6.8 KiB
JavaScript

const healthEl = document.getElementById("health");
const globalStatus = document.getElementById("globalStatus");
const lastUpdated = document.getElementById("lastUpdated");
const serverDot = document.getElementById("serverDot");
const webDot = document.getElementById("webDot");
const roamDot = document.getElementById("roamDot");
const buildBtn = document.getElementById("buildBtn");
const buildResultEl = document.getElementById("buildResult");
const logOutput = document.getElementById("logOutput");
const orgRoamBtn = document.getElementById("orgRoamBtn");
const orgRoamResult = document.getElementById("orgRoamResult");
const orgRoamLogs = document.getElementById("orgRoamLogs");
let webEventSource = null;
let roamEventSource = null;
/* =========================================
HEALTH
========================================= */
async function fetchHealth() {
try {
const res = await fetch("/api/health");
const text = await res.text();
healthEl.textContent = "Online";
healthEl.className = "badge ok";
serverDot.className = "dot green";
globalStatus.className = "global-ok";
globalStatus.textContent = "🟢 All Systems Running Normally";
lastUpdated.textContent =
"Last checked: " + new Date().toLocaleTimeString();
} catch {
healthEl.textContent = "Offline";
healthEl.className = "badge error";
serverDot.className = "dot red";
globalStatus.className = "global-error";
globalStatus.textContent = "⚠ Attention Required";
}
}
// Auto refresh every 10s
setInterval(fetchHealth, 10000);
/* =========================================
LOG TOGGLE
========================================= */
document.querySelectorAll(".toggleLogs").forEach(btn => {
btn.addEventListener("click", () => {
const target = document.getElementById(btn.dataset.target);
target.classList.toggle("hidden");
btn.textContent =
target.classList.contains("hidden")
? "Show technical details"
: "Hide technical details";
});
});
/* =========================================
STREAM HELPERS
========================================= */
function startLogStream(url, outputEl, setter) {
const source = new EventSource(url);
source.onmessage = (event) => {
outputEl.textContent += event.data + "\n";
outputEl.scrollTop = outputEl.scrollHeight;
};
source.onerror = () => {
source.close();
};
setter(source);
}
function closeStream(source) {
if (source) source.close();
}
/* =========================================
WEBSITE BUILD
========================================= */
async function runWebBuild() {
if (!confirm("This will update the website. Continue?")) return;
buildBtn.disabled = true;
buildResultEl.textContent = "🔄 Updating website...";
webDot.className = "dot yellow";
logOutput.textContent = "";
try {
const res = await fetch("/api/build-web", { method: "POST" });
if (!res.ok) throw new Error();
closeStream(webEventSource);
startLogStream("/api/build-web/logs", logOutput, src => webEventSource = src);
pollWebStatus();
} catch {
buildResultEl.textContent = "❌ Could not start update";
buildBtn.disabled = false;
webDot.className = "dot red";
}
}
async function pollWebStatus() {
const interval = setInterval(async () => {
const res = await fetch("/api/build-web/status");
const status = await res.json();
if (!status.running) {
clearInterval(interval);
closeStream(webEventSource);
buildBtn.disabled = false;
if (status.lastExitCode === 0) {
buildResultEl.textContent = "✅ Website updated successfully";
webDot.className = "dot green";
} else {
buildResultEl.textContent =
"⚠ Update finished with issue (code " + status.lastExitCode + ")";
webDot.className = "dot red";
}
}
}, 2000);
}
/* =========================================
ORG ROAM BUILD
========================================= */
async function runOrgRoamBuild() {
if (!confirm("Refresh the knowledge base?")) return;
orgRoamBtn.disabled = true;
orgRoamResult.textContent = "🔄 Refreshing notes...";
roamDot.className = "dot yellow";
orgRoamLogs.textContent = "";
try {
const res = await fetch("/api/build-roam", { method: "POST" });
if (!res.ok) throw new Error();
closeStream(roamEventSource);
startLogStream("/api/build-roam/logs", orgRoamLogs, src => roamEventSource = src);
pollRoamStatus();
} catch {
orgRoamResult.textContent = "❌ Could not start refresh";
orgRoamBtn.disabled = false;
roamDot.className = "dot red";
}
}
async function pollRoamStatus() {
const interval = setInterval(async () => {
const res = await fetch("/api/build-roam/status");
const status = await res.json();
if (!status.running) {
clearInterval(interval);
closeStream(roamEventSource);
orgRoamBtn.disabled = false;
if (status.lastExitCode === 0) {
orgRoamResult.textContent = "✅ Notes refreshed successfully";
roamDot.className = "dot green";
} else {
orgRoamResult.textContent =
"⚠ Refresh finished with issue (code " + status.lastExitCode + ")";
roamDot.className = "dot red";
}
}
}, 2000);
}
/* =========================================
DAILY MESSAGE
========================================= */
const messages = [
"You are my favourite person.",
];
function setDailyMessage() {
const today = new Date().toDateString();
const index = today.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0) % messages.length;
document.getElementById("dailyMessage").textContent = messages[index];
}
setDailyMessage();
/* =========================================
COUNTDOWN (LIVE - UPDATES EVERY SECOND)
========================================= */
function startCountdown() {
const targetDate = new Date("2026-08-03T00:00:00"); // change this
const label = "Nikah";
const countdownEl = document.getElementById("countdownText");
function updateCountdown() {
const now = new Date();
const diff = targetDate - now;
if (diff <= 0) {
countdownEl.textContent = `${label} is happening now! 🎉`;
clearInterval(interval);
return;
}
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff / (1000 * 60 * 60)) % 24);
const minutes = Math.floor((diff / (1000 * 60)) % 60);
const seconds = Math.floor((diff / 1000) % 60);
countdownEl.textContent =
`${label} in ${days}d ${hours}h ${minutes}m ${seconds}s`;
}
updateCountdown();
const interval = setInterval(updateCountdown, 1000);
}
startCountdown();
/* =========================================
INIT
========================================= */
fetchHealth();
buildBtn.addEventListener("click", runWebBuild);
orgRoamBtn.addEventListener("click", runOrgRoamBuild);