@meddleware/access-gate-ui 0.1.0 → 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/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@meddleware/access-gate-ui",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Operator console for creating and managing on-chain Sui access gates — create gates, configure settings, airdrop NFTs, and freeze gates via a wallet-connected SPA.",
5
- "author": "MeddleWare <meddleware@proton.me>",
5
+ "author": "Meddleware <dev@meddleware.co.uk>",
6
6
  "license": "0BSD",
7
7
  "repository": {
8
8
  "type": "git",
@@ -26,9 +26,9 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@meddleware/design-tokens": "^0.1.0",
30
- "@meddleware/ui": "^0.1.0",
31
- "@meddleware/nft-gate-client": "^0.0.3",
29
+ "@meddleware/design-tokens": "^0.1.2",
30
+ "@meddleware/ui": "^0.1.6",
31
+ "@meddleware/nft-gate-client": "^0.0.5",
32
32
  "@mysten/sui": "~2.17.0",
33
33
  "@mysten/wallet-standard": "~0.19.9",
34
34
  "vue": "^3.5.40"
package/src/App.vue CHANGED
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { ref } from 'vue'
3
- import { UiButton, UiNotice } from '@meddleware/ui'
3
+ import { AppHeader, AppFooter, ColorModeControl, UiButton, UiNotice, useColorMode } from '@meddleware/ui'
4
4
  import type { OwnedGate } from '@meddleware/nft-gate-client'
5
5
  import { NETWORK } from './config.js'
6
6
  import { PACKAGE_ID, listMyGates } from './gates.js'
@@ -8,6 +8,9 @@ import { useWallet } from './wallet.js'
8
8
  import CreateGateForm from './components/CreateGateForm.vue'
9
9
  import GateList from './components/GateList.vue'
10
10
 
11
+ const isEmbedded = new URLSearchParams(window.location.search).has('embedded')
12
+ const { mode, set } = useColorMode('dark')
13
+
11
14
  type Tab = 'create' | 'gates'
12
15
  const activeTab = ref<Tab>('gates')
13
16
 
@@ -46,13 +49,12 @@ function onCreated(): void {
46
49
  </script>
47
50
 
48
51
  <template>
49
- <div class="page">
50
- <header class="head">
51
- <div>
52
- <h1>Access Gate Operator</h1>
53
- <p class="sub">Create and manage on-chain access gates on Sui ({{ NETWORK }}).</p>
54
- </div>
55
- <div class="wallet">
52
+ <div class="app" :class="{ 'app--embedded': isEmbedded }">
53
+ <AppHeader v-if="!isEmbedded" variant="dark">
54
+ <template #brand>
55
+ <span>Access Gate</span>
56
+ </template>
57
+ <template #actions>
56
58
  <template v-if="account">
57
59
  <span class="addr">{{ account.address.slice(0, 8) }}…{{ account.address.slice(-4) }}</span>
58
60
  <UiButton variant="ghost" @click="disconnect">Disconnect</UiButton>
@@ -62,81 +64,86 @@ function onCreated(): void {
62
64
  {{ wallets.length ? 'Connect wallet' : 'No wallet detected' }}
63
65
  </UiButton>
64
66
  </template>
65
- </div>
66
- </header>
67
-
68
- <UiNotice v-if="!deployed" type="error">
69
- The access_gate contract is not deployed on {{ NETWORK }}. Switch to a supported network.
70
- </UiNotice>
71
-
72
- <template v-else-if="account">
73
- <nav class="tabs" aria-label="Sections">
74
- <button type="button" class="tab" :class="{ active: activeTab === 'gates' }" @click="activeTab = 'gates'; reloadGates()">
75
- My gates
76
- </button>
77
- <button type="button" class="tab" :class="{ active: activeTab === 'create' }" @click="activeTab = 'create'">
78
- Create gate
79
- </button>
80
- </nav>
81
-
82
- <UiNotice v-if="loadError" type="error">{{ loadError }}</UiNotice>
83
-
84
- <section v-if="activeTab === 'gates'">
85
- <GateList :gates="gates" :loading="loadingGates" @changed="reloadGates" />
86
- </section>
87
- <section v-else>
88
- <CreateGateForm :address="account.address" @created="onCreated" />
89
- </section>
90
- </template>
91
-
92
- <UiNotice v-else type="info">
93
- Connect a Sui wallet to create and manage your access gates.
94
- </UiNotice>
95
-
96
- <footer class="foot">
97
- <p>© MeddleWare · <a href="https://sui.meddleware.co.uk">more SUI tools</a></p>
98
- </footer>
67
+ <ColorModeControl :model-value="mode" @update:model-value="set" />
68
+ </template>
69
+ </AppHeader>
70
+
71
+ <div class="page">
72
+ <p class="sub">Create and manage on-chain access gates on Sui ({{ NETWORK }}).</p>
73
+
74
+ <UiNotice v-if="!deployed" type="error">
75
+ The access_gate contract is not deployed on {{ NETWORK }}. Switch to a supported network.
76
+ </UiNotice>
77
+
78
+ <template v-else-if="account">
79
+ <nav class="tabs" aria-label="Sections">
80
+ <button type="button" class="tab" :class="{ active: activeTab === 'gates' }" @click="activeTab = 'gates'; reloadGates()">
81
+ My gates
82
+ </button>
83
+ <button type="button" class="tab" :class="{ active: activeTab === 'create' }" @click="activeTab = 'create'">
84
+ Create gate
85
+ </button>
86
+ </nav>
87
+
88
+ <UiNotice v-if="loadError" type="error">{{ loadError }}</UiNotice>
89
+
90
+ <section v-if="activeTab === 'gates'">
91
+ <GateList :gates="gates" :loading="loadingGates" @changed="reloadGates" />
92
+ </section>
93
+ <section v-else>
94
+ <CreateGateForm :address="account.address" @created="onCreated" />
95
+ </section>
96
+ </template>
97
+
98
+ <UiNotice v-else type="info">
99
+ Connect a Sui wallet to create and manage your access gates.
100
+ </UiNotice>
101
+ </div>
102
+
103
+ <AppFooter v-if="!isEmbedded" />
99
104
  </div>
100
105
  </template>
101
106
 
102
107
  <style scoped>
108
+ .app {
109
+ min-height: 100vh;
110
+ display: flex;
111
+ flex-direction: column;
112
+ }
113
+
114
+ .app--embedded {
115
+ min-height: 100%;
116
+ }
117
+
103
118
  .page {
104
119
  max-width: 720px;
105
120
  margin: 0 auto;
106
121
  padding: 2rem 1.25rem 4rem;
122
+ flex: 1;
107
123
  }
108
- .head {
109
- display: flex;
110
- justify-content: space-between;
111
- align-items: flex-start;
112
- gap: 1rem;
113
- flex-wrap: wrap;
114
- }
115
- .head h1 {
116
- margin: 0;
117
- font-size: 1.8rem;
118
- color: var(--text);
124
+
125
+ .app--embedded .page {
126
+ padding-top: 1rem;
127
+ padding-bottom: 1rem;
119
128
  }
129
+
120
130
  .sub {
121
131
  color: var(--muted);
122
- margin: 0.25rem 0 0;
123
- }
124
- .wallet {
125
- display: flex;
126
- align-items: center;
127
- gap: 0.75rem;
132
+ margin: 0.25rem 0 1.25rem;
128
133
  }
134
+
129
135
  .addr {
130
136
  font-family: monospace;
131
137
  font-size: 0.9rem;
132
- color: var(--text);
133
138
  }
139
+
134
140
  .tabs {
135
141
  display: flex;
136
142
  gap: 0.25rem;
137
- margin: 1.25rem 0 1rem;
143
+ margin: 0 0 1rem;
138
144
  border-bottom: 2px solid var(--border);
139
145
  }
146
+
140
147
  .tab {
141
148
  background: none;
142
149
  border: none;
@@ -147,14 +154,10 @@ function onCreated(): void {
147
154
  font-size: 0.95rem;
148
155
  color: var(--muted);
149
156
  }
157
+
150
158
  .tab.active {
151
- border-bottom-color: var(--mw-accent-500, var(--text));
159
+ border-bottom-color: var(--accent);
152
160
  color: var(--text);
153
161
  font-weight: 600;
154
162
  }
155
- .foot {
156
- margin-top: 3rem;
157
- font-size: 0.85rem;
158
- color: var(--muted);
159
- }
160
163
  </style>
@@ -43,6 +43,13 @@ function priceLabel(mist: bigint): string {
43
43
 
44
44
  <div class="actions">
45
45
  <UiButton variant="ghost" @click="open = !open">{{ open ? 'Hide' : 'Manage' }}</UiButton>
46
+ <a
47
+ class="seal-link"
48
+ :href="`https://sui-seal.meddleware.co.uk/?gate=${gate.gateId}`"
49
+ target="_blank"
50
+ rel="noopener"
51
+ title="Seal-encrypt content that only this gate's pass-holders can unlock"
52
+ >🔒 Add unlockable content →</a>
46
53
  </div>
47
54
 
48
55
  <div v-if="open" class="manage">
@@ -97,6 +104,18 @@ function priceLabel(mist: bigint): string {
97
104
  }
98
105
  .actions {
99
106
  margin-top: 0.75rem;
107
+ display: flex;
108
+ align-items: center;
109
+ gap: 1rem;
110
+ flex-wrap: wrap;
111
+ }
112
+ .seal-link {
113
+ color: var(--accent, #c0503f);
114
+ text-decoration: none;
115
+ font-size: 0.85rem;
116
+ }
117
+ .seal-link:hover {
118
+ text-decoration: underline;
100
119
  }
101
120
  .manage {
102
121
  margin-top: 0.75rem;