Spaces for Purchase List

This commit is contained in:
2026-10-21 00:12:49 -04:00
parent 5bf8d0fe6b
commit 36fe4c3901
3 changed files with 125 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
module.exports = async function handler(req, res) {
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
res.setHeader("Content-Type", "application/json; charset=utf-8");
try {
const response = await fetch(
"https://spacesops.com/getspaces?app=spaces-wallet&format=json",
{ cache: "no-store" }
);
const body = await response.text();
res.status(response.status).send(body);
} catch (error) {
res.status(502).json({ success: false, error: "Unable to load spaces" });
}
};
+101
View File
@@ -251,6 +251,36 @@
border-radius: 999px;
}
.spaces-list {
display: flex;
flex-wrap: wrap;
gap: 0.65rem;
}
.space-tag {
display: inline-flex;
align-items: center;
font-size: 0.95rem;
font-weight: 600;
color: var(--text);
background: var(--surface);
border: 1px solid var(--border);
padding: 0.5rem 0.9rem;
border-radius: 999px;
}
.space-tag::before {
content: "@";
color: var(--brand-light);
margin-right: 0.05rem;
}
.spaces-status {
margin: 0 0 1.25rem;
color: var(--text-muted);
font-size: 0.95rem;
}
/* Footer */
footer {
padding: 2.5rem 0 3rem;
@@ -374,6 +404,17 @@
</div>
</section>
<section id="spaces">
<div class="wrap">
<h2>Spaces available in SpacesWallet</h2>
<p class="section-lead">
Active @spaces currently listed for discovery and purchase in the app.
</p>
<p class="spaces-status" id="spaces-status">Loading live listings…</p>
<div class="spaces-list" id="spaces-list" aria-live="polite"></div>
</div>
</section>
<section>
<div class="wrap">
<h2>Built for crypto natives</h2>
@@ -423,5 +464,65 @@
<p>&copy; 2026 Lunde Cognitive Effects Inc.</p>
</div>
</footer>
<script>
const SPACES_ENDPOINTS = [
"/api/spaces",
"https://spacesops.com/getspaces?app=spaces-wallet&format=json"
];
const FALLBACK_SPACES = [
"space", "tabconf", "bitvocation", "nsite", "yeti", "ungovernable",
"bitcoinand", "thisweekinbitcoin", "twib", "imagineif", "acorn",
"bitcoin21", "usdt", "usat", "cnht", "mxnt", "xaut", "usdc", "eurc",
"zap", "pubkey", "cyber", "swifty", "heart"
];
function renderSpaces(names, sourceLabel) {
const list = document.getElementById("spaces-list");
const status = document.getElementById("spaces-status");
list.replaceChildren();
names.forEach((name) => {
const tag = document.createElement("span");
tag.className = "space-tag";
tag.textContent = name;
list.appendChild(tag);
});
status.textContent = names.length + " active spaces · " + sourceLabel;
}
function namesFromPayload(data) {
if (!data || !Array.isArray(data.spaces)) return [];
return data.spaces
.slice()
.sort((a, b) => (a.show_order || 0) - (b.show_order || 0))
.map((space) => space.space_name)
.filter(Boolean);
}
function freshUrl(url) {
return url + (url.includes("?") ? "&" : "?") + "t=" + Date.now();
}
async function loadSpaces() {
const status = document.getElementById("spaces-status");
status.textContent = "Refreshing listings…";
for (const url of SPACES_ENDPOINTS) {
try {
const response = await fetch(freshUrl(url), { cache: "no-store" });
if (!response.ok) continue;
const names = namesFromPayload(await response.json());
if (names.length) {
renderSpaces(names, "updated just now");
return;
}
} catch (error) {
// Try the next endpoint or fall back to the last known list.
}
}
renderSpaces(FALLBACK_SPACES, "last known listings");
}
window.addEventListener("pageshow", loadSpaces);
</script>
</body>
</html>
+9
View File
@@ -1,5 +1,14 @@
{
"headers": [
{
"source": "/api/spaces",
"headers": [
{
"key": "Cache-Control",
"value": "no-store, no-cache, must-revalidate"
}
]
},
{
"source": "/apk/(.*\\.apk)",
"headers": [