@meddleware/dashboard 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="icon" href="/favicon.ico">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Meddleware</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@meddleware/dashboard",
3
+ "version": "0.1.1",
4
+ "description": "Meddleware tools hub — Vue 3 SPA listing hosted services (Walrus, Access Gate) with white-label deploy options.",
5
+ "author": "MeddleWare <meddleware@proton.me>",
6
+ "license": "0BSD",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/meddleware-org/dashboard.git"
10
+ },
11
+ "type": "module",
12
+ "files": [
13
+ "src",
14
+ "index.html",
15
+ "vite.config.ts",
16
+ "tsconfig.json",
17
+ "CHANGELOG.md"
18
+ ],
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "build": "vue-tsc --noEmit && vite build",
22
+ "preview": "vite preview",
23
+ "type-check": "vue-tsc --noEmit"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "@meddleware/design-tokens": "^0.1.2",
30
+ "@meddleware/ui": "^0.1.5",
31
+ "pinia": "^4.0.2",
32
+ "vue": "^3.5.40",
33
+ "vue-router": "^5.2.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "~24.12.2",
37
+ "@vitejs/plugin-vue": "^6.0.8",
38
+ "typescript": "~6.0.0",
39
+ "vite": "^8.1.5",
40
+ "vue-tsc": "~3.3.0"
41
+ },
42
+ "engines": {
43
+ "node": "^22.18.0 || >=24.12.0"
44
+ }
45
+ }
package/src/App.vue ADDED
@@ -0,0 +1,60 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { useRoute, RouterView } from 'vue-router'
4
+ import {
5
+ AppHeader, AppSidebar, AppFooter,
6
+ ColorModeControl, SidebarItem, StatusWidget,
7
+ useColorMode,
8
+ } from '@meddleware/ui'
9
+
10
+ const { mode, set } = useColorMode('dark')
11
+ const route = useRoute()
12
+ const year = new Date().getFullYear()
13
+
14
+ const isWalrus = computed(() => route.path === '/walrus')
15
+ const isAccessGate = computed(() => route.path === '/access-gate')
16
+ const isSealedStorage = computed(() => route.path === '/sealed-storage')
17
+ </script>
18
+
19
+ <template>
20
+ <div class="app-shell">
21
+ <AppHeader class="app-shell__header" variant="dark">
22
+ <template #brand>
23
+ <span class="brand-mark" aria-hidden="true">◆</span>
24
+ <span>Meddleware</span>
25
+ </template>
26
+ <template #actions>
27
+ <StatusWidget />
28
+ <ColorModeControl :model-value="mode" @update:model-value="set" />
29
+ </template>
30
+ </AppHeader>
31
+
32
+ <AppSidebar class="app-shell__sidebar" variant="dark">
33
+ <nav aria-label="Tools">
34
+ <router-link to="/walrus" custom v-slot="{ navigate }">
35
+ <SidebarItem label="Walrus" icon="🗄" :active="isWalrus" @click="navigate" />
36
+ </router-link>
37
+ <router-link to="/access-gate" custom v-slot="{ navigate }">
38
+ <SidebarItem label="Access Gate" icon="🔐" :active="isAccessGate" @click="navigate" />
39
+ </router-link>
40
+ <router-link to="/sealed-storage" custom v-slot="{ navigate }">
41
+ <SidebarItem label="Sealed Storage" icon="🔒" :active="isSealedStorage" @click="navigate" />
42
+ </router-link>
43
+ </nav>
44
+ </AppSidebar>
45
+
46
+ <main class="app-shell__main">
47
+ <RouterView />
48
+ </main>
49
+
50
+ <AppFooter class="app-shell__footer" variant="transparent">
51
+ <span>&copy; {{ year }} Meddleware</span>
52
+ </AppFooter>
53
+ </div>
54
+ </template>
55
+
56
+ <style scoped>
57
+ .brand-mark {
58
+ color: var(--gold);
59
+ }
60
+ </style>
package/src/env.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.vue' {
4
+ import type { DefineComponent } from 'vue'
5
+ const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>
6
+ export default component
7
+ }
package/src/main.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+
4
+ // Shared design system: tokens first (defines CSS vars), then base element defaults.
5
+ import '@meddleware/design-tokens/tokens.css'
6
+ import '@meddleware/ui/base.css'
7
+ import './styles.css'
8
+
9
+ import { useColorMode } from '@meddleware/ui'
10
+ import App from './App.vue'
11
+ import router from './router'
12
+
13
+ // Default to dark on first load (persisted to localStorage thereafter).
14
+ // Applied before mount to avoid a light-mode flash.
15
+ useColorMode('dark')
16
+
17
+ const app = createApp(App)
18
+ app.use(createPinia())
19
+ app.use(router)
20
+ app.mount('#app')
@@ -0,0 +1,17 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+ import Home from '../views/Home.vue'
3
+ import WalrusPage from '../views/WalrusPage.vue'
4
+ import AccessGatePage from '../views/AccessGatePage.vue'
5
+ import SealedStoragePage from '../views/SealedStoragePage.vue'
6
+
7
+ const router = createRouter({
8
+ history: createWebHistory(import.meta.env.BASE_URL),
9
+ routes: [
10
+ { path: '/', component: Home },
11
+ { path: '/walrus', component: WalrusPage },
12
+ { path: '/access-gate', component: AccessGatePage },
13
+ { path: '/sealed-storage', component: SealedStoragePage },
14
+ ],
15
+ })
16
+
17
+ export default router
package/src/styles.css ADDED
@@ -0,0 +1,49 @@
1
+ /*
2
+ * Dashboard app-layout styles. Design tokens + element defaults come from
3
+ * @meddleware/design-tokens + @meddleware/ui/base.css (imported in main.ts).
4
+ * This file holds only the app-shell grid and page-content helpers.
5
+ */
6
+
7
+ #app {
8
+ min-height: 100vh;
9
+ }
10
+
11
+ /*
12
+ * App shell: full-width header on top; sidebar pinned left immediately under the
13
+ * header down to the bottom of the page/viewport; main fills the central space;
14
+ * footer spans from the sidebar's right edge to the viewport's right edge.
15
+ */
16
+ .app-shell {
17
+ display: grid;
18
+ grid-template-columns: var(--mw-sidebar-width, 240px) 1fr;
19
+ grid-template-rows: var(--mw-header-height, 56px) 1fr auto;
20
+ grid-template-areas:
21
+ "header header"
22
+ "sidebar main"
23
+ "sidebar footer";
24
+ min-height: 100vh;
25
+ }
26
+
27
+ .app-shell__header { grid-area: header; }
28
+ .app-shell__sidebar { grid-area: sidebar; }
29
+ .app-shell__main { grid-area: main; min-width: 0; padding: 1.5rem; }
30
+ .app-shell__footer { grid-area: footer; }
31
+
32
+ @media (max-width: 720px) {
33
+ .app-shell {
34
+ grid-template-columns: 1fr;
35
+ grid-template-areas:
36
+ "header"
37
+ "main"
38
+ "footer";
39
+ }
40
+ .app-shell__sidebar { display: none; }
41
+ }
42
+
43
+ .prose {
44
+ max-width: 68ch;
45
+ color: var(--muted);
46
+ }
47
+ .prose h2 {
48
+ color: var(--text);
49
+ }
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import { UiCard } from '@meddleware/ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="feature-page">
7
+ <h1>🔐 Access Gate</h1>
8
+
9
+ <UiCard class="section">
10
+ <h2>Overview</h2>
11
+ <p>
12
+ Access Gate is an on-chain NFT access control system on Sui. Operators deploy a gate
13
+ smart contract that issues soulbound or transferable NFT passes; the gate enforces a
14
+ platform commission (20 bps) on every pass purchase, routed directly on-chain. The
15
+ Meddleware Access Gate console lets you create gates, configure pricing, and monitor
16
+ your gate's activity — all from a browser wallet, with no backend required.
17
+ </p>
18
+ </UiCard>
19
+
20
+ <UiCard class="section">
21
+ <h2>Launch</h2>
22
+ <p>Use the hosted Meddleware Access Gate console — no installation required.</p>
23
+ <a
24
+ href="https://sui-access-gate.meddleware.co.uk"
25
+ target="_blank"
26
+ rel="noopener"
27
+ class="launch-btn"
28
+ >
29
+ Open Access Gate →
30
+ </a>
31
+ </UiCard>
32
+
33
+ <UiCard class="section section--secondary">
34
+ <h2>White-label</h2>
35
+ <p>
36
+ Deploy a branded version of the Access Gate console for your own project. The
37
+ <code>access-gate-ui</code> Docker image is a standalone Vue 3 SPA — run it behind
38
+ your own subdomain and point users at your specific gate ID. The commission enforcement
39
+ is in the smart contract, so any gate created through your interface still routes 20 bps
40
+ to Meddleware automatically.
41
+ </p>
42
+ <p class="note">
43
+ Detailed deployment instructions will be available at <code>dev.meddleware.co.uk</code>.
44
+ </p>
45
+ </UiCard>
46
+ </div>
47
+ </template>
48
+
49
+ <style scoped>
50
+ .feature-page { max-width: 760px; }
51
+ h1 { margin-top: 0; }
52
+
53
+ .section { margin-bottom: 1.25rem; }
54
+ .section h2 { margin-top: 0; }
55
+
56
+ .section--secondary { opacity: 0.9; }
57
+ .section--secondary h2 { font-size: 1rem; }
58
+
59
+ .launch-btn {
60
+ display: inline-block;
61
+ margin-top: 0.25rem;
62
+ padding: 0.55rem 1.2rem;
63
+ border-radius: var(--mw-radius, 10px);
64
+ background: var(--accent);
65
+ color: #fff;
66
+ text-decoration: none;
67
+ font-weight: 600;
68
+ }
69
+ .launch-btn:hover { opacity: 0.88; }
70
+
71
+ code {
72
+ font-size: 0.85em;
73
+ background: color-mix(in srgb, currentColor 10%, transparent);
74
+ padding: 0.1em 0.35em;
75
+ border-radius: 4px;
76
+ }
77
+
78
+ .note {
79
+ margin-top: 0.75rem;
80
+ font-size: 0.85rem;
81
+ color: var(--muted);
82
+ }
83
+ </style>
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import { UiCard } from '@meddleware/ui'
3
+ import { useRouter } from 'vue-router'
4
+
5
+ const router = useRouter()
6
+ </script>
7
+
8
+ <template>
9
+ <div class="home">
10
+ <h1>Meddleware Tools</h1>
11
+ <p class="prose">
12
+ Decentralised storage and smart-contract-powered access control — hosted and ready to use.
13
+ </p>
14
+
15
+ <div class="card-grid">
16
+ <UiCard class="tool-card" @click="router.push('/walrus')">
17
+ <h2>🗄 Walrus</h2>
18
+ <p>Upload and manage blobs on Walrus decentralised storage. NFT-gated relay, wallet-connected, no backend required.</p>
19
+ <a
20
+ href="https://sui-walrus.meddleware.co.uk"
21
+ target="_blank"
22
+ rel="noopener"
23
+ class="launch-link"
24
+ @click.stop
25
+ >
26
+ Launch →
27
+ </a>
28
+ </UiCard>
29
+
30
+ <UiCard class="tool-card" @click="router.push('/access-gate')">
31
+ <h2>🔐 Access Gate</h2>
32
+ <p>Create and manage NFT-gated access controls on Sui. Commission-enforced on-chain, no server required.</p>
33
+ <a
34
+ href="https://sui-access-gate.meddleware.co.uk"
35
+ target="_blank"
36
+ rel="noopener"
37
+ class="launch-link"
38
+ @click.stop
39
+ >
40
+ Launch →
41
+ </a>
42
+ </UiCard>
43
+
44
+ <UiCard class="tool-card" @click="router.push('/sealed-storage')">
45
+ <h2>🔒 Sealed Storage</h2>
46
+ <p>Client-side encrypted, access-gated storage: seal a file, store it on Walrus, and gate decryption on-chain (NFT pass, time-lock, and more). Testnet — mainnet pending.</p>
47
+ <a
48
+ href="https://sui-seal.meddleware.co.uk"
49
+ target="_blank"
50
+ rel="noopener"
51
+ class="launch-link"
52
+ @click.stop
53
+ >
54
+ Launch →
55
+ </a>
56
+ </UiCard>
57
+ </div>
58
+ </div>
59
+ </template>
60
+
61
+ <style scoped>
62
+ .home { max-width: 900px; }
63
+ h1 { margin-top: 0; }
64
+
65
+ .card-grid {
66
+ display: grid;
67
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
68
+ gap: 1rem;
69
+ margin-top: 1.5rem;
70
+ }
71
+
72
+ .tool-card { cursor: pointer; }
73
+ .tool-card h2 { margin-top: 0; }
74
+
75
+ .launch-link {
76
+ display: inline-block;
77
+ margin-top: 0.5rem;
78
+ color: var(--accent);
79
+ text-decoration: none;
80
+ font-weight: 500;
81
+ }
82
+ .launch-link:hover { text-decoration: underline; }
83
+ </style>
@@ -0,0 +1,99 @@
1
+ <script setup lang="ts">
2
+ import { UiCard } from '@meddleware/ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="feature-page">
7
+ <h1>🔒 Sealed Storage <span class="badge">Testnet · mainnet pending</span></h1>
8
+
9
+ <UiCard class="section">
10
+ <h2>Overview</h2>
11
+ <p>
12
+ Sealed Storage composes three primitives into one: encrypt a file in your browser with
13
+ <strong>Seal</strong> (threshold identity-based encryption), store the ciphertext on
14
+ <strong>Walrus</strong>, and gate decryption with an on-chain <strong>access policy</strong>.
15
+ Decryption keys are released by a committee of independent key servers only when the policy is
16
+ satisfied — no server ever holds your data or keys. Policies are modular: gate on an
17
+ <strong>access-gate NFT</strong>, a <strong>time-lock</strong>, and more over time.
18
+ </p>
19
+ </UiCard>
20
+
21
+ <UiCard class="section">
22
+ <h2>Launch</h2>
23
+ <p>Use the hosted Meddleware Sealed Storage app (testnet).</p>
24
+ <a
25
+ href="https://sui-seal.meddleware.co.uk"
26
+ target="_blank"
27
+ rel="noopener"
28
+ class="launch-btn"
29
+ >
30
+ Open Sealed Storage →
31
+ </a>
32
+ <p class="note">
33
+ Mainnet is pending: Seal committee mode is currently testnet-only. The app will enable mainnet
34
+ automatically once it ships.
35
+ </p>
36
+ </UiCard>
37
+
38
+ <UiCard class="section section--secondary">
39
+ <h2>White-label</h2>
40
+ <p>
41
+ Deploy your own branded Sealed Storage with the <code>seal-ui</code> Docker image: set your
42
+ network, policy package, key-server committee, and Walrus endpoints via build-time VITE args.
43
+ The policy contracts (<code>seal-policies-sui</code>) and client
44
+ (<code>@meddleware/seal-client</code>) are reusable — add your own policy type as a drop-in
45
+ Move module + client provider.
46
+ </p>
47
+ <p class="note">
48
+ Detailed deployment instructions will be available at <code>dev.meddleware.co.uk</code>.
49
+ </p>
50
+ </UiCard>
51
+ </div>
52
+ </template>
53
+
54
+ <style scoped>
55
+ .feature-page { max-width: 760px; }
56
+ h1 { margin-top: 0; }
57
+
58
+ .badge {
59
+ font-size: 0.6em;
60
+ vertical-align: middle;
61
+ text-transform: uppercase;
62
+ letter-spacing: 0.04em;
63
+ padding: 0.2em 0.6em;
64
+ border-radius: 999px;
65
+ background: color-mix(in srgb, var(--gold, #d29922) 22%, transparent);
66
+ color: var(--text);
67
+ }
68
+
69
+ .section { margin-bottom: 1.25rem; }
70
+ .section h2 { margin-top: 0; }
71
+
72
+ .section--secondary { opacity: 0.9; }
73
+ .section--secondary h2 { font-size: 1rem; }
74
+
75
+ .launch-btn {
76
+ display: inline-block;
77
+ margin-top: 0.25rem;
78
+ padding: 0.55rem 1.2rem;
79
+ border-radius: var(--mw-radius, 10px);
80
+ background: var(--accent);
81
+ color: #fff;
82
+ text-decoration: none;
83
+ font-weight: 600;
84
+ }
85
+ .launch-btn:hover { opacity: 0.88; }
86
+
87
+ code {
88
+ font-size: 0.85em;
89
+ background: color-mix(in srgb, currentColor 10%, transparent);
90
+ padding: 0.1em 0.35em;
91
+ border-radius: 4px;
92
+ }
93
+
94
+ .note {
95
+ margin-top: 0.75rem;
96
+ font-size: 0.85rem;
97
+ color: var(--muted);
98
+ }
99
+ </style>
@@ -0,0 +1,88 @@
1
+ <script setup lang="ts">
2
+ import { UiCard } from '@meddleware/ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="feature-page">
7
+ <h1>🗄 Walrus</h1>
8
+
9
+ <UiCard class="section">
10
+ <h2>Overview</h2>
11
+ <p>
12
+ Walrus is a decentralised blob storage network built on Sui. The Meddleware Walrus app
13
+ lets you upload arbitrary files, manage your owned blobs, and extend their storage lifetime
14
+ — all from your browser wallet. Access is controlled by an on-chain NFT gate: the relay tip
15
+ is paid only after gate verification, keeping the relay open to legitimate holders while
16
+ preventing spam.
17
+ </p>
18
+ </UiCard>
19
+
20
+ <UiCard class="section">
21
+ <h2>Launch</h2>
22
+ <p>Use the hosted Meddleware Walrus app — no installation required.</p>
23
+ <a
24
+ href="https://sui-walrus.meddleware.co.uk"
25
+ target="_blank"
26
+ rel="noopener"
27
+ class="launch-btn"
28
+ >
29
+ Open Walrus →
30
+ </a>
31
+ </UiCard>
32
+
33
+ <UiCard class="section section--secondary">
34
+ <h2>White-label</h2>
35
+ <p>
36
+ Run your own branded Walrus upload experience. The <code>walrus-ui</code> Docker image
37
+ accepts VITE build args baked at build time — set your relay URL, network, and access
38
+ gate IDs, then deploy the image behind your own subdomain.
39
+ </p>
40
+ <p>
41
+ You will also need your own NFT gate (deployed via Access Gate) and a running relay
42
+ Worker (nft-gate Cloudflare Worker pointing at a Walrus upload relay origin). The
43
+ commission enforcement (20 bps) is hard-coded in the
44
+ <code>@meddleware/walrus-relay</code> library constants and applies to all relays,
45
+ regardless of who operates them.
46
+ </p>
47
+ <p class="note">
48
+ Detailed deployment instructions will be available at <code>dev.meddleware.co.uk</code>.
49
+ </p>
50
+ </UiCard>
51
+ </div>
52
+ </template>
53
+
54
+ <style scoped>
55
+ .feature-page { max-width: 760px; }
56
+ h1 { margin-top: 0; }
57
+
58
+ .section { margin-bottom: 1.25rem; }
59
+ .section h2 { margin-top: 0; }
60
+
61
+ .section--secondary { opacity: 0.9; }
62
+ .section--secondary h2 { font-size: 1rem; }
63
+
64
+ .launch-btn {
65
+ display: inline-block;
66
+ margin-top: 0.25rem;
67
+ padding: 0.55rem 1.2rem;
68
+ border-radius: var(--mw-radius, 10px);
69
+ background: var(--accent);
70
+ color: #fff;
71
+ text-decoration: none;
72
+ font-weight: 600;
73
+ }
74
+ .launch-btn:hover { opacity: 0.88; }
75
+
76
+ code {
77
+ font-size: 0.85em;
78
+ background: color-mix(in srgb, currentColor 10%, transparent);
79
+ padding: 0.1em 0.35em;
80
+ border-radius: 4px;
81
+ }
82
+
83
+ .note {
84
+ margin-top: 0.75rem;
85
+ font-size: 0.85rem;
86
+ color: var(--muted);
87
+ }
88
+ </style>
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "verbatimModuleSyntax": true,
13
+ "jsx": "preserve",
14
+ "types": ["node"],
15
+ "noEmit": true
16
+ },
17
+ "include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.d.ts", "vite.config.ts"]
18
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ // @meddleware/* resolve from node_modules (published packages — no monorepo aliases).
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ })