From d40666b878018c0cf1581ea9a06bd6bcb7177002 Mon Sep 17 00:00:00 2001 From: kittentm Date: Mon, 20 Jul 2026 22:46:21 +0200 Subject: [PATCH] ? --- app/components/TheHeader.vue | 2 +- app/locales/message-en.json | 9 +- app/pages/docs/policy/[id].vue | 490 +++++++++++++++++++++++++++++++++ bun.lock | 8 + package.json | 2 + server/api/policies.ts | 56 ++++ 6 files changed, 565 insertions(+), 2 deletions(-) create mode 100644 app/pages/docs/policy/[id].vue create mode 100644 server/api/policies.ts diff --git a/app/components/TheHeader.vue b/app/components/TheHeader.vue index 98c2a3f..5dfbd30 100644 --- a/app/components/TheHeader.vue +++ b/app/components/TheHeader.vue @@ -13,7 +13,7 @@ diff --git a/app/locales/message-en.json b/app/locales/message-en.json index 29a7e97..6ade601 100644 --- a/app/locales/message-en.json +++ b/app/locales/message-en.json @@ -1,7 +1,7 @@ { "nav": { "supportedGames": "Supported games", - "errorCodes": "Error Codes", + "errorCodes": "View Policies", "discordServer": "Discord Server", "installSpbr": "Install SPBR", "searchPlaceholder": "Search" @@ -68,5 +68,12 @@ "aromaTitle": "Aroma", "aromaDesc": "Hacked" } + }, + "policies": { + "sidebarHeader": "Spacebar Network Policies", + "sidebarSubheader": "Game Rules", + "loading": "Loading...", + "errorText": "Error", + "lastUpdated": "Last updated: " } } \ No newline at end of file diff --git a/app/pages/docs/policy/[id].vue b/app/pages/docs/policy/[id].vue new file mode 100644 index 0000000..2b7ebb5 --- /dev/null +++ b/app/pages/docs/policy/[id].vue @@ -0,0 +1,490 @@ + + + + + diff --git a/bun.lock b/bun.lock index c1aee6b..bf6963a 100644 --- a/bun.lock +++ b/bun.lock @@ -10,8 +10,10 @@ "@nuxt/ui": "^4.10.0", "@nuxt/vite-builder": "^4.5.0", "@primer/octicons": "^19.29.2", + "@types/node": "^26.1.1", "@unhead/ssr": "^3.2.1", "@unhead/vue": "^3.2.1", + "marked-alert": "^2.1.2", "nuxt": "^4.5.0", "tailwindcss": "^4.3.3", }, @@ -616,6 +618,8 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], + "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], @@ -1318,6 +1322,8 @@ "marked": ["marked@17.0.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA=="], + "marked-alert": ["marked-alert@2.1.2", "", { "peerDependencies": { "marked": ">=7.0.0" } }, "sha512-EFNRZ08d8L/iEIPLTlQMDjvwIsj03gxWCczYTht6DCiHJIZhMk4NK5gtPY9UqAYb09eV5VGT+jD4lp396E0I+w=="], + "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], @@ -1770,6 +1776,8 @@ "undici": ["undici@8.8.0", "", {}, "sha512-ubshXMXwF3MQIMF1y/WxZdNBnjEKeSg2wF5mcGUtU55YTw34tnVVpKRlLf7ruDXZ5344KokPVX4RBx1wJm64Bw=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], "unhead": ["unhead@3.2.1", "", { "dependencies": { "hookable": "^6.1.1", "unplugin": "^3.3.0" }, "peerDependencies": { "vite": ">=6.4.2" }, "optionalPeers": ["vite"] }, "sha512-Z7VNRf0QJlRZmwA1p5gsnmKYkjnbvV/CXdJAL+VMDmMF+RS2P4FqLouEhBA6WOuKPe3ZZ8EZgX2zQm7ZkAGDPg=="], diff --git a/package.json b/package.json index 37a4ff5..631e22b 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,10 @@ "@nuxt/ui": "^4.10.0", "@nuxt/vite-builder": "^4.5.0", "@primer/octicons": "^19.29.2", + "@types/node": "^26.1.1", "@unhead/ssr": "^3.2.1", "@unhead/vue": "^3.2.1", + "marked-alert": "^2.1.2", "nuxt": "^4.5.0", "tailwindcss": "^4.3.3" }, diff --git a/server/api/policies.ts b/server/api/policies.ts new file mode 100644 index 0000000..5b53fcb --- /dev/null +++ b/server/api/policies.ts @@ -0,0 +1,56 @@ +import fs from 'node:fs' +import path from 'node:path' + +export default defineEventHandler(async () => { + const gameRulesDir = path.resolve(process.cwd(), 'public/policy/game-rules') + + const baseRules = [ + { id: 'general', name: 'General Rules' }, + { id: 'conduct', name: 'Code of Conduct' }, + { id: 'privacy', name: 'Privacy Policy' } + ] + + const games: Array<{ id: string, name: string, version: string }> = [] + + try { + if (fs.existsSync(gameRulesDir)) { + const folders = await fs.promises.readdir(gameRulesDir) + + for (const folder of folders) { + const folderPath = path.join(gameRulesDir, folder) + + if (!folderPath.startsWith(gameRulesDir)) { + continue + } + + const stat = await fs.promises.stat(folderPath) + + if (stat.isDirectory()) { + const metadataPath = path.join(folderPath, 'metadata.json') + + if (fs.existsSync(metadataPath)) { + try { + const metaContent = await fs.promises.readFile(metadataPath, 'utf-8') + const parsedMeta = JSON.parse(metaContent) + + games.push({ + id: folder, + name: parsedMeta.name || folder, + version: parsedMeta.version || '1.0.0' + }) + } catch (jsonError) { + console.error(`Malformed metadata.json in ${folder}:`, jsonError) + } + } + } + } + } + } catch (error) { + console.error('Error scanning public policy tree:', error) + } + + return { + baseRules, + games + } +})