🔍 ESC
↑ ↑ ↓ ↓ ← → ← → B A
AETHERION CHEAT CODE ACTIVATED
click anywhere to close
Press ⌘K or Ctrl+K to open command palette
ΔΙΑΘΕΣΙΜΟΣ
↑
💬
A
Aetherion Assistant
Online
Γεια! 👋 Είμαι ο AI assistant της Aetherion Projects. Μπορώ να απαντήσω για υπηρεσίες, τιμές, timelines και projects. Τι θέλεις να μάθεις;
Domains › —

Νέο DNS Record

Ανανέωση Domain

—
—
Ανανέωση 1 χρόνο€0.00
ΦΠΑ 24%€0.00
Σύνολο€0.00

Διαγραφή Record;

Το record θα διαγραφεί αμέσως.

'; if(ch) ch.textContent=ed.value.length+' chars'; } window.pgUpdate=upd; window.pgReset=function(){ed.value=DEF;upd();}; window.pgSnippet=function(k){ed.value=SN[k]||DEF;upd();}; ed.addEventListener('keydown',function(e){ if((e.ctrlKey||e.metaKey)&&e.key==='Enter'){e.preventDefault();upd();} if(e.key==='Tab'){e.preventDefault();var s=ed.selectionStart;ed.value=ed.value.slice(0,s)+' '+ed.value.slice(ed.selectionEnd);ed.selectionStart=ed.selectionEnd=s+2;} }); ed.value=DEF; upd(); })(); /* ══ SERVER LOGS ════════════════════════════════════════════════════ */ (function(){ var out=document.getElementById('log-output'); if(!out) return; var C={'GET':'#4ade80','POST':'#818cf8','PUT':'#fbbf24','DELETE':'#f87171','200':'#4ade80','201':'#34d399','204':'#60a5fa','[WS]':'#c084fc','[DB]':'#60a5fa','[CRON]':'#fb923c'}; var R=[ ['GET','/api/v2/devices','200','18ms'],['POST','/api/v2/location','201','12ms'], ['GET','/api/v2/fleet','200','24ms'],['GET','/api/v2/alerts','200','8ms'], ['POST','/api/v2/auth/token','200','31ms'],['PUT','/api/v2/devices/3421','200','14ms'], ['[WS]','device:3421 connected','',''],['[WS]','device:1189 location update','',''], ['[DB]','SELECT devices WHERE active=true','','4ms'],['[CRON]','heartbeat 2.147 devices','',''], ['GET','/api/v2/map/tiles','200','6ms'],['DELETE','/api/v2/sessions/old','204','9ms'], ['POST','/api/v2/webhooks','200','22ms'],['[WS]','fleet:DE-Munich 14 vehicles','',''], ]; function addLog(){ var e=R[Math.floor(Math.random()*R.length)]; var t=new Date().toLocaleTimeString('en',{hour12:false}); var d=document.createElement('div'); d.style='border-bottom:1px solid rgba(255,255,255,.03);padding:.1rem 0;display:flex;gap:.6rem;overflow:hidden'; d.innerHTML=''+t+'' +''+e[0]+'' +''+e[1]+'' +(e[2]?''+e[2]+'':'') +(e[3]?''+e[3]+'':''); out.appendChild(d); if(out.children.length>40) out.removeChild(out.firstChild); out.scrollTop=out.scrollHeight; } setTimeout(function(){for(var i=0;i<5;i++)addLog();setInterval(addLog,1000+Math.random()*600);},800); function jitter(){ var api=20+Math.floor(Math.random()*20),db=8+Math.floor(Math.random()*12); var dev=2140+Math.floor(Math.random()*20),ws=840+Math.floor(Math.random()*20); function s(id,v){var e=document.getElementById(id);if(e)e.textContent=v;} function w(id,pct){var e=document.getElementById(id);if(e)e.style.width=pct+'%';} s('pm-api',api+'ms');s('pm-db',db+'ms'); s('pm-dev',dev.toLocaleString('el-GR'));s('pm-ws',ws); w('pm-api-bar',Math.max(40,100-api*2));w('pm-db-bar',Math.max(60,100-db*3)); w('pm-dev-bar',dev/3000*100);w('pm-ws-bar',ws/2000*100); } setInterval(jitter,2000);setTimeout(jitter,1500); })(); /* ══ CUSTOM CURSOR ═══════════════════════════════════════════════════ */ (function(){ var dot = document.getElementById('cursor-dot'); var ring = document.getElementById('cursor-ring'); if(!dot||!ring||window.matchMedia('(hover:none)').matches) return; var dx=0,dy=0,rx=0,ry=0; window.addEventListener('mousemove',function(e){ dx=e.clientX; dy=e.clientY; dot.style.transform='translate(calc('+dx+'px - 50%), calc('+dy+'px - 50%))'; },{passive:true}); // ring removed // expand effects removed })(); /* ══ SOCIAL PROOF TOASTS (disabled) ════════════════════════════════ */ /* DISABLED (function(){ var container = document.getElementById('toast-container'); if(!container) return; var visitors = [ {name:'Μ. Παπαδόπουλος', city:'Αθήνα 🇬🇷', action:'είδε το Portfolio', color:'#818cf8'}, {name:'Klaus M.', city:'München 🇩🇪', action:'ζήτησε προσφορά', color:'#fbbf24'}, {name:'Γ. Κωνσταντίνου', city:'Θεσσαλονίκη 🇬🇷', action:'διάβασε για FahrTrack', color:'#E03030'}, {name:'Nikos A.', city:'Λευκωσία 🇨🇾', action:'άνοιξε το Contact', color:'#4ade80'}, {name:'Thomas B.', city:'Wien 🇦🇹', action:'χρησιμοποίησε το Terminal', color:'#c084fc'}, {name:'Σ. Αλεξάνδρου', city:'Πάτρα 🇬🇷', action:'είδε τις τιμές', color:'#fb923c'}, ]; var i=0; function showToast(){ var v=visitors[i%visitors.length]; i++; var t=document.createElement('div'); t.className='toast'; t.innerHTML= '
👤
'+ '
'+ '
'+v.name+'
'+ '
'+v.city+' · '+v.action+'
'+ '
'; container.appendChild(t); requestAnimationFrame(function(){ requestAnimationFrame(function(){ t.classList.add('show'); }); }); setTimeout(function(){ t.classList.remove('show'); setTimeout(function(){ if(t.parentNode) t.parentNode.removeChild(t); },400); }, 4500); } // Start after 3s, then every 8s setTimeout(showToast, 3000); setInterval(showToast, 8000); })(); /* ══ LIVE TYPING DEMO (simplified) ══════════════════════════════ */ (function(){ var code = document.getElementById('live-demo-code'); if(!code) return; var lines = [ 'const site = await buildSite({', ' stack: ["React", "Node", "Stripe"],', ' lighthouse: 98,', ' deploy: "netlify"', '});', 'await site.deploy(); // ✓ live!', ]; var li=0; var obs=new IntersectionObserver(function(entries){ if(!entries[0].isIntersecting) return; obs.disconnect(); (function next(){ if(li>=lines.length) return; var d=document.createElement('div'); d.innerHTML=lines[li++]; code.appendChild(d); if(li'+cmd.icon+''+ ''+cmd.label+''+ ''+cmd.sub+''; div.addEventListener('click', function(){ execute(cmd); }); div.addEventListener('mouseenter', function(){ selected=idx; updateSelected(); }); return div; } function updateSelected(){ results.querySelectorAll('.cmd-item').forEach(function(el,i){ el.classList.toggle('selected', i===selected); }); } function execute(cmd){ close(); setTimeout(function(){ if(cmd.r){ if(window.showPage) window.showPage(cmd.r); window.scrollTo(0,0); } else if(cmd.action==='whatsapp'){ window.open('https://wa.me/30398371244','_blank'); } else if(cmd.action==='email'){ window.location.href='mailto:info@aetherionprojects.cloud'; } else if(cmd.action==='dark'){ if(window.toggleDark) window.toggleDark(); } else if(cmd.action==='terminal'){ if(window.showPage) window.showPage('home'); setTimeout(function(){ var t=document.getElementById('term-input'); if(t){ t.scrollIntoView({behavior:'smooth',block:'center'}); t.focus(); } },500); } }, 100); } // Keyboard shortcuts document.addEventListener('keydown', function(e){ if((e.metaKey||e.ctrlKey) && e.key==='k'){ e.preventDefault(); open(); return; } if(!backdrop.classList.contains('open')) return; if(e.key==='Escape'){ close(); return; } if(e.key==='ArrowDown'){ e.preventDefault(); selected=Math.min(selected+1,filtered.length-1); updateSelected(); } if(e.key==='ArrowUp'){ e.preventDefault(); selected=Math.max(selected-1,0); updateSelected(); } if(e.key==='Enter'){ if(filtered[selected]) execute(filtered[selected]); } }); input.addEventListener('input', function(){ var q=input.value.toLowerCase(); if(!q){ render(commands); return; } render(commands.filter(function(c){ return c.label.toLowerCase().includes(q) || c.sub.toLowerCase().includes(q); })); }); backdrop.addEventListener('click', function(e){ if(e.target===backdrop) close(); }); })(); /* ══ CONFETTI 🎉 ═════════════════════════════════════════════════════ */ window.launchConfetti = function(x, y){ var colors=['#818cf8','#c084fc','#4ade80','#fb923c','#f472b6','#fbbf24','#60a5fa']; for(var i=0;i<60;i++){ (function(i){ var el=document.createElement('div'); el.className='confetti-piece'; var color=colors[Math.floor(Math.random()*colors.length)]; el.style.cssText='left:'+(x||50)+'%;top:'+(y||0)+'px;background:'+color+ ';border-radius:'+(Math.random()>.5?'50%':'2px')+ ';animation-duration:'+(Math.random()*1.5+1)+'s'+ ';animation-delay:'+(Math.random()*.5)+'s'; document.body.appendChild(el); setTimeout(function(){ el.remove(); }, 2500); })(i); } }; /* ══ MOUSE TRAIL 🌟 ══════════════════════════════════════════════════ */ (function(){ var colors=['#6366f1','#818cf8','#c084fc','#4ade80','#f472b6']; var ci=0; var lastX=0,lastY=0; window.addEventListener('mousemove',function(e){ if(Math.abs(e.clientX-lastX)<25 && Math.abs(e.clientY-lastY)<25) return; lastX=e.clientX; lastY=e.clientY; // Only on dark sections var el=document.elementFromPoint(e.clientX,e.clientY); var dark=false; for(var k=el,d=0;k&&d<5;k=k.parentElement,d++){ var bg=window.getComputedStyle(k).backgroundColor; if(bg&&(bg.includes('17, 17')||bg.includes('10, 10')||bg.includes('12, 12')||bg.includes('13, 13'))){ dark=true;break; } } if(!dark) return; var dot=document.createElement('div'); dot.className='trail-dot'; dot.style.cssText='left:'+e.clientX+'px;top:'+e.clientY+'px;background:'+colors[ci%colors.length]+';opacity:.7;animation-duration:'+(Math.random()*.3+.4)+'s'; ci++; document.body.appendChild(dot); setTimeout(function(){dot.remove();},700); },{passive:true}); })(); /* ══ KONAMI CODE ↑↑↓↓←→←→BA ══════════════════════════════════════ */ (function(){ var seq=[38,38,40,40,37,39,37,39,66,65]; var pos=0; document.addEventListener('keydown',function(e){ if(e.keyCode===seq[pos]){ pos++; if(pos===seq.length){ pos=0; var ov=document.getElementById('konami-overlay'); if(!ov) return; ov.classList.add('show'); window.launchConfetti && window.launchConfetti(50,0); // Matrix rain on the konami canvas var wrap=document.getElementById('konami-canvas-wrap'); if(wrap){ var c=document.createElement('canvas'); c.width=300;c.height=120; c.style.cssText='display:block;margin:0 auto;opacity:.6'; wrap.innerHTML=''; wrap.appendChild(c); var ctx=c.getContext('2d'); var chars='アイウエオΑΒΓΔ0101'; var cols=Math.floor(c.width/14); var drops=Array(cols).fill(1); var iv=setInterval(function(){ ctx.fillStyle='rgba(10,0,20,.15)'; ctx.fillRect(0,0,c.width,c.height); ctx.fillStyle='#c084fc'; ctx.font='13px monospace'; drops.forEach(function(y,i){ ctx.fillText(chars[Math.floor(Math.random()*chars.length)],i*14,y*14); if(y*14>c.height && Math.random()>.95) drops[i]=0; drops[i]++; }); },60); setTimeout(function(){ clearInterval(iv); },6000); } } } else { pos=0; } }); })(); /* ══ CONTACT FORM CONFETTI ═══════════════════════════════════════════ */ (function(){ var form=document.getElementById('contact-form'); if(!form) return; form.addEventListener('submit',function(e){ setTimeout(function(){ window.launchConfetti && window.launchConfetti(50,0); },400); }); // Also on chat send var chatSend=document.getElementById('chat-send'); if(chatSend){ chatSend.addEventListener('click',function(){ window.launchConfetti && window.launchConfetti(Math.random()*80+10,200); }); } })(); /* ══ TIME-BASED GREETING IN HERO ════════════════════════════════════ */ (function(){ var el=document.getElementById('hero-greeting'); if(!el) return; var h=new Date(new Date().toLocaleString('en',{timeZone:'Europe/Athens'})).getHours(); var greet= h<5?'🌙 Καλά ξημερώματα' : h<12?'☀️ Καλημέρα' : h<17?'🌤 Καλό απόγευμα' : h<21?'🌆 Καλό βράδυ' : '🌙 Καλό βράδυ'; el.textContent=greet; })(); var API_BASE = (function(){ var h = window.location.hostname; return (h==='localhost'||h==='127.0.0.1') ? 'http://localhost:3001/api/v1' : 'https://api.aetherionprojects.cloud/api/v1'; })(); async function apiFetch(method, path, body){ var res = await fetch(API_BASE+path,{ method: method, credentials: 'include', headers: {'Content-Type':'application/json'}, body: body ? JSON.stringify(body) : undefined }); var json = await res.json(); if(!json.success) throw new Error(json.error?.message||'Σφάλμα'); return json.data; } function showErr(id, msg){ var el=document.getElementById(id); el.textContent=msg; el.style.display='block'; } function hideErr(id){ document.getElementById(id).style.display='none'; } function showOk(id, msg){ var el=document.getElementById(id); el.textContent=msg; el.style.display='block'; } function pwStrength(pw){ var score = 0; if(pw.length>=8) score++; if(pw.length>=12) score++; if(/[A-Z]/.test(pw)) score++; if(/[0-9]/.test(pw)) score++; if(/[^a-zA-Z0-9]/.test(pw)) score++; var bar = document.getElementById('pw-bar'); if(!bar)return; var cols=['#ef4444','#f97316','#eab308','#22c55e','#16a34a']; var widths=['20%','40%','60%','80%','100%']; bar.style.background = cols[Math.min(score,4)]; bar.style.width = widths[Math.min(score,4)]; } var _user=JSON.parse(localStorage.getItem('ae_user')||'null'); if(!_user){location.href='/login.html';} function doLogout(){localStorage.removeItem('ae_user');localStorage.removeItem('ae_access');localStorage.removeItem('ae_domain_cart');location.href='/login.html';} (function(){if(!_user)return;var av=document.getElementById('sb-av'),nm=document.getElementById('sb-name'),em=document.getElementById('sb-email');if(av)av.textContent=(_user.name||_user.firstName||_user.email).charAt(0).toUpperCase();if(nm)nm.textContent=_user.name||(_user.firstName?_user.firstName+' '+(_user.lastName||''):_user.email)||'—';if(em)em.textContent=_user.email||'—';})(); async function apiFetch(m,p,b){var h={'Content-Type':'application/json'};var tok=localStorage.getItem('ae_access');if(tok)h['Authorization']='Bearer '+tok;var res=await fetch((window.location.hostname==='localhost'?'http://localhost:3001':'https://api.aetherionprojects.cloud')+'/api/v1'+p,{method:m,credentials:'include',headers:h,body:b?JSON.stringify(b):undefined});var j=await res.json();if(!j.success)throw new Error(j.error?.message||'Σφάλμα');return j.data;} /* ─── State ──────────────────────────────────────────────── */ var _fqdn = '', _domain = null, _editId = null, _delId = null; var _renewPrice = 12.99, _renewYrs = 1; /* Mock domain */ var MOCK = { fqdn:'aetherionprojects.cloud', tld:'.cloud', status:'ACTIVE', locked:true, autoRenew:true, registeredAt:'2024-09-15', expiresAt:'2027-09-15', providerRef:'OP-CLD-001', renewCost:18.99, nameservers:['dns1.p01.nsone.net','dns2.p01.nsone.net','dns3.p01.nsone.net'], dnsRecords:[ {id:'r1',type:'A', name:'@', value:'75.2.60.5', ttl:1800}, {id:'r2',type:'A', name:'www', value:'75.2.60.5', ttl:1800}, {id:'r3',type:'CNAME',name:'mail', value:'mail.google.com.',ttl:3600}, {id:'r4',type:'MX', name:'@', value:'aspmx.l.google.com.',ttl:3600,priority:1}, {id:'r5',type:'MX', name:'@', value:'alt1.aspmx.l.google.com.',ttl:3600,priority:5}, {id:'r6',type:'TXT', name:'@', value:'"v=spf1 include:_spf.google.com ~all"',ttl:3600}, {id:'r7',type:'TXT', name:'_dmarc', value:'"v=DMARC1; p=quarantine; rua=mailto:dmarc@aetherionprojects.cloud"',ttl:3600}, {id:'r8',type:'TXT', name:'@', value:'"google-site-verification=abc123def456"',ttl:3600}, ] }; /* ─── Init ───────────────────────────────────────────────── */ document.addEventListener('DOMContentLoaded', function() { var p = new URLSearchParams(window.location.search); _fqdn = p.get('d') || MOCK.fqdn; loadDomain(); }); async function loadDomain() { try { _domain = await apiFetch('GET', '/account/domains/' + encodeURIComponent(_fqdn)); } catch(e) { _domain = Object.assign({}, MOCK, {fqdn: _fqdn}); } renderHeader(); renderDNS(_domain.dnsRecords || []); renderNS(_domain.nameservers || []); renderInfo(); } /* ─── Header ─────────────────────────────────────────────── */ function renderHeader() { var d = _domain; document.getElementById('bc-domain').textContent = d.fqdn; document.getElementById('hd-fqdn').textContent = d.fqdn; document.getElementById('hd-ref').textContent = d.providerRef || '—'; var days = Math.ceil((new Date(d.expiresAt) - new Date()) / 86400000); var expCol = days < 0 ? '#dc2626' : days <= 30 ? '#d97706' : '#111'; document.getElementById('hd-exp').textContent = fmtDate(d.expiresAt) + ' (' + days + 'd)'; document.getElementById('hd-exp').style.color = expCol; document.getElementById('hd-reg').textContent = fmtDate(d.registeredAt); var st = document.getElementById('hd-status'); if (d.status === 'ACTIVE') st.innerHTML = 'Ενεργό'; else st.innerHTML = '⏳ ' + d.status + ''; document.getElementById('hd-lock').style.opacity = d.locked ? '1' : '.25'; var ar = document.getElementById('tog-ar'); ar.classList.toggle('on', !!d.autoRenew); document.getElementById('tog-ar-lbl').textContent = d.autoRenew ? 'Ενεργό — ανανεώνεται αυτόματα' : 'Ανενεργό — θυμήσου να ανανεώσεις'; document.getElementById('tog-lock').classList.toggle('on', !!d.locked); _renewPrice = d.renewCost || 12.99; if (days >= 0 && days <= 60) document.getElementById('renew-btn').style.display = 'flex'; document.getElementById('ren-fqdn').textContent = d.fqdn; document.getElementById('ren-exp').textContent = 'Λήγει: ' + fmtDate(d.expiresAt); calcRenew(); } /* ─── DNS Records ────────────────────────────────────────── */ var _allRecords = []; function renderDNS(records) { _allRecords = records; filterDNS(); } function filterDNS() { var q = (document.getElementById('dns-q')?.value || '').toLowerCase(); var type = document.getElementById('dns-type-filter')?.value || ''; var list = _allRecords.filter(function(r) { if (type && r.type !== type) return false; if (q && !(r.name.toLowerCase().includes(q) || r.value.toLowerCase().includes(q))) return false; return true; }); var el = document.getElementById('dns-list'); var empty = document.getElementById('dns-empty'); if (!list.length) { el.innerHTML = ''; empty.style.display = 'block'; return; } empty.style.display = 'none'; // Sort: A → AAAA → CNAME → MX → TXT → NS var order = {A:0,AAAA:1,CNAME:2,MX:3,TXT:4,NS:5,SRV:6}; list.sort(function(a,b){ return (order[a.type]||9)-(order[b.type]||9); }); el.innerHTML = list.map(function(r) { var prio = r.priority != null ? ' prio:'+r.priority+'' : ''; var val = r.value.length > 42 ? r.value.slice(0,42) + '…' : r.value; return '
' +'
'+r.type+'
' +'
'+r.name+'
' +'
'+val+prio+'
' +'
'+r.ttl+'s
' +'
' +'' +'' +'
'; }).join(''); } /* ─── Record modal ───────────────────────────────────────── */ var REC_HELP = { A: 'Παράδειγμα: 75.2.60.5 — Δείχνει το domain σε IPv4 διεύθυνση.', AAAA: 'Παράδειγμα: 2001:db8::1 — Δείχνει το domain σε IPv6 διεύθυνση.', CNAME:'Παράδειγμα: target.example.com. — Alias για άλλο hostname. Όχι για @ root.', MX: 'Παράδειγμα: aspmx.l.google.com. — Mail server. Χαμηλότερο priority = υψηλότερη προτεραιότητα.', TXT: 'Παράδειγμα: "v=spf1 include:_spf.google.com ~all" — SPF, DKIM, DMARC, site verification.', NS: 'Παράδειγμα: ns1.example.com. — Nameserver για subdomain delegation.', SRV: 'Μορφή: priority weight port target — Π.χ. 10 10 5060 sip.example.com.', }; function openAddRecord() { _editId = null; document.getElementById('mo-rec-t').textContent = 'Νέο DNS Record'; document.getElementById('rec-save-btn').textContent = 'Προσθήκη'; document.getElementById('rec-type').value = 'A'; document.getElementById('rec-name').value = ''; document.getElementById('rec-val').value = ''; document.getElementById('rec-prio').value = '10'; document.getElementById('rec-ttl').value = '1800'; document.getElementById('rec-err').style.display = 'none'; onTypeChange(); document.getElementById('mo-rec').classList.add('open'); setTimeout(function(){ document.getElementById('rec-name').focus(); }, 80); } function editRecord(id) { var r = _allRecords.find(function(x){ return x.id === id; }); if (!r) return; _editId = id; document.getElementById('mo-rec-t').textContent = 'Επεξεργασία Record'; document.getElementById('rec-save-btn').textContent = 'Αποθήκευση'; document.getElementById('rec-type').value = r.type; document.getElementById('rec-name').value = r.name; document.getElementById('rec-val').value = r.value; document.getElementById('rec-prio').value = r.priority || '10'; document.getElementById('rec-ttl').value = r.ttl || '1800'; document.getElementById('rec-err').style.display = 'none'; onTypeChange(); document.getElementById('mo-rec').classList.add('open'); } function onTypeChange() { var t = document.getElementById('rec-type').value; document.getElementById('rec-prio-wrap').style.display = t === 'MX' ? 'block' : 'none'; document.getElementById('rec-help').textContent = REC_HELP[t] || ''; var lbl = document.getElementById('rec-val-lbl'); lbl.textContent = {A:'IPv4 Address',AAAA:'IPv6 Address',CNAME:'Target hostname',MX:'Mail server hostname',TXT:'Text content',NS:'Nameserver hostname',SRV:'Priority weight port target'}[t] || 'Τιμή'; var pl = {A:'75.2.60.5',AAAA:'2001:db8::1',CNAME:'target.example.com.',MX:'aspmx.l.google.com.',TXT:'"v=spf1 include:_spf.google.com ~all"',NS:'ns1.example.com.',SRV:'10 10 443 target.example.com.'}[t]||''; document.getElementById('rec-val').placeholder = pl; } function closeMoRec() { document.getElementById('mo-rec').classList.remove('open'); } async function saveRecord() { var type = document.getElementById('rec-type').value; var name = document.getElementById('rec-name').value.trim() || '@'; var value = document.getElementById('rec-val').value.trim(); var prio = parseInt(document.getElementById('rec-prio').value) || 10; var ttl = parseInt(document.getElementById('rec-ttl').value) || 1800; var err = document.getElementById('rec-err'); err.style.display = 'none'; if (!value) { err.textContent = 'Συμπλήρωσε την τιμή του record.'; err.style.display = 'block'; return; } if (type === 'A' && !/^\d{1,3}(\.\d{1,3}){3}$/.test(value)) { err.textContent = 'Μη έγκυρη IPv4 διεύθυνση.'; err.style.display = 'block'; return; } var btn = document.getElementById('rec-save-btn'); btn.textContent = 'Αποθήκευση...'; btn.disabled = true; var rec = {type, name, value, ttl, ...(type==='MX'?{priority:prio}:{})}; try { if (_editId) { await apiFetch('PUT', '/account/domains/' + encodeURIComponent(_fqdn) + '/dns/' + _editId, rec); var idx = _allRecords.findIndex(function(r){ return r.id===_editId; }); if(idx>=0) _allRecords[idx] = Object.assign({id:_editId},rec); } else { var newRec = await apiFetch('POST', '/account/domains/' + encodeURIComponent(_fqdn) + '/dns', rec); _allRecords.push(Object.assign({id:'r'+Date.now()},rec,newRec||{})); } } catch(e) { // Demo: apply locally if (_editId) { var idx2 = _allRecords.findIndex(function(r){ return r.id===_editId; }); if(idx2>=0) _allRecords[idx2] = Object.assign({id:_editId},rec); } else { _allRecords.push(Object.assign({id:'r'+Date.now()},rec)); } } filterDNS(); closeMoRec(); showToast((_editId?'Record ενημερώθηκε':'Record προστέθηκε')+' ✓', 'ok'); btn.textContent = _editId ? 'Αποθήκευση' : 'Προσθήκη'; btn.disabled = false; } /* ─── Delete ─────────────────────────────────────────────── */ function askDelete(id, desc) { _delId = id; document.getElementById('del-desc').textContent = desc; document.getElementById('mo-del').classList.add('open'); } async function confirmDelete() { try { await apiFetch('DELETE', '/account/domains/' + encodeURIComponent(_fqdn) + '/dns/' + _delId); } catch(e) {} _allRecords = _allRecords.filter(function(r){ return r.id !== _delId; }); filterDNS(); document.getElementById('mo-del').classList.remove('open'); showToast('Record διαγράφηκε', 'ok'); } /* ─── Presets ────────────────────────────────────────────── */ var PRESETS = { 'netlify': [{type:'A',name:'@',value:'75.2.60.5',ttl:1800},{type:'CNAME',name:'www',value:'apex-loadbalancer.netlify.com.',ttl:3600}], 'cloudflare': [{type:'A',name:'@',value:'104.21.0.1',ttl:1800},{type:'A',name:'www',value:'104.21.0.1',ttl:1800}], 'google-workspace': [{type:'MX',name:'@',value:'aspmx.l.google.com.',ttl:3600,priority:1},{type:'MX',name:'@',value:'alt1.aspmx.l.google.com.',ttl:3600,priority:5},{type:'MX',name:'@',value:'alt2.aspmx.l.google.com.',ttl:3600,priority:5},{type:'TXT',name:'@',value:'"v=spf1 include:_spf.google.com ~all"',ttl:3600}], 'microsoft365': [{type:'MX',name:'@',value:'company-com.mail.protection.outlook.com.',ttl:3600,priority:0},{type:'TXT',name:'@',value:'"v=spf1 include:spf.protection.outlook.com -all"',ttl:3600},{type:'CNAME',name:'autodiscover',value:'autodiscover.outlook.com.',ttl:3600}], 'github-pages': [{type:'A',name:'@',value:'185.199.108.153',ttl:1800},{type:'A',name:'@',value:'185.199.109.153',ttl:1800},{type:'CNAME',name:'www',value:'yourusername.github.io.',ttl:3600}], }; function applyPreset(name) { if (!confirm('Προσθήκη preset "'+name+'"; Τα υπάρχοντα records δεν θα διαγραφούν.')) return; var recs = PRESETS[name] || []; recs.forEach(function(r){ _allRecords.push(Object.assign({id:'r'+Date.now()+Math.random()},r)); }); filterDNS(); showToast('Preset "'+name+'" εφαρμόστηκε ✓','ok'); } /* ─── Nameservers ────────────────────────────────────────── */ function renderNS(ns) { document.getElementById('ns-current').innerHTML = (ns.length?ns:[]).map(function(n){ return '
'+n+'✓ Active
'; }).join('') || '
—
'; if (ns[0]) document.getElementById('ns1').value = ns[0]||''; if (ns[1]) document.getElementById('ns2').value = ns[1]||''; if (ns[2]) document.getElementById('ns3').value = ns[2]||''; if (ns[3]) document.getElementById('ns4').value = ns[3]||''; } var NS_PRESETS = { cloudflare: ['evelyn.ns.cloudflare.com','ivan.ns.cloudflare.com'], netlify: ['dns1.p01.nsone.net','dns2.p01.nsone.net','dns3.p01.nsone.net','dns4.p01.nsone.net'], aetherion: ['ns1.aetherionprojects.cloud','ns2.aetherionprojects.cloud'], }; function nsPreset(name) { var ns = NS_PRESETS[name] || []; ['ns1','ns2','ns3','ns4'].forEach(function(id,i){ document.getElementById(id).value = ns[i]||''; }); } async function saveNS() { var ns = ['ns1','ns2','ns3','ns4'].map(function(id){ return document.getElementById(id).value.trim(); }).filter(Boolean); if (ns.length < 2) { showToast('Χρειάζεσαι τουλάχιστον 2 nameservers','err'); return; } try { await apiFetch('PUT', '/account/domains/'+encodeURIComponent(_fqdn)+'/nameservers', {nameservers:ns}); } catch(e) {} _domain.nameservers = ns; renderNS(ns); showToast('Nameservers ενημερώθηκαν ✓ (48ω διάδοση)','ok'); } /* ─── Info tab ───────────────────────────────────────────── */ function renderInfo() { var d = _domain; var days = Math.ceil((new Date(d.expiresAt)-new Date())/86400000); document.getElementById('info-grid').innerHTML = [ ['FQDN', d.fqdn], ['TLD', d.tld||d.fqdn.slice(d.fqdn.indexOf('.'))], ['Status', d.status], ['Registered', fmtDate(d.registeredAt)], ['Expires', fmtDate(d.expiresAt)+' ('+days+'d)'], ['Auto-Renew', d.autoRenew?'✓ Ενεργό':'✗ Ανενεργό'], ['Domain Lock', d.locked?'🔒 Κλειδωμένο':'🔓 Ξεκλείδωτο'], ['DNS Records', (_domain.dnsRecords||[]).length+' records'], ].map(function(x){ return '
'+x[0]+'
'+x[1]+'
'; }).join(''); document.getElementById('op-grid').innerHTML = [ ['Provider Ref', d.providerRef||'—'], ['Openprovider', 'api.openprovider.eu'], ].map(function(x){ return '
'+x[0]+'
'+x[1]+'
'; }).join(''); } /* ─── Toggles ────────────────────────────────────────────── */ async function toggleAR() { var el=document.getElementById('tog-ar'); var newVal=!el.classList.contains('on'); el.classList.toggle('on',newVal); document.getElementById('tog-ar-lbl').textContent=newVal?'Ενεργό — ανανεώνεται αυτόματα':'Ανενεργό — θυμήσου να ανανεώσεις'; try{ await apiFetch('PUT','/account/domains/'+encodeURIComponent(_fqdn)+'/autorenew',{enabled:newVal}); }catch(e){} showToast('Auto-Renew '+(newVal?'ενεργοποιήθηκε':'απενεργοποιήθηκε'),'ok'); } async function toggleLock() { var el=document.getElementById('tog-lock'); var newVal=!el.classList.contains('on'); el.classList.toggle('on',newVal); document.getElementById('hd-lock').style.opacity=newVal?'1':'.25'; try{ await apiFetch('PUT','/account/domains/'+encodeURIComponent(_fqdn)+'/lock',{locked:newVal}); }catch(e){} showToast('Domain Lock '+(newVal?'ενεργοποιήθηκε':'απενεργοποιήθηκε'),'ok'); } /* ─── Tabs ───────────────────────────────────────────────── */ function switchTab(name,btn) { ['dns','ns','info'].forEach(function(t){document.getElementById('tab-'+t).style.display=t===name?'block':'none';}); document.querySelectorAll('.dns-tab').forEach(function(b){b.classList.remove('on');}); btn.classList.add('on'); } /* ─── Renew ──────────────────────────────────────────────── */ function openRenewModal(){document.getElementById('mo-renew').classList.add('open');_renewYrs=1;calcRenew();} function setRenYrs(y){_renewYrs=y;[1,2,3,5].forEach(function(n){var b=document.getElementById('ry'+n);b.style.background=n===y?'#111':'#fff';b.style.color=n===y?'#fff':'#111';b.style.borderColor=n===y?'#111':'var(--line)';});calcRenew();} function calcRenew(){var s=_renewPrice*_renewYrs,v=s*.24,t=s+v;document.getElementById('ry-yrs').textContent=_renewYrs;document.getElementById('ry-sub').textContent='€'+s.toFixed(2);document.getElementById('ry-vat').textContent='€'+v.toFixed(2);document.getElementById('ry-tot').textContent='€'+t.toFixed(2);} function goRenewCheckout(){localStorage.setItem('ae_domain_cart',JSON.stringify([{fqdn:_fqdn,tld:_domain?.tld||'',price:_renewPrice*_renewYrs,years:_renewYrs,type:'renew'}]));location.href='/domains-checkout.html';} /* ─── Helpers ────────────────────────────────────────────── */ function fmtDate(d){return d?new Date(d).toLocaleDateString('el-GR',{day:'2-digit',month:'long',year:'numeric'}):'—';} function showToast(msg,type){var c=document.getElementById('toast-c');if(!c){c=document.createElement('div');c.id='toast-c';c.style.cssText='position:fixed;bottom:1.2rem;right:1.2rem;z-index:9999;display:flex;flex-direction:column;gap:.4rem';document.body.appendChild(c);}var el=document.createElement('div');el.style.cssText='padding:.7rem 1rem;border-radius:9px;font-size:.78rem;font-weight:600;box-shadow:0 8px 24px rgba(0,0,0,.12);animation:fadein .2s ease;'+(type==='ok'?'background:#f0fdf4;color:#16a34a;border:1px solid #bbf7d0':'background:#fff0f0;color:#dc2626;border:1px solid #fecaca');el.textContent=msg;c.appendChild(el);setTimeout(function(){el.style.opacity='0';el.style.transition='opacity .3s';setTimeout(function(){el.remove();},300);},3000);} /* Modal overlay close */ ['mo-rec','mo-del','mo-renew'].forEach(function(id){var m=document.getElementById(id);m.addEventListener('click',function(e){if(e.target===m)m.classList.remove('open');});});