339 lines
22 KiB
HTML
339 lines
22 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>CluPilot — Cluster anlegen</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="clupilot.css">
|
||
<style>
|
||
.wizard{display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start}
|
||
.step-pane{display:none;animation:fade .25s ease}
|
||
.step-pane.active{display:block}
|
||
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
||
.summary{position:sticky;top:84px;display:flex;flex-direction:column;gap:0}
|
||
.sum-price{font-family:var(--mono);font-size:26px;font-weight:600;letter-spacing:-0.02em}
|
||
.sum-price .unit{font-size:13px;color:var(--muted-2);font-weight:500}
|
||
.slider-row{display:flex;align-items:center;gap:14px}
|
||
.slider-row input[type=range]{flex:1;accent-color:var(--accent);height:5px}
|
||
.node-val{font-family:var(--mono);font-weight:600;font-size:18px;min-width:24px;text-align:center}
|
||
.wizard-foot{display:flex;align-items:center;justify-content:space-between;margin-top:6px}
|
||
@media (max-width:1100px){.wizard{grid-template-columns:1fr}.summary{position:static}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="app">
|
||
<aside class="sidebar" data-screen-label="Sidebar">
|
||
<div class="brand"><div class="brand-mark" aria-hidden="true"></div><div class="brand-name">CluPilot<span>v2.4</span></div></div>
|
||
<button class="ws-switch" aria-label="Workspace wechseln">
|
||
<div class="ws-avatar">AC</div>
|
||
<div class="ws-meta"><div class="ws-name">Acme Cluster</div><div class="ws-plan">team · 14 user</div></div>
|
||
<svg class="ws-chev" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 9l4-4 4 4M8 15l4 4 4-4"/></svg>
|
||
</button>
|
||
<nav class="nav">
|
||
<a class="nav-item" href="CluPilot Dashboard Glass.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></svg><span>Dashboard</span></a>
|
||
<a class="nav-item active" href="Server.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="4" width="18" height="7" rx="1.5"/><rect x="3" y="13" width="18" height="7" rx="1.5"/><circle cx="7" cy="7.5" r="0.7" fill="currentColor"/><circle cx="7" cy="16.5" r="0.7" fill="currentColor"/></svg><span>Server</span><span class="count">6</span></a>
|
||
<a class="nav-item" href="Sites.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg><span>Sites</span><span class="count">87</span></a>
|
||
<a class="nav-item" href="Backups.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M21 12c0 5-9 9-9 9s-9-4-9-9V5l9-3 9 3v7z"/><path d="M9 11l2 2 4-4"/></svg><span>Backups</span></a>
|
||
<a class="nav-item" href="Sicherheit.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7l8-4z"/></svg><span>Sicherheit</span><span class="count" style="color:var(--warning);background:var(--warning-soft);border-color:rgba(194,130,15,0.3)">3</span></a>
|
||
<div class="nav-title">Konto</div>
|
||
<a class="nav-item" href="Team.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.9M16 3.1a4 4 0 0 1 0 7.8"/></svg><span>Team</span></a>
|
||
<a class="nav-item" href="Einstellungen.html"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg><span>Einstellungen</span></a>
|
||
</nav>
|
||
<div class="plan-box">
|
||
<div class="plan-row"><div class="plan-name">Team Plan</div><div class="plan-tag">PRO</div></div>
|
||
<div class="plan-meter"><span></span></div>
|
||
<div class="plan-stats"><span>87 / 140 sites</span><span>62%</span></div>
|
||
</div>
|
||
</aside>
|
||
|
||
<main class="main" data-screen-label="Cluster anlegen">
|
||
<div class="topbar">
|
||
<a class="icon-btn" href="Server.html" aria-label="Zurück">
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg>
|
||
</a>
|
||
<div>
|
||
<div class="page-title">Cluster anlegen</div>
|
||
<div class="page-sub">neuer server-cluster · acme</div>
|
||
</div>
|
||
<div class="top-spacer"></div>
|
||
<div class="stepper" id="stepper">
|
||
<div class="step active" data-step="0"><span class="num">1</span>Basis</div>
|
||
<span class="step-line"></span>
|
||
<div class="step" data-step="1"><span class="num">2</span>Region & Hardware</div>
|
||
<span class="step-line"></span>
|
||
<div class="step" data-step="2"><span class="num">3</span>WordPress</div>
|
||
<span class="step-line"></span>
|
||
<div class="step" data-step="3"><span class="num">4</span>Überprüfen</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="content">
|
||
<div class="wizard">
|
||
<!-- ============ FORM ============ -->
|
||
<div>
|
||
<!-- STEP 1 -->
|
||
<div class="step-pane active" data-pane="0">
|
||
<section class="card">
|
||
<div class="card-head"><h3>Basis-Konfiguration</h3><span class="meta">schritt 1 / 4</span></div>
|
||
<div class="card-body">
|
||
<div class="field">
|
||
<label>Cluster-Name</label>
|
||
<input class="input" id="f-name" value="eu-prod-04" placeholder="z. B. eu-prod-04" />
|
||
<span class="hint">Wird in Listen, SSH und im Audit-Log angezeigt.</span>
|
||
</div>
|
||
<div class="field">
|
||
<label>Slug / Hostname</label>
|
||
<div class="input-group"><input id="f-slug" value="eu-prod-04" /><span class="suffix">.clupilot.net</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<label>Umgebung</label>
|
||
<div class="opt-grid cols-3" data-radio="env">
|
||
<div class="opt selected" data-val="Produktion"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Produktion</div><div class="opt-desc">live · monitoring</div></div></div>
|
||
<div class="opt" data-val="Staging"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Staging</div><div class="opt-desc">test · isoliert</div></div></div>
|
||
<div class="opt" data-val="Entwicklung"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Entwicklung</div><div class="opt-desc">sandbox</div></div></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label>Beschreibung <span class="hint" style="font-weight:400">(optional)</span></label>
|
||
<textarea class="input" id="f-desc" placeholder="Wofür ist dieser Cluster gedacht?"></textarea>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- STEP 2 -->
|
||
<div class="step-pane" data-pane="1">
|
||
<section class="card">
|
||
<div class="card-head"><h3>Region</h3><span class="meta">schritt 2 / 4</span></div>
|
||
<div class="card-body">
|
||
<div class="opt-grid cols-2" data-radio="region">
|
||
<div class="opt selected" data-val="Frankfurt · de-fra"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">🇩🇪 Frankfurt</div><div class="opt-desc">de-fra · 4 ms</div></div></div>
|
||
<div class="opt" data-val="Amsterdam · nl-ams"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">🇳🇱 Amsterdam</div><div class="opt-desc">nl-ams · 11 ms</div></div></div>
|
||
<div class="opt" data-val="Helsinki · fi-hel"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">🇫🇮 Helsinki</div><div class="opt-desc">fi-hel · 24 ms</div></div></div>
|
||
<div class="opt" data-val="Ashburn · us-east"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">🇺🇸 Ashburn</div><div class="opt-desc">us-east · 92 ms</div></div></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section class="card" style="margin-top:18px">
|
||
<div class="card-head"><h3>Server-Größe</h3></div>
|
||
<div class="card-body">
|
||
<div class="opt-grid" data-radio="size" data-price>
|
||
<div class="opt" data-val="Starter" data-amt="29"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Starter</div><div class="opt-desc">2 vCPU · 8 GB · 160 GB NVMe · ~15 sites</div></div><div class="opt-price">29 €/mo</div></div>
|
||
<div class="opt selected" data-val="Standard" data-amt="59"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Standard <span class="pill accent" style="margin-left:4px">beliebt</span></div><div class="opt-desc">4 vCPU · 16 GB · 320 GB NVMe · ~40 sites</div></div><div class="opt-price">59 €/mo</div></div>
|
||
<div class="opt" data-val="Performance" data-amt="119"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Performance</div><div class="opt-desc">8 vCPU · 32 GB · 640 GB NVMe · ~90 sites</div></div><div class="opt-price">119 €/mo</div></div>
|
||
<div class="opt" data-val="Dedicated" data-amt="249"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">Dedicated</div><div class="opt-desc">16 vCPU · 64 GB · 1,2 TB NVMe · ~200 sites</div></div><div class="opt-price">249 €/mo</div></div>
|
||
</div>
|
||
<div class="field" style="margin-top:18px;margin-bottom:0">
|
||
<label>Anzahl Nodes</label>
|
||
<div class="slider-row">
|
||
<input type="range" id="f-nodes" min="1" max="6" value="1" />
|
||
<span class="node-val" id="nodes-val">1</span>
|
||
</div>
|
||
<span class="hint">Ab 2 Nodes wird automatisch ein Load-Balancer & Failover eingerichtet.</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- STEP 3 -->
|
||
<div class="step-pane" data-pane="2">
|
||
<section class="card">
|
||
<div class="card-head"><h3>WordPress-Voreinstellungen</h3><span class="meta">schritt 3 / 4</span></div>
|
||
<div class="card-body">
|
||
<div class="grid-2">
|
||
<div class="field"><label>PHP-Version</label>
|
||
<div class="opt-grid cols-3" data-radio="php">
|
||
<div class="opt" data-val="8.1"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">8.1</div></div></div>
|
||
<div class="opt selected" data-val="8.2"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">8.2</div></div></div>
|
||
<div class="opt" data-val="8.3"><span class="opt-radio"></span><div class="opt-main"><div class="opt-title">8.3</div></div></div>
|
||
</div>
|
||
</div>
|
||
<div class="field"><label>WordPress-Version</label><input class="input input-mono" value="6.5.2 (aktuell)" readonly /></div>
|
||
</div>
|
||
<div style="margin-top:6px">
|
||
<div class="toggle-row" data-toggle="autoupdate"><div class="tr-body"><div class="tr-title">Automatische Updates</div><div class="tr-desc">core- & sichere plugin-updates</div></div><div class="toggle on"></div></div>
|
||
<div class="toggle-row" data-toggle="ssl"><div class="tr-body"><div class="tr-title">SSL automatisch (Let's Encrypt)</div><div class="tr-desc">zertifikate ausstellen & erneuern</div></div><div class="toggle on"></div></div>
|
||
<div class="toggle-row" data-toggle="cdn"><div class="tr-body"><div class="tr-title">Edge-CDN & Cache</div><div class="tr-desc">globaler cache für statische inhalte</div></div><div class="toggle on"></div></div>
|
||
<div class="toggle-row" data-toggle="backup"><div class="tr-body"><div class="tr-title">Tägliche Backups</div><div class="tr-desc">03:00 utc · 30 tage aufbewahrung</div></div><div class="toggle on"></div></div>
|
||
<div class="toggle-row" data-toggle="waf"><div class="tr-body"><div class="tr-title">WAF & Brute-Force-Schutz</div><div class="tr-desc">managed firewall-regelsatz</div></div><div class="toggle on"></div></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- STEP 4 -->
|
||
<div class="step-pane" data-pane="3">
|
||
<section class="card">
|
||
<div class="card-head"><h3><svg class="hico" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12l5 5L20 7"/></svg>Überprüfen & anlegen</h3><span class="meta">schritt 4 / 4</span></div>
|
||
<div class="card-body">
|
||
<div class="kv"><span class="k">Cluster-Name</span><span class="v" data-review="name">eu-prod-04</span></div>
|
||
<div class="kv"><span class="k">Hostname</span><span class="v" data-review="host">eu-prod-04.clupilot.net</span></div>
|
||
<div class="kv"><span class="k">Umgebung</span><span class="v" data-review="env">Produktion</span></div>
|
||
<div class="kv"><span class="k">Region</span><span class="v" data-review="region">Frankfurt · de-fra</span></div>
|
||
<div class="kv"><span class="k">Server-Größe</span><span class="v" data-review="size">Standard</span></div>
|
||
<div class="kv"><span class="k">Nodes</span><span class="v" data-review="nodes">1</span></div>
|
||
<div class="kv"><span class="k">PHP / WordPress</span><span class="v" data-review="stack">8.2 · WP 6.5.2</span></div>
|
||
<div class="kv"><span class="k">Funktionen</span><span class="v" data-review="features">5 aktiv</span></div>
|
||
</div>
|
||
<div class="card-body" style="border-top:1px solid var(--hairline);display:flex;align-items:center;gap:12px">
|
||
<div class="feed-ico accent" style="width:34px;height:34px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 8v5M12 16h.01"/><circle cx="12" cy="12" r="9"/></svg></div>
|
||
<div class="tr-desc" style="flex:1">Die Bereitstellung dauert i. d. R. <b>2–4 Minuten</b>. Du wirst benachrichtigt, sobald der Cluster bereit ist.</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- nav buttons -->
|
||
<div class="wizard-foot">
|
||
<button class="btn-ghost" id="btn-back" style="visibility:hidden">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M15 18l-6-6 6-6"/></svg>Zurück
|
||
</button>
|
||
<button class="btn-primary lg" id="btn-next">
|
||
Weiter
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ SUMMARY ============ -->
|
||
<section class="card summary">
|
||
<div class="card-head"><h3>Zusammenfassung</h3></div>
|
||
<div class="card-body">
|
||
<div class="kv"><span class="k">Name</span><span class="v" id="s-name">eu-prod-04</span></div>
|
||
<div class="kv"><span class="k">Umgebung</span><span class="v" id="s-env">Produktion</span></div>
|
||
<div class="kv"><span class="k">Region</span><span class="v" id="s-region">Frankfurt</span></div>
|
||
<div class="kv"><span class="k">Größe</span><span class="v" id="s-size">Standard</span></div>
|
||
<div class="kv"><span class="k">Nodes</span><span class="v" id="s-nodes">1×</span></div>
|
||
</div>
|
||
<div class="card-body" style="border-top:1px solid var(--hairline)">
|
||
<div style="display:flex;align-items:flex-end;justify-content:space-between">
|
||
<div>
|
||
<div class="tr-desc">Geschätzt / Monat</div>
|
||
<div class="sum-price"><span id="s-price">59</span> €<span class="unit">/mo</span></div>
|
||
</div>
|
||
<span class="pill success">inkl. backup</span>
|
||
</div>
|
||
<div class="hint" style="margin-top:10px">Abgerechnet pro Stunde · jederzeit kündbar. Preis exkl. MwSt.</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="foot">CluPilot · bereitstellung über terraform · region eu-central-1</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<script>
|
||
const state = {
|
||
step:0, total:4,
|
||
name:'eu-prod-04', env:'Produktion', region:'Frankfurt · de-fra',
|
||
size:'Standard', amt:59, nodes:1, php:'8.2',
|
||
features:{autoupdate:true,ssl:true,cdn:true,backup:true,waf:true},
|
||
};
|
||
|
||
/* ---- radio option groups ---- */
|
||
document.querySelectorAll('[data-radio]').forEach(group=>{
|
||
group.querySelectorAll('.opt').forEach(opt=>{
|
||
opt.addEventListener('click',()=>{
|
||
group.querySelectorAll('.opt').forEach(o=>o.classList.remove('selected'));
|
||
opt.classList.add('selected');
|
||
const key = group.dataset.radio;
|
||
const val = opt.dataset.val;
|
||
if(key==='env') state.env = val;
|
||
if(key==='region') state.region = val;
|
||
if(key==='php') state.php = val;
|
||
if(key==='size'){ state.size = val; state.amt = +opt.dataset.amt; }
|
||
render();
|
||
});
|
||
});
|
||
});
|
||
|
||
/* ---- toggles ---- */
|
||
document.querySelectorAll('[data-toggle]').forEach(row=>{
|
||
const t = row.querySelector('.toggle');
|
||
row.addEventListener('click',()=>{
|
||
t.classList.toggle('on');
|
||
state.features[row.dataset.toggle] = t.classList.contains('on');
|
||
render();
|
||
});
|
||
});
|
||
|
||
/* ---- inputs ---- */
|
||
const nameEl = document.getElementById('f-name');
|
||
const slugEl = document.getElementById('f-slug');
|
||
nameEl.addEventListener('input',()=>{ state.name = nameEl.value || '—'; render(); });
|
||
const nodesEl = document.getElementById('f-nodes');
|
||
nodesEl.addEventListener('input',()=>{ state.nodes = +nodesEl.value; render(); });
|
||
|
||
/* ---- stepper ---- */
|
||
const panes = [...document.querySelectorAll('.step-pane')];
|
||
const steps = [...document.querySelectorAll('#stepper .step')];
|
||
const btnNext = document.getElementById('btn-next');
|
||
const btnBack = document.getElementById('btn-back');
|
||
|
||
function gotoStep(n){
|
||
state.step = Math.max(0, Math.min(state.total-1, n));
|
||
panes.forEach((p,i)=>p.classList.toggle('active', i===state.step));
|
||
steps.forEach((s,i)=>{
|
||
s.classList.toggle('active', i===state.step);
|
||
s.classList.toggle('done', i<state.step);
|
||
});
|
||
btnBack.style.visibility = state.step===0 ? 'hidden':'visible';
|
||
if(state.step===state.total-1){
|
||
btnNext.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M5 12l5 5L20 7"/></svg> Cluster anlegen';
|
||
}else{
|
||
btnNext.innerHTML = 'Weiter <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>';
|
||
}
|
||
render();
|
||
}
|
||
btnNext.addEventListener('click',()=>{
|
||
if(state.step===state.total-1){
|
||
btnNext.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" style="animation:spin 1s linear infinite"><path d="M21 12a9 9 0 1 1-6.2-8.5"/></svg> Wird angelegt…';
|
||
btnNext.disabled = true;
|
||
setTimeout(()=>{ window.location.href = 'Server.html'; }, 1400);
|
||
return;
|
||
}
|
||
gotoStep(state.step+1);
|
||
});
|
||
btnBack.addEventListener('click',()=>gotoStep(state.step-1));
|
||
steps.forEach(s=>s.addEventListener('click',()=>gotoStep(+s.dataset.step)));
|
||
|
||
/* ---- render derived values ---- */
|
||
function render(){
|
||
slugify();
|
||
const lb = state.nodes>1 ? state.nodes*state.amt + 9 : state.amt;
|
||
// summary card
|
||
document.getElementById('s-name').textContent = state.name;
|
||
document.getElementById('s-env').textContent = state.env;
|
||
document.getElementById('s-region').textContent = state.region.split(' · ')[0];
|
||
document.getElementById('s-size').textContent = state.size;
|
||
document.getElementById('s-nodes').textContent = state.nodes+'×';
|
||
document.getElementById('s-price').textContent = lb;
|
||
document.getElementById('nodes-val').textContent = state.nodes;
|
||
// review step
|
||
const feats = Object.values(state.features).filter(Boolean).length;
|
||
const set=(k,v)=>{const el=document.querySelector(`[data-review="${k}"]`); if(el) el.textContent=v;};
|
||
set('name', state.name);
|
||
set('host', (slugEl.value||state.name)+'.clupilot.net');
|
||
set('env', state.env);
|
||
set('region', state.region);
|
||
set('size', state.size+' · '+state.amt+' €/mo');
|
||
set('nodes', state.nodes + (state.nodes>1?' (+ load-balancer)':''));
|
||
set('stack', state.php+' · WP 6.5.2');
|
||
set('features', feats+' aktiv');
|
||
}
|
||
function slugify(){
|
||
if(document.activeElement!==slugEl){
|
||
slugEl.value = state.name.toLowerCase().replace(/[^a-z0-9-]+/g,'-').replace(/^-+|-+$/g,'');
|
||
}
|
||
}
|
||
const style=document.createElement('style');
|
||
style.textContent='@keyframes spin{to{transform:rotate(360deg)}}';
|
||
document.head.appendChild(style);
|
||
gotoStep(0);
|
||
</script>
|
||
</body>
|
||
</html>
|