Onboarding: status chip, QR, copy feedback, platform auto-open

This commit is contained in:
Aaron
2025-12-13 14:45:46 -05:00
parent b911171045
commit bcb6f3005d
2 changed files with 104 additions and 7 deletions

View File

@@ -14,6 +14,9 @@
</header> </header>
<p class="welcome">Great news — youre already on your Pi-Kit and its responding.</p> <p class="welcome">Great news — youre already on your Pi-Kit and its responding.</p>
<div class="status-row" aria-live="polite">
<span class="status-chip" id="statusChip">Youre on HTTP — trust the CA or continue to HTTPS.</span>
</div>
<p class="subtle"> <p class="subtle">
Everything stays on your local network. Lets move you to the secure (HTTPS) dashboard so you Everything stays on your local network. Lets move you to the secure (HTTPS) dashboard so you
can manage Pi-Kit safely. can manage Pi-Kit safely.
@@ -45,47 +48,59 @@
Download Pi-Kit CA Download Pi-Kit CA
</a> </a>
</div> </div>
<p class="checksum">SHA256: <code class="inline">6bc217c340e502ef20117bd4dc35e05f9f16c562cc3a236d3831a9947caddb97</code></p>
<details> <details>
<summary>Windows</summary> <summary id="win">Windows</summary>
<p>Run <strong>mmc</strong> → Add/Remove Snap-in → Certificates (Computer) → Trusted Root CAs → Import <em>pikit-ca.crt</em>.</p> <p>Run <strong>mmc</strong> → Add/Remove Snap-in → Certificates (Computer) → Trusted Root CAs → Import <em>pikit-ca.crt</em>.</p>
</details> </details>
<details> <details>
<summary>macOS</summary> <summary id="mac">macOS</summary>
<p>Double-click <em>pikit-ca.crt</em> → Always Trust.</p> <p>Double-click <em>pikit-ca.crt</em> → Always Trust.</p>
</details> </details>
<details> <details>
<summary>Linux (Arch / Manjaro / Garuda, etc.)</summary> <summary id="arch">Linux (Arch / Manjaro / Garuda, etc.)</summary>
<code id="archCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /etc/ca-certificates/trust-source/anchors/ && sudo trust extract-compat</code> <code id="archCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /etc/ca-certificates/trust-source/anchors/ && sudo trust extract-compat</code>
<button class="copy" data-target="archCmd">Copy</button> <button class="copy" data-target="archCmd">Copy</button>
</details> </details>
<details> <details>
<summary>Linux (Debian / Ubuntu)</summary> <summary id="deb">Linux (Debian / Ubuntu)</summary>
<code id="debCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /usr/local/share/ca-certificates/pikit-ca.crt && sudo update-ca-certificates</code> <code id="debCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /usr/local/share/ca-certificates/pikit-ca.crt && sudo update-ca-certificates</code>
<button class="copy" data-target="debCmd">Copy</button> <button class="copy" data-target="debCmd">Copy</button>
</details> </details>
<details> <details>
<summary>Linux (Fedora)</summary> <summary id="fedora">Linux (Fedora)</summary>
<code id="fedoraCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /etc/pki/ca-trust/source/anchors/pikit-ca.crt && sudo update-ca-trust</code> <code id="fedoraCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /etc/pki/ca-trust/source/anchors/pikit-ca.crt && sudo update-ca-trust</code>
<button class="copy" data-target="fedoraCmd">Copy</button> <button class="copy" data-target="fedoraCmd">Copy</button>
</details> </details>
<details> <details>
<summary>BSD (FreeBSD / OpenBSD)</summary> <summary id="bsd">BSD (FreeBSD / OpenBSD)</summary>
<code id="bsdCmd">fetch -o /tmp/pikit-ca.crt http://pikit.local/assets/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /usr/local/share/certs/pikit-ca.crt && sudo certctl rehash</code> <code id="bsdCmd">fetch -o /tmp/pikit-ca.crt http://pikit.local/assets/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /usr/local/share/certs/pikit-ca.crt && sudo certctl rehash</code>
<button class="copy" data-target="bsdCmd">Copy</button> <button class="copy" data-target="bsdCmd">Copy</button>
</details> </details>
<div id="copyStatus" class="copy-status" aria-live="polite"></div>
</section> </section>
<section class="actions"> <section class="actions">
<button id="continueBtn">Go to secure dashboard</button> <button id="continueBtn">Go to secure dashboard</button>
<div class="qr-block">
<div>
<p class="qr-title">Use your phone</p>
<p class="subtle tiny">Scan to open https://pikit.local</p>
</div>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAYAAAA9zQYyAAAAAklEQVR4AewaftIAAAVgSURBVO3BMWol3Q5G0W1xAwcddioEmv+YBEITeeFL6jTUpdr+rf7W+uDz129EljBEFjFEFjFEFjFEFjFEFjFEFnnxJ9XDT5XhXKkenpbhXKkeTjKck+rhrgznrurhp8pwLhgiixgiixgiixgiixgiixgii7x4V4bz3aqHn6p6OMlwrlQPJ9XDlQznHRnOd6sebjJEFjFEFjFEFjFEFjFEFjFEFnnxN1QPT8lwvkqG847q4UqGs0318KQM50GGyCKGyCKGyCKGyCKGyCIv5P+qhydVDycZzkn1cFeGIxgiixgiixgiixgiixgiixgii7yQ/8tw3lE9XMlwTqoHeZwhsoghsoghsoghsoghssiLvyHD+a/KcE6qhydVD1+leriS4Twpw/kPM0QWMUQWMUQWMUQWMUQWMUQWefGu6uEnqh5OMpyT6uEkw7lSPZxkOCfVw5UM56R6eFL18AMZIosYIosYIosYIosYIosYIou8+JMM519SPZxkOCfVw5UM56R6OMlwvkKGs4whsoghsoghsoghsoghssiLd1UPd2U4J9XDlQznpHq4K8N5R/XwpAznpHr4CtXDSYZzpXr4L8hwLhgiixgiixgiixgiixgiixgii3zw+es3J9XDSYZzV/VwkuE8qXq4kuGcVA/vyHCuVA8nGc6TqocnZTjfrXo4yXAuGCKLGCKLGCKLGCKLGCKLGCKLvPiTDOekevhu1cNJhnOlenha9XBX9XCS4Twlw3lS9XCS4ZxUD1/AEFnEEFnEEFnEEFnEEFnEEFnkxbsynJPq4StkOE/KcE6qh5MM50r1cJLh3FU9fJXq4UqG844M50r1cJLh3GSILGKILGKILGKILGKILPLiT6qHd2Q4d1UPVzKck+rhrgznpHo4yXBOqof/qurhq1QPJxnOXdXDSYZzwRBZxBBZxBBZxBBZxBBZxBBZ5IPPX795R/VwV4ZzUj3cleGcVA93ZTgn1cOTMpwnVQ9PynDuqh5OMpy7qoeTDOeCIbKIIbKIIbKIIbKIIbKIIbLIiz+pHk4ynJPq4Ur1cJLhXKkeTqqHkwznSvXwVTKck+rhrgznrgznHdXDlQznJMM5qR6+gCGyiCGyiCGyiCGyiCGyyAefv37zjurhu2U4J9XDlQznpHo4yXBOqoe7MpwnVQ9XMpyT6uEkw7lSPZxkOHdVDycZzk2GyCKGyCKGyCKGyCKGyCKGyCIffP76zUn1cJLhfLfq4a4M56R6eEeGc1f1cJLhXKkefqoM5wsYIosYIosYIosYIosYIot88PnrN/+S6uGrZDjvqB6ekuE8qXp4R4ZzpXp4R4ZzwRBZxBBZxBBZxBBZxBBZxBBZ5MWfVA8/VYZzV4ZzUj2cZDg/UfVwkuH8QIbIIobIIobIIobIIobIIobIIi/eleF8t+rhrgznHRnOSfXwE2U43y3DOakebjJEFjFEFjFEFjFEFjFEFnnxN1QPT8lwnlQ9nGQ4T8pwTqqHkwznrurhSvXwDzFEFjFEFjFEFjFEFjFEFjFEFnnxr8lwTqqHkwznrurhJMM5qR7uynCeVD08qXq4kuGcZDg3GSKLGCKLGCKLGCKLGCKLGCKLvPjXVA8nGc5J9XCS4dxVPTyperiS4bwjw7lSPZxkOE+qHk4ynAuGyCKGyCKGyCKGyCKGyCIv/oYM5yeqHk4ynK+S4dxVPVypHt6R4dxVPZxkOFeqh5MM5yZDZBFDZBFDZBFDZBFDZBFDZJEPPn/95qR6+KkynCdVDycZzpXqYZsM50nVwzsynAuGyCKGyCKGyCKGyCKGyCKGyCIffP76jcgShsgihsgihsgihsgihsgi/wNnZIh4Pc9/WQAAAABJRU5ErkJggg==" alt="QR code to https://pikit.local" />
</div>
</section> </section>
<p class="footnote">Once trusted, this page will auto-forward you to the secure dashboard.</p> <p class="footnote">Once trusted, this page will auto-forward you to the secure dashboard.</p>
<p class="footnote">If the hostname ever fails, try http://&lt;pi-ip&gt;/ (or https://&lt;pi-ip&gt;/ — your browser will show the same warning to bypass).</p>
</main> </main>
<script> <script>
(function () { (function () {
const target = `https://${location.hostname}`; const target = `https://${location.hostname}`;
const hasCookie = document.cookie.includes("pikit_https_ok=1"); const hasCookie = document.cookie.includes("pikit_https_ok=1");
const statusChip = document.getElementById("statusChip");
const copyStatus = document.getElementById("copyStatus");
document.getElementById("continueBtn").addEventListener("click", () => { document.getElementById("continueBtn").addEventListener("click", () => {
window.location = target; window.location = target;
@@ -110,9 +125,14 @@
document.body.removeChild(ta); document.body.removeChild(ta);
} }
btn.textContent = "Copied"; btn.textContent = "Copied";
setTimeout(() => (btn.textContent = "Copy"), 1500); copyStatus.textContent = "Copied to clipboard.";
setTimeout(() => {
btn.textContent = "Copy";
copyStatus.textContent = "";
}, 1600);
} catch (err) { } catch (err) {
btn.textContent = "Failed"; btn.textContent = "Failed";
copyStatus.textContent = "Copy failed. Try manual copy.";
setTimeout(() => (btn.textContent = "Copy"), 1500); setTimeout(() => (btn.textContent = "Copy"), 1500);
} }
}); });
@@ -129,8 +149,29 @@
}); });
}); });
// Auto-open matching OS section
const ua = navigator.userAgent.toLowerCase();
const openOne = (id) => {
const el = document.getElementById(id)?.parentElement;
if (el && el.tagName === "DETAILS") {
el.setAttribute("open", "");
detailBlocks.forEach((other) => {
if (other !== el) other.removeAttribute("open");
});
}
};
if (ua.includes("windows")) openOne("win");
else if (ua.includes("mac")) openOne("mac");
else if (ua.includes("arch") || ua.includes("manjaro")) openOne("arch");
else if (ua.includes("fedora")) openOne("fedora");
else if (ua.includes("ubuntu") || ua.includes("debian")) openOne("deb");
else if (ua.includes("bsd")) openOne("bsd");
if (hasCookie) { if (hasCookie) {
statusChip.textContent = "HTTPS trusted — redirecting…";
window.location = target; window.location = target;
} else {
statusChip.textContent = "Youre on HTTP — trust the CA or click Go to secure dashboard.";
} }
})(); })();
</script> </script>

View File

@@ -64,6 +64,22 @@ p {
color: var(--text); color: var(--text);
} }
.status-row {
margin: 6px 0 10px;
}
.status-chip {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 9px 12px;
border-radius: 999px;
background: rgba(68, 211, 146, 0.08);
border: 1px solid var(--border);
color: var(--text);
font-weight: 600;
}
.dot { .dot {
width: 12px; width: 12px;
height: 12px; height: 12px;
@@ -152,6 +168,46 @@ a.ghost {
background: rgba(255, 255, 255, 0.06); background: rgba(255, 255, 255, 0.06);
} }
.checksum {
margin: 4px 0 10px;
color: var(--muted);
}
code.inline {
display: inline;
padding: 4px 6px;
border-radius: 6px;
}
.qr-block {
display: flex;
align-items: center;
gap: 14px;
margin-top: 8px;
padding: 12px 14px;
border: 1px solid var(--border);
border-radius: 12px;
background: rgba(255, 255, 255, 0.02);
width: min(360px, 100%);
}
.qr-title {
margin: 0;
font-weight: 700;
color: var(--text);
}
.tiny {
margin: 2px 0 0;
font-size: 0.9rem;
}
.copy-status {
min-height: 18px;
color: var(--text);
font-size: 0.95rem;
}
button.copy { button.copy {
margin-left: 8px; margin-left: 8px;
background: rgba(255, 255, 255, 0.05); background: rgba(255, 255, 255, 0.05);