Cleaning up unused files
This commit is contained in:
323
app.js
323
app.js
@@ -1,323 +0,0 @@
|
|||||||
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");
|
|
||||||
|
|
||||||
const orgRoamBtn2 = document.getElementById("orgRoamBtn2");
|
|
||||||
|
|
||||||
let emacsEventSource = null;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
ORG ROAM BUILD 2 (EXAMPLE OF SECOND BUILD BUTTON)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
async function rerunEmacs() {
|
|
||||||
|
|
||||||
if (!confirm("Rerun Emacs now?")) return;
|
|
||||||
|
|
||||||
orgRoamBtn2.disabled = true;
|
|
||||||
orgRoamResult.textContent = "🔄 Running Emacs...";
|
|
||||||
roamDot.className = "dot yellow";
|
|
||||||
orgRoamLogs.textContent = "";
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
const res = await fetch("/api/rerun-emacs", { method: "POST" });
|
|
||||||
if (!res.ok) throw new Error();
|
|
||||||
|
|
||||||
closeStream(emacsEventSource);
|
|
||||||
|
|
||||||
startLogStream("/api/rerun-emacs/logs", orgRoamLogs, src => emacsEventSource = src);
|
|
||||||
|
|
||||||
pollEmacsStatus();
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
orgRoamResult.textContent = "❌ Could not start Emacs";
|
|
||||||
orgRoamBtn2.disabled = false;
|
|
||||||
roamDot.className = "dot red";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
async function pollEmacsStatus() {
|
|
||||||
|
|
||||||
const interval = setInterval(async () => {
|
|
||||||
|
|
||||||
const res = await fetch("/api/rerun-emacs/status");
|
|
||||||
const status = await res.json();
|
|
||||||
|
|
||||||
if (!status.running) {
|
|
||||||
|
|
||||||
clearInterval(interval);
|
|
||||||
closeStream(emacsEventSource);
|
|
||||||
|
|
||||||
orgRoamBtn2.disabled = false;
|
|
||||||
|
|
||||||
if (status.lastExitCode === 0 || status.lastExitCode === 124) {
|
|
||||||
|
|
||||||
orgRoamResult.textContent = "✅ Emacs completed";
|
|
||||||
roamDot.className = "dot green";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
orgRoamResult.textContent =
|
|
||||||
"⚠ Emacs 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);
|
|
||||||
orgRoamBtn2.addEventListener("click", rerunEmacs);
|
|
||||||
253
app.js~
253
app.js~
@@ -1,253 +0,0 @@
|
|||||||
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
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
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);
|
|
||||||
44
index.html~
44
index.html~
@@ -1,44 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Server Zone</title>
|
|
||||||
<link rel="stylesheet" href="style.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<main class="container">
|
|
||||||
<h1>Server Zone</h1>
|
|
||||||
|
|
||||||
<!-- Status Section -->
|
|
||||||
<section class="card">
|
|
||||||
<h2>Status</h2>
|
|
||||||
<p>
|
|
||||||
Server Status:
|
|
||||||
<span id="status" class="badge neutral">Loading...</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Health:
|
|
||||||
<span id="health" class="badge neutral">Loading...</span>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="card">
|
|
||||||
<h2>Build</h2>
|
|
||||||
<button id="buildBtn">Run Build Script</button>
|
|
||||||
<p id="buildResult" class="muted">Idle</p>
|
|
||||||
|
|
||||||
<pre id="logOutput" class="log-box"></pre>
|
|
||||||
</section>
|
|
||||||
<section class="card">
|
|
||||||
<h2>Org Roam</h2>
|
|
||||||
<button id="orgRoamBtn">Run Org Roam Make</button>
|
|
||||||
<p id="orgRoamResult" class="muted">Idle</p>
|
|
||||||
<pre id="orgRoamLogs" class="log-box"></pre>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<script src="app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
185
style.css
185
style.css
@@ -1,185 +0,0 @@
|
|||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: system-ui, -apple-system, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
background: #0f172a;
|
|
||||||
color: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 900px;
|
|
||||||
margin: 2rem auto;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: #020617;
|
|
||||||
border: 1px solid #1e293b;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 1.2rem;
|
|
||||||
margin-bottom: 1.2rem;
|
|
||||||
transition: 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover {
|
|
||||||
border-color: #334155;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global Banner */
|
|
||||||
|
|
||||||
.global-ok {
|
|
||||||
background: #064e3b;
|
|
||||||
padding: 0.8rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.global-error {
|
|
||||||
background: #7f1d1d;
|
|
||||||
padding: 0.8rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overview */
|
|
||||||
|
|
||||||
.overview {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.green { background: #22c55e; }
|
|
||||||
.red { background: #ef4444; }
|
|
||||||
.yellow { background: #eab308; }
|
|
||||||
|
|
||||||
/* Buttons */
|
|
||||||
|
|
||||||
button {
|
|
||||||
background: #1d4ed8;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 0.6rem 1rem;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:disabled {
|
|
||||||
background: #475569;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggleLogs {
|
|
||||||
background: transparent;
|
|
||||||
color: #94a3b8;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Badges */
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
padding: 0.2rem 0.6rem;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.ok {
|
|
||||||
background: #166534;
|
|
||||||
color: #dcfce7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.error {
|
|
||||||
background: #7f1d1d;
|
|
||||||
color: #fee2e2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.neutral {
|
|
||||||
background: #334155;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Logs */
|
|
||||||
|
|
||||||
.log-box {
|
|
||||||
background: #111;
|
|
||||||
color: #22c55e;
|
|
||||||
padding: 1rem;
|
|
||||||
height: 250px;
|
|
||||||
overflow-y: auto;
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.muted {
|
|
||||||
color: #94a3b8;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mobile */
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.overview {
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.quick-links {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
|
||||||
gap: 1rem;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-card {
|
|
||||||
background: #111827;
|
|
||||||
border: 1px solid #1e293b;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 10px;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
color: #e5e7eb;
|
|
||||||
transition: 0.2s ease;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-card:hover {
|
|
||||||
background: #1e293b;
|
|
||||||
transform: translateY(-3px);
|
|
||||||
}
|
|
||||||
.daily-message {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-style: italic;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
79
style.css~
79
style.css~
@@ -1,79 +0,0 @@
|
|||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: system-ui, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: #0f172a;
|
|
||||||
color: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 2rem auto;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: #020617;
|
|
||||||
border: 1px solid #1e293b;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 1rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background: #1d4ed8;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:disabled {
|
|
||||||
background: #475569;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
padding: 0.15rem 0.5rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.ok {
|
|
||||||
background: #166534;
|
|
||||||
color: #dcfce7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.error {
|
|
||||||
background: #7f1d1d;
|
|
||||||
color: #fee2e2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge.neutral {
|
|
||||||
background: #334155;
|
|
||||||
color: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.muted {
|
|
||||||
color: #94a3b8;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
.log-box {
|
|
||||||
margin-top: 1rem;
|
|
||||||
background: #000;
|
|
||||||
color: #00ff88;
|
|
||||||
padding: 1rem;
|
|
||||||
height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user