Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/controlplane/portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (server *Server) renderPortal(response http.ResponseWriter, status int, vie
const portalHTML = `<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>CloudRING · Development provider</title><link rel="stylesheet" href="/assets/portal.css"></head>
<body><main><header><a class="brand" href="/" aria-label="CloudRING home"><span class="ring" aria-hidden="true"></span>CloudRING</a><span class="badge">Development</span></header>
<body><main><header><a class="brand" href="/" aria-label="CloudRING home"><svg class="ring" viewBox="0 0 28 28" aria-hidden="true"><circle cx="14" cy="14" r="10.5" fill="none" stroke="#1C3F8F" stroke-width="2.2"/><circle cx="14" cy="14" r="5" fill="none" stroke="#1C3F8F" stroke-width="1.4" stroke-dasharray="2.4 2.4"/><circle cx="22.5" cy="8.5" r="2.2" fill="#985000"/></svg><span><span class="kicker">TRUKHIN</span><span class="hash">#</span>CloudRING</span></a><span class="badge">OCSv3 Workspace</span></header>
{{if .Unavailable}}<section class="card"><p class="eyebrow">Provider unavailable</p><h1>Waiting for durable state</h1><p>The database or installation identity could not be verified. Retry after the installation is healthy.</p><a class="button" href="/">Check again</a></section>
{{else if .Provider}}<section class="intro"><p class="eyebrow">Your development provider</p><h1>A place to build.</h1><p>This isolated installation is ready for integration work.</p></section>
<section class="card"><div class="card-heading"><h2>Installation</h2><span class="ready">Ready</span></div><dl><div><dt>Installation</dt><dd>{{.Provider.InstallationID}}</dd></div><div><dt>Operator</dt><dd>{{.Provider.OperatorID}}</dd></div><div><dt>Created</dt><dd><time>{{.Provider.CreatedAt.Format "02 Jan 2006, 15:04 UTC"}}</time></dd></div><div><dt>Database</dt><dd>Connected · writable</dd></div></dl></section>
Expand All @@ -30,4 +30,4 @@ const portalHTML = `<!doctype html>
{{else}}<section class="intro"><p class="eyebrow">Your development provider</p><h1>Start with a clean slate.</h1><p>Sign in to inspect this isolated CloudRING installation.</p></section><section class="card login"><h2>Development operator</h2><p>Use the access key created for this installation.</p>{{if .AuthenticationFailed}}<p class="error" role="alert">The access key or session is invalid. Please sign in again.</p>{{end}}<form method="post" action="/login"><label for="token">Development access key</label><input id="token" name="token" type="password" autocomplete="off" required minlength="64" maxlength="64" pattern="[a-f0-9]{64}" spellcheck="false"><button class="button" type="submit">Sign in</button></form></section><footer><p>Development environment · Production use is not supported.</p></footer>{{end}}
</main></body></html>`

const portalCSS = `:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#172b31;background:#f5f7f5;font-synthesis:none;color-scheme:light}*{box-sizing:border-box}body{margin:0}main{max-width:880px;margin:auto;padding:34px 28px 48px}header{display:flex;align-items:center;justify-content:space-between;padding-bottom:36px;border-bottom:1px solid #dce3dd}.brand{display:flex;align-items:center;gap:12px;color:inherit;text-decoration:none;font-size:23px;font-weight:750;letter-spacing:-.7px}.ring{height:27px;width:27px;border:6px solid #147d62;border-radius:50%;box-shadow:inset 0 0 0 3px #f5f7f5}.badge{font-size:12px;font-weight:650;color:#7b571b;background:#f6ebd4;border:1px solid #e9d6b0;border-radius:6px;padding:6px 10px}.intro{padding:44px 0 26px}.eyebrow{text-transform:uppercase;font-size:11px;font-weight:750;letter-spacing:1.6px;color:#4d6b62}h1{font-size:42px;letter-spacing:-1.6px;line-height:1.12;margin:14px 0 15px;font-weight:680}p{font-size:15px;line-height:1.65;color:#52666a}h2{font-size:17px;font-weight:680;margin:0}.card{background:#fff;border:1px solid #dce3dd;border-radius:12px;padding:28px;margin-top:20px}.card-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}.ready{font-size:12px;color:#116645;background:#e6f4e9;border-radius:30px;padding:5px 11px}.ready:before{content:"";display:inline-block;border-radius:50%;background:#23855c;width:6px;height:6px;margin-right:7px}dl{margin:25px 0 0}dl div{display:grid;grid-template-columns:140px 1fr;gap:18px;padding:12px 0;border-top:1px solid #eef1ed}dt{font-size:13px;color:#667b7e}dd{font-size:13px;margin:0;overflow-wrap:anywhere}.empty{text-align:center;padding:36px 30px}.empty p{max-width:360px;margin:10px auto 0;font-size:14px}.empty-mark{width:36px;height:36px;display:grid;place-items:center;margin:0 auto 16px;font-size:22px;color:#6d8278;background:#f1f5f0;border:1px solid #e1e9df;border-radius:9px}footer{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:24px}footer p{font-size:12px;color:#70807b}.text-button{background:none;color:#365b50;border:0;font:inherit;font-size:13px;text-decoration:underline;cursor:pointer}.login{max-width:520px;margin-top:4px}.login p{font-size:14px;margin:12px 0 24px}label{display:block;font-size:13px;font-weight:600;margin:0 0 9px}input[type=password]{display:block;width:100%;height:44px;border:1px solid #bbc9c0;border-radius:7px;padding:10px 12px;font:inherit;margin-bottom:20px;outline:none}input:focus{border-color:#147d62;box-shadow:0 0 0 3px #147d6220}.button{display:inline-block;border:0;border-radius:7px;background:#147d62;color:white;font:inherit;font-size:14px;font-weight:650;padding:12px 22px;text-decoration:none;cursor:pointer}.button:hover{background:#0e6850}.button:focus-visible,a:focus-visible,button:focus-visible{outline:3px solid #72b8a4;outline-offset:3px}.error{color:#a23030!important;background:#fff2ef;padding:12px;border:1px solid #f3d3cc;border-radius:6px}@media(max-width:560px){main{padding:24px 18px}h1{font-size:34px}.card{padding:22px}dl div{grid-template-columns:1fr;gap:5px}footer{align-items:flex-start;flex-direction:column;gap:0}header{padding-bottom:25px}.intro{padding-top:30px}}`
const portalCSS = `:root{--paper:#EDF1F6;--paper-elevated:#F6F8FB;--paper-deep:#E3E9F2;--ink:#14213A;--ink-2:#334463;--ink-muted:#536482;--prussian:#1C3F8F;--prussian-deep:#102B63;--signal:#985000;--ok:#24653F;--rule:#D5DCE8;--rule-strong:#BCC7DA;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,sans-serif;color:var(--ink);background:var(--paper);font-synthesis:none;color-scheme:light}*{box-sizing:border-box}body{margin:0;background-image:linear-gradient(to right,var(--rule) 1px,transparent 1px),linear-gradient(to bottom,var(--rule) 1px,transparent 1px);background-size:32px 32px}main{max-width:880px;margin:auto;padding:34px 28px 48px}header{display:flex;align-items:center;justify-content:space-between;padding-bottom:36px;border-bottom:1px solid var(--rule-strong)}.brand{display:flex;align-items:center;gap:12px;color:inherit;text-decoration:none;font-family:"DIN Alternate","Franklin Gothic Medium","Avenir Next Condensed",sans-serif;font-size:22px;font-weight:750;letter-spacing:-.4px}.kicker{display:block;font-family:"SFMono-Regular",ui-monospace,Menlo,Consolas,monospace;font-size:10px;letter-spacing:.14em;color:var(--ink-muted)}.hash{color:var(--prussian)}.ring{height:28px;width:28px;flex:none}.badge{font-family:"SFMono-Regular",ui-monospace,Menlo,Consolas,monospace;font-size:12px;font-weight:650;color:var(--prussian);background:#E6EEF9;border:1px solid var(--rule-strong);border-radius:6px;padding:6px 10px}.intro{padding:44px 0 26px}.eyebrow{text-transform:uppercase;font-family:"SFMono-Regular",ui-monospace,Menlo,Consolas,monospace;font-size:11px;font-weight:750;letter-spacing:1.6px;color:var(--signal)}h1{font-family:"DIN Alternate","Franklin Gothic Medium","Avenir Next Condensed",sans-serif;font-size:42px;letter-spacing:-1.2px;line-height:1.08;margin:14px 0 15px;font-weight:700}p{font-size:15px;line-height:1.65;color:var(--ink-2)}h2{font-size:17px;font-weight:680;margin:0}.card{background:var(--paper-elevated);border:1px solid var(--rule-strong);border-radius:8px;padding:28px;margin-top:20px;box-shadow:0 1px 2px rgba(20,33,58,.06),0 12px 32px rgba(20,33,58,.07)}.card-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}.ready{font-size:12px;font-weight:650;color:var(--ok);background:#E6F3EC;border-radius:30px;padding:5px 11px}.ready:before{content:"";display:inline-block;border-radius:50%;background:var(--ok);width:6px;height:6px;margin-right:7px}dl{margin:25px 0 0}dl div{display:grid;grid-template-columns:140px 1fr;gap:18px;padding:12px 0;border-top:1px solid var(--rule)}dt{font-size:13px;color:var(--ink-muted)}dd{font-family:"SFMono-Regular",ui-monospace,Menlo,Consolas,monospace;font-size:13px;margin:0;overflow-wrap:anywhere}.empty{text-align:center;padding:36px 30px}.empty p{max-width:360px;margin:10px auto 0;font-size:14px}.empty-mark{width:36px;height:36px;display:grid;place-items:center;margin:0 auto 16px;font-size:22px;color:var(--prussian);background:var(--paper-deep);border:1px solid var(--rule-strong);border-radius:8px}footer{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:24px}footer p{font-size:12px;color:var(--ink-muted)}.text-button{background:none;color:var(--prussian);border:0;font:inherit;font-size:13px;text-decoration:underline;cursor:pointer}.login{max-width:520px;margin-top:4px;border-left:3px solid var(--prussian)}.login p{font-size:14px;margin:12px 0 24px}label{display:block;font-size:13px;font-weight:600;margin:0 0 9px}input[type=password]{display:block;width:100%;height:44px;border:1px solid var(--rule-strong);border-radius:6px;background:#fff;padding:10px 12px;font:inherit;margin-bottom:20px;outline:none}input:focus{border-color:var(--prussian);box-shadow:0 0 0 3px rgba(28,63,143,.22)}.button{display:inline-block;border:0;border-radius:6px;background:var(--prussian);color:#fff;font:inherit;font-size:14px;font-weight:650;padding:12px 22px;text-decoration:none;cursor:pointer}.button:hover{background:var(--prussian-deep)}.button:focus-visible,a:focus-visible,button:focus-visible{outline:3px solid rgba(28,63,143,.35);outline-offset:3px}.error{color:#A93126!important;background:#FDECEA;padding:12px;border:1px solid #F3D3CC;border-radius:6px}@media(max-width:560px){main{padding:24px 18px}h1{font-size:34px}.card{padding:22px}dl div{grid-template-columns:1fr;gap:5px}footer{align-items:flex-start;flex-direction:column;gap:0}header{padding-bottom:25px}.intro{padding-top:30px}}`
Loading