Files
appServerPortalUI/public/app.js
2026-03-23 07:25:13 +01:00

161 lines
4.6 KiB
JavaScript
Executable File

// ==== FRONTEND app.js ====
// Service-Liste
const services = [
{ id: "abc", name: "Control GamePad", url: "https://tccontrol.server.schooltech.ch/" },
{ id: "xyz", name: "Guacamole", url: "https://rp5guac.server.schooltech.ch/" },
{ id: "sim", name: "Simulation", url: "https://tcSimulation.server.schooltech.ch/" },
{ id: "video", name: "Video", url: "https://robotVideo.server.schooltech.ch/" },
{ id: "homing", name: "Homing", url:"https://robotHoming.server.schooltech.ch/"}
];
// DOM-Elemente
const iframe = document.getElementById("service-frame");
const loginModal = document.getElementById("login-modal");
const loginBtn = document.getElementById("login-btn");
const loginSubmit = document.getElementById("login-submit");
const loginMsg = document.getElementById("login-msg");
const nav = document.getElementById("services");
const usernameInput = document.getElementById("username");
const passwordInput = document.getElementById("password");
let loggedIn = false;
// ===========================
// Login anzeigen
// ===========================
function switchToLogin() {
loginBtn.textContent = "Login";
loginBtn.onclick = () => {
loginModal.style.display = "block";
};
}
// ===========================
// Logout anzeigen
// ===========================
function switchToLogout() {
loginBtn.textContent = "Logout";
loginBtn.onclick = async () => {
try {
await fetch("/api/logout", { method: "POST" });
} catch (e) {
console.warn("Logout request failed:", e);
}
performLocalLogout();
};
}
// ===========================
// Lokales Logout
// ===========================
function performLocalLogout() {
loggedIn = false;
iframe.src = "";
iframe.style.display = "none";
nav.innerHTML = "";
loginModal.style.display = "block";
switchToLogin();
}
// ===========================
// Login-Logik
// ===========================
async function doLogin() {
const user = usernameInput.value;
const pass = passwordInput.value;
try {
const res = await fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user, pass })
});
if (res.ok) {
loggedIn = true;
loginModal.style.display = "none";
loginMsg.textContent = "";
setupServiceButtons();
switchToLogout();
} else {
loginMsg.textContent = "Login fehlgeschlagen";
}
} catch (e) {
loginMsg.textContent = "Fehler: " + e.message;
}
}
loginSubmit.onclick = doLogin;
// Enter-Taste Login
[usernameInput, passwordInput].forEach(input => {
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
doLogin();
}
});
});
// ===========================
// Buttons erzeugen
// ===========================
function setupServiceButtons() {
nav.innerHTML = "";
services.forEach(svc => {
console.log("Service " + svc.name + " wird als Button angefuegt");
const btn = document.createElement("button");
btn.textContent = svc.name;
btn.onclick = async () => {
try {
await fetch('/api/event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event: 'open',
service: svc.id,
url: svc.url
})
});
} catch(e) {
console.error('Event log failed', e);
}
document.querySelectorAll("nav button").forEach(b => b.classList.remove("active"));
btn.classList.add("active");
openService(svc);
};
nav.appendChild(btn);
});
}
// ===========================
// Service öffnen
// ===========================
function openService(svc) {
iframe.src = svc.url;
iframe.style.display = "block";
window.scrollTo(0,0);
}
// ===========================
// Session Status beim Laden prüfen
// ===========================
(async function checkStatus() {
try {
const r = await fetch('/api/status');
if (r.ok) {
loggedIn = true;
setupServiceButtons();
switchToLogout();
} else {
switchToLogin();
}
} catch (e) {
switchToLogin();
}
})();