fix: replace path-option-card with glass-card in Settings.vue
Also fix TypeScript errors in test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
98b2c098aa
commit
55a12e9bec
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#### Sprint 2: Fix Broken UI (Week 3-4)
|
#### Sprint 2: Fix Broken UI (Week 3-4)
|
||||||
|
|
||||||
- [ ] **UI-01** — Fix Settings.vue: replace .path-option-card with .glass-card. In `neode-ui/src/views/Settings.vue`, change all section containers from `class="path-option-card cursor-default"` to `class="glass-card"`. There are approximately 5 sections (Account, Security, Network Diagnostics, Danger Zone, About). Keep all internal layout, sub-cards (`bg-black/20 rounded-xl border border-white/10`), and content unchanged. Only the outer container class changes. **Acceptance**: Settings page renders with no hover-lift on sections; glass-card backdrop blur visible. Deploy and verify at http://192.168.1.228/dashboard/settings.
|
- [x] **UI-01** — Fix Settings.vue: replace .path-option-card with .glass-card. In `neode-ui/src/views/Settings.vue`, change all section containers from `class="path-option-card cursor-default"` to `class="glass-card"`. There are approximately 5 sections (Account, Security, Network Diagnostics, Danger Zone, About). Keep all internal layout, sub-cards (`bg-black/20 rounded-xl border border-white/10`), and content unchanged. Only the outer container class changes. **Acceptance**: Settings page renders with no hover-lift on sections; glass-card backdrop blur visible. Deploy and verify at http://192.168.1.228/dashboard/settings.
|
||||||
|
|
||||||
- [ ] **UI-02** — Fix Web5.vue top bar: use proper glass sub-card pattern. In `neode-ui/src/views/Web5.vue` lines 10-119, the 5 quick-action cards inside the `.glass-card` container use `bg-white/5 rounded-lg`. This is the correct pattern for info sub-cards inside a glass container per CLAUDE.md CSS hierarchy (`bg-white/5` = "Simple read-only info rows"). However, verify alignment with the Server.vue quick-actions bar (lines 10-96) which uses the identical pattern. Confirm both pages are visually consistent. If Web5 cards lack `data-controller-container` and `tabindex="0"` attributes, add them for keyboard/gamepad navigation parity. **Acceptance**: Web5 and Server quick-action bars visually match. No animation changes. Deploy and verify.
|
- [ ] **UI-02** — Fix Web5.vue top bar: use proper glass sub-card pattern. In `neode-ui/src/views/Web5.vue` lines 10-119, the 5 quick-action cards inside the `.glass-card` container use `bg-white/5 rounded-lg`. This is the correct pattern for info sub-cards inside a glass container per CLAUDE.md CSS hierarchy (`bg-white/5` = "Simple read-only info rows"). However, verify alignment with the Server.vue quick-actions bar (lines 10-96) which uses the identical pattern. Confirm both pages are visually consistent. If Web5 cards lack `data-controller-container` and `tabindex="0"` attributes, add them for keyboard/gamepad navigation parity. **Acceptance**: Web5 and Server quick-action bars visually match. No animation changes. Deploy and verify.
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ describe('RPCClient', () => {
|
|||||||
|
|
||||||
expect(result).toEqual({ did: 'did:key:z123' })
|
expect(result).toEqual({ did: 'did:key:z123' })
|
||||||
expect(mockFetch).toHaveBeenCalledOnce()
|
expect(mockFetch).toHaveBeenCalledOnce()
|
||||||
const [url, init] = mockFetch.mock.calls[0]
|
const [url, init] = mockFetch.mock.calls[0]!
|
||||||
expect(url).toBe('/rpc/v1')
|
expect(url).toBe('/rpc/v1')
|
||||||
expect(init.method).toBe('POST')
|
expect(init.method).toBe('POST')
|
||||||
expect(init.credentials).toBe('include')
|
expect(init.credentials).toBe('include')
|
||||||
@ -61,7 +61,7 @@ describe('RPCClient', () => {
|
|||||||
|
|
||||||
await rpcClient.call({ method: 'test', params: {} })
|
await rpcClient.call({ method: 'test', params: {} })
|
||||||
|
|
||||||
const [, init] = mockFetch.mock.calls[0]
|
const [, init] = mockFetch.mock.calls[0]!
|
||||||
expect(init.credentials).toBe('include')
|
expect(init.credentials).toBe('include')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ describe('RPCClient', () => {
|
|||||||
|
|
||||||
await rpcClient.call({ method: 'test' })
|
await rpcClient.call({ method: 'test' })
|
||||||
|
|
||||||
const body = JSON.parse(mockFetch.mock.calls[0][1].body)
|
const body = JSON.parse(mockFetch.mock.calls[0]![1].body)
|
||||||
expect(body.params).toEqual({})
|
expect(body.params).toEqual({})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ describe('RPCClient', () => {
|
|||||||
|
|
||||||
await rpcClient.call({ method: 'test', timeout: 5000 })
|
await rpcClient.call({ method: 'test', timeout: 5000 })
|
||||||
|
|
||||||
const [, init] = mockFetch.mock.calls[0]
|
const [, init] = mockFetch.mock.calls[0]!
|
||||||
expect(init.signal).toBeInstanceOf(AbortSignal)
|
expect(init.signal).toBeInstanceOf(AbortSignal)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||||
import { createRouter, createWebHistory, type RouteLocationNormalized } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { setActivePinia, createPinia } from 'pinia'
|
import { setActivePinia, createPinia } from 'pinia'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
|||||||
@ -22,9 +22,9 @@ import { containerClient } from '@/api/container-client'
|
|||||||
const mockedClient = vi.mocked(containerClient)
|
const mockedClient = vi.mocked(containerClient)
|
||||||
|
|
||||||
const mockContainers = [
|
const mockContainers = [
|
||||||
{ name: 'bitcoin-knots', state: 'running', status: 'Up 2 hours', image: 'bitcoinknots:29', lan_address: 'http://localhost:8332' },
|
{ id: '1', name: 'bitcoin-knots', state: 'running' as const, status: 'Up 2 hours', image: 'bitcoinknots:29', created: '2026-01-01', ports: ['8332'], lan_address: 'http://localhost:8332' },
|
||||||
{ name: 'lnd', state: 'stopped', status: 'Exited (0)', image: 'lnd:v0.18.4', lan_address: undefined },
|
{ id: '2', name: 'lnd', state: 'stopped' as const, status: 'Exited (0)', image: 'lnd:v0.18.4', created: '2026-01-01', ports: ['9735'], lan_address: undefined },
|
||||||
{ name: 'mempool', state: 'running', status: 'Up 1 hour', image: 'mempool:latest', lan_address: 'http://localhost:8080' },
|
{ id: '3', name: 'mempool', state: 'running' as const, status: 'Up 1 hour', image: 'mempool:latest', created: '2026-01-01', ports: ['8080'], lan_address: 'http://localhost:8080' },
|
||||||
]
|
]
|
||||||
|
|
||||||
describe('useContainerStore', () => {
|
describe('useContainerStore', () => {
|
||||||
@ -71,7 +71,7 @@ describe('useContainerStore', () => {
|
|||||||
await store.fetchContainers()
|
await store.fetchContainers()
|
||||||
|
|
||||||
expect(store.stoppedContainers).toHaveLength(1)
|
expect(store.stoppedContainers).toHaveLength(1)
|
||||||
expect(store.stoppedContainers[0].name).toBe('lnd')
|
expect(store.stoppedContainers[0]!.name).toBe('lnd')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('startContainer calls client and refreshes', async () => {
|
it('startContainer calls client and refreshes', async () => {
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Account Section -->
|
<!-- Account Section -->
|
||||||
<div class="path-option-card cursor-default px-6 py-6 mb-6">
|
<div class="glass-card px-6 py-6 mb-6">
|
||||||
<h2 class="text-xl font-semibold text-white/96 mb-6">Account</h2>
|
<h2 class="text-xl font-semibold text-white/96 mb-6">Account</h2>
|
||||||
|
|
||||||
<!-- Info Grid -->
|
<!-- Info Grid -->
|
||||||
@ -385,7 +385,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Interface Mode Section -->
|
<!-- Interface Mode Section -->
|
||||||
<div class="path-option-card cursor-default px-6 py-6 mb-6">
|
<div class="glass-card px-6 py-6 mb-6">
|
||||||
<h2 class="text-xl font-semibold text-white/96 mb-2">Interface Mode</h2>
|
<h2 class="text-xl font-semibold text-white/96 mb-2">Interface Mode</h2>
|
||||||
<p class="text-sm text-white/60 mb-6">Choose how you want to interact with your node.</p>
|
<p class="text-sm text-white/60 mb-6">Choose how you want to interact with your node.</p>
|
||||||
|
|
||||||
@ -416,7 +416,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Claude Authentication Section -->
|
<!-- Claude Authentication Section -->
|
||||||
<div class="path-option-card cursor-default px-6 py-6 mb-6">
|
<div class="glass-card px-6 py-6 mb-6">
|
||||||
<h2 class="text-xl font-semibold text-white/96 mb-2">Claude Authentication</h2>
|
<h2 class="text-xl font-semibold text-white/96 mb-2">Claude Authentication</h2>
|
||||||
<p class="text-sm text-white/60 mb-6">Connect your Claude Max account to enable AI chat features.</p>
|
<p class="text-sm text-white/60 mb-6">Connect your Claude Max account to enable AI chat features.</p>
|
||||||
|
|
||||||
@ -475,7 +475,7 @@
|
|||||||
</Teleport>
|
</Teleport>
|
||||||
|
|
||||||
<!-- AI Data Access Section -->
|
<!-- AI Data Access Section -->
|
||||||
<div class="path-option-card cursor-default px-6 py-6 mb-6">
|
<div class="glass-card px-6 py-6 mb-6">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<h2 class="text-xl font-semibold text-white/96">AI Data Access</h2>
|
<h2 class="text-xl font-semibold text-white/96">AI Data Access</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -543,7 +543,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Network & Connectivity Section -->
|
<!-- Network & Connectivity Section -->
|
||||||
<div class="path-option-card cursor-default px-6 py-6 mb-6">
|
<div class="glass-card px-6 py-6 mb-6">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h2 class="text-xl font-semibold text-white/96">Network</h2>
|
<h2 class="text-xl font-semibold text-white/96">Network</h2>
|
||||||
<p class="text-sm text-white/60 mt-1">Network connectivity, UPnP, and diagnostics</p>
|
<p class="text-sm text-white/60 mt-1">Network connectivity, UPnP, and diagnostics</p>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user