bank landing: community-shared explorer withdraw UI and how-it-works
This commit is contained in:
parent
57973db4f0
commit
31c8dcdb9c
1 changed files with 161 additions and 16 deletions
|
|
@ -82,6 +82,32 @@
|
|||
border: 1px solid rgba(232, 168, 56, 0.4);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.community-note,
|
||||
.how-note {
|
||||
margin: 0 0 1.15rem;
|
||||
padding: 0.8rem 0.95rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.45;
|
||||
text-align: left;
|
||||
}
|
||||
.community-note {
|
||||
background: rgba(94, 234, 212, 0.1);
|
||||
border: 1px solid rgba(94, 234, 212, 0.4);
|
||||
color: #ccfbf1;
|
||||
}
|
||||
.community-note strong { color: #5eead4; font-weight: 750; }
|
||||
.how-note {
|
||||
background: rgba(232, 168, 56, 0.08);
|
||||
border: 1px solid rgba(232, 168, 56, 0.35);
|
||||
color: #f5e6c8;
|
||||
}
|
||||
.how-note strong { color: #f0c86a; font-weight: 750; }
|
||||
.how-note ol {
|
||||
margin: 0.4rem 0 0;
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
.how-note li { margin: 0.25rem 0; }
|
||||
|
||||
.step-card {
|
||||
background: var(--card);
|
||||
|
|
@ -535,10 +561,17 @@
|
|||
<span class="badge">Exploration · GOA</span>
|
||||
<h1>GOA Exploration Bank</h1>
|
||||
<p class="sub">
|
||||
Install the wallet, then <strong>one QR</strong> adds the exchange and starts a withdraw.
|
||||
Install the wallet, then <strong>one QR</strong> withdraws GOA from a
|
||||
<strong>community-shared bank account</strong> — no personal bank registration.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<p class="community-note" role="note">
|
||||
<strong>Community pool.</strong>
|
||||
Demo GOA comes from one shared exploration account used by everyone on this site
|
||||
(not your private bank login). Balance is shared; amounts are small; for play only.
|
||||
</p>
|
||||
|
||||
<!-- ========== LIVE STATS ========== -->
|
||||
<section class="stats" id="stats" aria-labelledby="stats-title" hidden>
|
||||
<h2 id="stats-title">GOA flow</h2>
|
||||
|
|
@ -683,23 +716,36 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ========== STEP 2: one-step withdraw-exchange ========== -->
|
||||
<section class="step-card step-money" aria-labelledby="step2-title">
|
||||
<!-- ========== STEP 2: one-click community pool withdraw ========== -->
|
||||
<section class="step-card step-money" id="withdraw" aria-labelledby="step2-title">
|
||||
<h2 id="step2-title"><span class="step-num">2</span> Withdraw GOA</h2>
|
||||
<p class="step-tagline">One-step: add exchange + withdraw</p>
|
||||
<p class="step-tagline">One QR · community-shared account · no registration</p>
|
||||
<div class="step-body">
|
||||
<div class="qr-box">
|
||||
<div id="qr-withdraw-exchange"></div>
|
||||
<div id="qr-withdraw-demo"></div>
|
||||
<div class="qr-label">Scan or open in wallet</div>
|
||||
</div>
|
||||
<a class="cta teal" id="open-withdraw-exchange"
|
||||
href="taler://withdraw-exchange/exchange.hacktivism.ch/">
|
||||
<a class="cta teal" id="open-withdraw-demo" href="#">
|
||||
Open in wallet →
|
||||
</a>
|
||||
<p class="meta">taler://withdraw-exchange/exchange.hacktivism.ch/</p>
|
||||
<p class="meta" id="withdraw-demo-meta">Preparing community withdraw…</p>
|
||||
<p class="meta" id="withdraw-demo-amount" hidden></p>
|
||||
<button type="button" class="cta-sec" id="withdraw-demo-refresh" style="margin-top:0.5rem">
|
||||
Get a fresh QR
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside class="how-note" aria-labelledby="how-title">
|
||||
<strong id="how-title">How this works</strong>
|
||||
<ol>
|
||||
<li>A <strong>community-shared bank account</strong> (demo pool) already holds GOA.</li>
|
||||
<li>Each “Open in wallet” / QR creates a <strong>one-shot withdraw</strong> from that pool — you do <em>not</em> open your own bank account.</li>
|
||||
<li>Your GNU Taler app receives coins after the bank confirms (automatic on this demo).</li>
|
||||
<li>Optional below: register your <em>own</em> bank UI account if you want a private balance.</li>
|
||||
</ol>
|
||||
</aside>
|
||||
|
||||
<!-- ========== Optional bank UI + mini GOA shop teaser ========== -->
|
||||
<div class="more-section">
|
||||
<span class="more-label">Optional · bank UI & GOA shop</span>
|
||||
|
|
@ -757,25 +803,124 @@
|
|||
<script>
|
||||
(function () {
|
||||
var WEBUI = "https://bank.hacktivism.ch/webui/";
|
||||
/* taler-ops one-step: add exchange + start withdraw */
|
||||
/* Secondary: own-account path (register first) */
|
||||
var WITHDRAW_EXCHANGE = "taler://withdraw-exchange/exchange.hacktivism.ch/";
|
||||
|
||||
function makeQr(el, text) {
|
||||
if (!el) return;
|
||||
el.innerHTML = "";
|
||||
if (!text) {
|
||||
el.textContent = "…";
|
||||
return;
|
||||
}
|
||||
if (typeof QRCode === "undefined") {
|
||||
el.textContent = "QR lib missing";
|
||||
return;
|
||||
}
|
||||
new QRCode(el, {
|
||||
text: text,
|
||||
width: 220,
|
||||
height: 220,
|
||||
correctLevel: QRCode.CorrectLevel.M
|
||||
});
|
||||
// Encode off-DOM so QR is visible (canvas/img not collapsed)
|
||||
var size = 220;
|
||||
var scratch = document.createElement("div");
|
||||
scratch.style.cssText =
|
||||
"position:fixed;left:-9999px;top:0;width:" + size + "px;height:" + size + "px;opacity:0";
|
||||
document.body.appendChild(scratch);
|
||||
try {
|
||||
new QRCode(scratch, {
|
||||
text: String(text),
|
||||
width: size,
|
||||
height: size,
|
||||
colorDark: "#000000",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.M
|
||||
});
|
||||
var canvas = scratch.querySelector("canvas");
|
||||
var dataUrl = canvas ? canvas.toDataURL("image/png") : "";
|
||||
if (dataUrl) {
|
||||
var img = document.createElement("img");
|
||||
img.alt = "QR code";
|
||||
img.width = size;
|
||||
img.height = size;
|
||||
img.src = dataUrl;
|
||||
img.style.display = "block";
|
||||
img.style.margin = "0 auto";
|
||||
el.appendChild(img);
|
||||
} else {
|
||||
el.appendChild(scratch.firstChild || document.createTextNode("QR failed"));
|
||||
}
|
||||
} catch (e) {
|
||||
el.textContent = "QR encode failed";
|
||||
}
|
||||
if (scratch.parentNode) scratch.parentNode.removeChild(scratch);
|
||||
}
|
||||
|
||||
makeQr(document.getElementById("qr-withdraw-exchange"), WITHDRAW_EXCHANGE);
|
||||
function setDemoWithdraw(uri, amount) {
|
||||
uri = String(uri || "").replace(/:443\//g, "/").replace(/:443\?/g, "?");
|
||||
var open = document.getElementById("open-withdraw-demo");
|
||||
var meta = document.getElementById("withdraw-demo-meta");
|
||||
var amtEl = document.getElementById("withdraw-demo-amount");
|
||||
if (open) {
|
||||
open.href = uri;
|
||||
open.classList.remove("disabled");
|
||||
}
|
||||
if (meta) meta.textContent = uri;
|
||||
if (amtEl) {
|
||||
if (amount) {
|
||||
amtEl.hidden = false;
|
||||
amtEl.textContent = "Amount: " + amount + " · from community pool";
|
||||
} else {
|
||||
amtEl.hidden = true;
|
||||
}
|
||||
}
|
||||
makeQr(document.getElementById("qr-withdraw-demo"), uri);
|
||||
}
|
||||
|
||||
function loadDemoWithdraw() {
|
||||
var meta = document.getElementById("withdraw-demo-meta");
|
||||
var open = document.getElementById("open-withdraw-demo");
|
||||
if (meta) meta.textContent = "Preparing community withdraw…";
|
||||
if (open) {
|
||||
open.removeAttribute("href");
|
||||
open.classList.add("disabled");
|
||||
}
|
||||
// Prefer live mint (fresh op each time); fall back to static withdraw.uri
|
||||
fetch("/intro/demo-withdraw.json", { cache: "no-store" })
|
||||
.then(function (r) {
|
||||
if (!r.ok) throw new Error("HTTP " + r.status);
|
||||
return r.json();
|
||||
})
|
||||
.then(function (d) {
|
||||
if (!d || !d.taler_withdraw_uri) throw new Error(d && d.error ? d.error : "no uri");
|
||||
setDemoWithdraw(d.taler_withdraw_uri, d.amount || "");
|
||||
})
|
||||
.catch(function () {
|
||||
return fetch("/intro/withdraw.uri", { cache: "no-store" })
|
||||
.then(function (r) {
|
||||
if (!r.ok) throw new Error("no fallback");
|
||||
return r.text();
|
||||
})
|
||||
.then(function (t) {
|
||||
var uri = String(t || "").trim();
|
||||
if (!uri) throw new Error("empty");
|
||||
return fetch("/intro/withdraw.amount", { cache: "no-store" })
|
||||
.then(function (r) {
|
||||
return r.ok ? r.text() : Promise.resolve("");
|
||||
})
|
||||
.then(function (a) {
|
||||
setDemoWithdraw(uri, String(a || "").trim());
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (meta) {
|
||||
meta.textContent =
|
||||
"Could not prepare withdraw — try again or use bank UI. " +
|
||||
(err && err.message ? err.message : "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadDemoWithdraw();
|
||||
var refreshBtn = document.getElementById("withdraw-demo-refresh");
|
||||
if (refreshBtn) refreshBtn.onclick = function () { loadDemoWithdraw(); };
|
||||
makeQr(document.getElementById("qr-webui"), WEBUI);
|
||||
|
||||
function fmtCest(unix, fallback) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue