dok/public/js/map-ui.js
2026-03-29 13:16:05 +01:00

197 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { loadCharacterHouse } from "./buildings/character-house.js";
import { loadBlackmarket } from "./buildings/blackmarket.js";
import { loadMine } from "./buildings/mine.js";
const popup = document.getElementById("building-popup");
const title = document.getElementById("popup-title");
const tooltip = document.getElementById("map-tooltip");
const tooltipCache = {};
const buildingModules = {
11: loadCharacterHouse, // Tabs ausblenden, eigenes UI
12: loadBlackmarket, // Tabs ausblenden, eigenes UI
10: loadMine, // Tabs bleiben sichtbar, nur Aktionen-Tab befüllen
};
// Gebäude die ihre eigenen Tabs behalten sollen
const keepTabsVisible = new Set([10]);
/* ================================
Tabs zurücksetzen
================================ */
function resetTabs() {
document
.querySelectorAll(".tab")
.forEach((t) => t.classList.remove("active"));
document
.querySelectorAll(".tab-content")
.forEach((c) => c.classList.remove("active"));
const firstTab = document.querySelector(".tab");
const firstContent = document.querySelector(".tab-content");
if (firstTab) firstTab.classList.add("active");
if (firstContent) firstContent.classList.add("active");
}
/* ================================
Gebäude Popup öffnen
================================ */
document.querySelectorAll(".building").forEach((building) => {
building.addEventListener("click", async (e) => {
e.preventDefault();
try {
const url = building.getAttribute("href");
title.innerText = "Lädt...";
popup.style.left = "50%";
popup.style.top = "50%";
popup.classList.add("active");
resetTabs();
const res = await fetch("/api" + url);
if (!res.ok) throw new Error("API Fehler");
const data = await res.json();
title.innerText = data.name;
const infoTab = document.getElementById("tab-info");
const tabs = document.querySelector(".popup-tabs");
// Standard: Info anzeigen
infoTab.innerHTML = `
<div class="popup-info-title">${data.name}</div>
<div class="popup-stat-row"><span class="popup-stat-key">Level</span><span class="popup-stat-val">${data.level}</span></div>
<div class="popup-stat-row"><span class="popup-stat-key">Punkte</span><span class="popup-stat-val">${data.points} / ${data.nextLevelPoints}</span></div>
<p class="popup-desc" style="color:#cccccc !important;font-size:13px;line-height:1.8;">${data.description}</p>
<div class="popup-xp-wrap">
<div class="popup-xp-label">Fortschritt zum nächsten Level</div>
<div class="popup-xp-track">
<div class="popup-xp-fill" style="width:${Math.min((data.points / data.nextLevelPoints) * 100, 100)}%">
<div class="popup-xp-shimmer"></div>
</div>
</div>
</div>
<div class="popup-divider">✦ · ✦ · ✦</div>
`;
// Standard Tabs anzeigen
tabs.style.display = "flex";
// Prüfen ob Gebäude eigenes UI hat
const buildingType = Number(data.type);
if (buildingModules[buildingType]) {
if (keepTabsVisible.has(buildingType)) {
// Tabs sichtbar lassen (z.B. Mine) — Info-Tab bleibt aktiv
tabs.style.display = "flex";
} else {
// Tabs ausblenden, eigenes Voll-UI (Wohnhaus, Schwarzmarkt)
tabs.style.display = "none";
infoTab.innerHTML = `<div class="building-ui"></div>`;
}
buildingModules[buildingType](buildingType);
}
document.getElementById("tab-upgrade").innerHTML = `
<div class="popup-info-title">Upgrade</div>
<div class="popup-stat-row"><span class="popup-stat-key">Kosten</span><span class="popup-stat-val">${data.upgradeCost}</span></div>
<button class="popup-upgrade-btn">⚒ UPGRADE STARTEN ⚒</button>
`;
} catch (error) {
console.error("Gebäude konnte nicht geladen werden:", error);
}
});
});
/* ================================
Tabs wechseln
================================ */
document.querySelectorAll(".tab").forEach((tab) => {
tab.addEventListener("click", () => {
document
.querySelectorAll(".tab")
.forEach((t) => t.classList.remove("active"));
tab.classList.add("active");
document
.querySelectorAll(".tab-content")
.forEach((c) => c.classList.remove("active"));
document.getElementById("tab-" + tab.dataset.tab).classList.add("active");
});
});
/* ================================
Popup schließen
================================ */
document.querySelector(".popup-close").onclick = () => {
popup.classList.remove("active");
};
/* ================================
Tooltip
================================ */
document.querySelectorAll(".building").forEach((building) => {
building.addEventListener("mouseenter", async (e) => {
try {
const id = building.dataset.id;
if (!tooltipCache[id]) {
const res = await fetch("/api/building/" + id);
if (!res.ok) throw new Error("API Fehler");
tooltipCache[id] = await res.json();
}
const data = tooltipCache[id];
tooltip.innerHTML = `
<strong>${data.name}</strong><br>
Level ${data.level}<br>
Punkte ${data.points}/${data.nextLevelPoints}<br>
<hr>
Upgrade Kosten:<br>
${data.upgradeCost}
`;
tooltip.style.display = "block";
} catch (err) {
console.error("Tooltip Fehler:", err);
}
});
building.addEventListener("mousemove", (e) => {
// Tooltip erst rendern lassen damit offsetWidth korrekt ist
const tw = tooltip.offsetWidth;
const th = tooltip.offsetHeight;
let x = e.clientX + 15;
let y = e.clientY + 15;
// Rechter Rand Tooltip links vom Cursor anzeigen
if (x + tw > window.innerWidth - 10) x = e.clientX - tw - 10;
// Unterer Rand Tooltip über dem Cursor anzeigen
if (y + th > window.innerHeight - 10) y = e.clientY - th - 10;
tooltip.style.left = x + "px";
tooltip.style.top = y + "px";
});
building.addEventListener("mouseleave", () => {
tooltip.style.display = "none";
});
});