async function loadDomains(){ const domains = await api(API + "/domains") const subs = await api(API + "/subdomains") const table = document.getElementById("domains") table.innerHTML = "" for(const d of domains){ const tr = document.createElement("tr") const sublist = subs .filter(s => s.domain_id === d.id) .map(s => `
↳ ${s.subdomain}.${s.domain_name} ...
`) .join(""); tr.innerHTML = ` ${d.domain_name} ${sublist} ${d.provider || ""} ${d.ip_address || ""} ${d.resource_name || ""} ... ${d.yearly_cost || ""} `; table.appendChild(tr) const resources = window.resources || [] subs.forEach(s => { const server = resources.find(r => Array.isArray(r.ips) && r.ips.some(ip => ip.ip === s.ip_address) ) if(server){ const el = document.getElementById("subserver-"+s.id) if(el){ el.innerText = " → " + server.name } } }) subs .filter(s => s.domain_id === d.id) .forEach(async s => { const full = s.subdomain + "." + s.domain_name try{ const dns = await api(API + "/dns/" + full) let status="❌" if(dns.ips && dns.ips.includes(s.ip_address)){ status="✅" + dns.ips.join(", ") }else if(dns.ips.length){ status="⚠" + dns.ips.join(", ") } document.getElementById("subdns-"+s.id).innerHTML=status }catch(e){ document.getElementById("subdns-"+s.id).innerHTML="❌" } }) try{ const dnsRes = await fetch(API + "/dns/" + d.domain_name) const result = await dnsRes.json() let status = "❌" if(result.ips && result.ips.length){ const ipList = result.ips.join("
") if(d.ip_address && result.ips.includes(d.ip_address)){ status = "✅ " + ipList }else{ status = "⚠ " + ipList } } document.getElementById("dns-"+d.id).innerHTML = status }catch(e){ document.getElementById("dns-"+d.id).innerHTML = "❌" } } } async function deleteDomain(id){ if(!confirm("Domain löschen?")) return; await api(API + "/domains/" + id, { method: "DELETE" }); loadDomains(); } async function saveDomain(){ const id=document.getElementById("domain_id").value let cost=document.getElementById("domain_cost").value if(cost){ cost=cost.replace(",",".") } const data={ domain_name:domain_name.value, provider:domain_provider.value, ip_address:domain_ip.value, yearly_cost:cost || null, notes:domain_notes.value } if(id){ await api(API+"/domains/"+id,{ method:"PUT", headers:{'Content-Type':'application/json'}, body:JSON.stringify(data) }) }else{ await api(API+"/domains",{ method:"POST", headers:{'Content-Type':'application/json'}, body:JSON.stringify(data) }) } closeDomainModal() loadDomains() loadMapping() loadCosts() } async function loadMapping(){ const data = await api(API + "/domainmap"); const table = document.getElementById("mapping"); table.innerHTML = ""; data.forEach(m => { const tr = document.createElement("tr"); tr.innerHTML = ` ${m.domain_name} ${m.ip_address} ${m.server_name || ""} `; table.appendChild(tr); }); }