style(openwrt): adopt glass-card design system for contrast
Replace bg-white/5 card containers with glass-card (rgba(0,0,0,0.65) + backdrop-blur), match input styling to Login.vue, and use glass-button variants for actions. Fixes low contrast against the background image. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f054766a58
commit
f69fac627a
@ -151,43 +151,41 @@ onMounted(() => load())
|
||||
</div>
|
||||
|
||||
<!-- Connect form (shown when no router is configured) -->
|
||||
<div v-if="showConnectForm" class="rounded-xl border border-white/10 bg-white/5 p-5 mb-6">
|
||||
<div v-if="showConnectForm" class="glass-card p-6 mb-6">
|
||||
<h2 class="text-sm font-semibold text-white/80 mb-4">Connect to Router</h2>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-xs text-white/50 mb-1">Router IP</label>
|
||||
<label class="block text-xs text-white/40 mb-1">Router IP</label>
|
||||
<input
|
||||
v-model="host"
|
||||
type="text"
|
||||
placeholder="192.168.1.1"
|
||||
class="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-white/30 focus:outline-none focus:border-white/30"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/30 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="block text-xs text-white/50 mb-1">SSH User</label>
|
||||
<label class="block text-xs text-white/40 mb-1">SSH User</label>
|
||||
<input
|
||||
v-model="sshUser"
|
||||
type="text"
|
||||
class="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-white/50 mb-1">Password</label>
|
||||
<label class="block text-xs text-white/40 mb-1">Password</label>
|
||||
<input
|
||||
v-model="sshPassword"
|
||||
type="password"
|
||||
placeholder="(blank for none)"
|
||||
class="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-white/30 focus:outline-none focus:border-white/30"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/30 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
:disabled="connecting || !host.trim()"
|
||||
class="w-full py-2 rounded-lg text-sm font-medium transition-colors"
|
||||
:class="connecting || !host.trim()
|
||||
? 'bg-white/5 text-white/30 cursor-not-allowed'
|
||||
: 'bg-blue-600 hover:bg-blue-500 text-white'"
|
||||
class="glass-button w-full text-sm font-medium"
|
||||
:class="connecting || !host.trim() ? 'opacity-40 cursor-not-allowed' : 'glass-button-warning'"
|
||||
@click="connect"
|
||||
>
|
||||
{{ connecting ? 'Connecting…' : 'Connect' }}
|
||||
@ -198,7 +196,7 @@ onMounted(() => load())
|
||||
|
||||
<!-- Loading skeleton -->
|
||||
<template v-else-if="loading">
|
||||
<div v-for="i in 3" :key="i" class="rounded-xl border border-white/10 bg-white/5 p-5 mb-4 animate-pulse">
|
||||
<div v-for="i in 3" :key="i" class="glass-card p-6 mb-4 animate-pulse">
|
||||
<div class="h-4 bg-white/10 rounded w-1/3 mb-4"></div>
|
||||
<div class="space-y-2">
|
||||
<div class="h-3 bg-white/10 rounded w-2/3"></div>
|
||||
@ -208,16 +206,16 @@ onMounted(() => load())
|
||||
</template>
|
||||
|
||||
<!-- Error state -->
|
||||
<div v-else-if="error" class="rounded-xl border border-red-500/30 bg-red-500/10 p-5 mb-4">
|
||||
<div v-else-if="error" class="glass-card p-6 mb-4">
|
||||
<p class="text-sm text-red-300">{{ error }}</p>
|
||||
<button class="mt-3 text-xs text-white/50 hover:text-white underline" @click="load()">Retry</button>
|
||||
<button class="mt-3 text-xs text-white/50 hover:text-white transition-colors underline" @click="load()">Retry</button>
|
||||
</div>
|
||||
|
||||
<!-- Status panels -->
|
||||
<template v-else-if="status">
|
||||
|
||||
<!-- System info -->
|
||||
<div class="rounded-xl border border-white/10 bg-white/5 p-5 mb-4">
|
||||
<div class="glass-card p-6 mb-4">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-sm font-semibold text-white/80">System</h2>
|
||||
<span class="flex items-center gap-1.5 text-xs text-green-400">
|
||||
@ -236,15 +234,15 @@ onMounted(() => load())
|
||||
</div>
|
||||
<div v-if="openwrtVersion">
|
||||
<dt class="text-xs text-white/40 mb-0.5">OpenWrt</dt>
|
||||
<dd class="text-white/80">{{ openwrtVersion }}</dd>
|
||||
<dd class="text-white/70">{{ openwrtVersion }}</dd>
|
||||
</div>
|
||||
<div v-if="boardName">
|
||||
<dt class="text-xs text-white/40 mb-0.5">Board</dt>
|
||||
<dd class="text-white/80">{{ boardName }}</dd>
|
||||
<dd class="text-white/70">{{ boardName }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-xs text-white/40 mb-0.5">Uptime</dt>
|
||||
<dd class="text-white/80">{{ formatUptime(status.uptime_secs) }}</dd>
|
||||
<dd class="text-white/70">{{ formatUptime(status.uptime_secs) }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<button
|
||||
@ -256,7 +254,7 @@ onMounted(() => load())
|
||||
</div>
|
||||
|
||||
<!-- TollGate -->
|
||||
<div class="rounded-xl border border-white/10 bg-white/5 p-5 mb-4">
|
||||
<div class="glass-card p-6 mb-4">
|
||||
<h2 class="text-sm font-semibold text-white/80 mb-4">TollGate</h2>
|
||||
|
||||
<div v-if="!status.tollgate.installed">
|
||||
@ -266,16 +264,14 @@ onMounted(() => load())
|
||||
</div>
|
||||
<button
|
||||
:disabled="provisioning"
|
||||
class="w-full py-2 rounded-lg text-sm font-medium transition-colors"
|
||||
:class="provisioning
|
||||
? 'bg-white/5 text-white/30 cursor-not-allowed'
|
||||
: 'bg-blue-600 hover:bg-blue-500 text-white'"
|
||||
class="glass-button glass-button-success w-full text-sm font-medium"
|
||||
:class="provisioning ? 'opacity-40 cursor-not-allowed' : ''"
|
||||
@click="provisionTollgate"
|
||||
>
|
||||
{{ provisioning ? 'Installing TollGate… (may take a few minutes)' : 'Install TollGate' }}
|
||||
{{ provisioning ? 'Installing… this may take a few minutes' : 'Install TollGate' }}
|
||||
</button>
|
||||
<p v-if="provisionError" class="mt-2 text-xs text-red-400">{{ provisionError }}</p>
|
||||
<p v-if="provisionSuccess && !provisioning" class="mt-2 text-xs text-green-400">TollGate provisioned successfully.</p>
|
||||
<p v-if="provisionError" class="mt-3 text-xs text-red-400">{{ provisionError }}</p>
|
||||
<p v-if="provisionSuccess && !provisioning" class="mt-3 text-xs text-green-400">TollGate provisioned successfully.</p>
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
@ -298,31 +294,31 @@ onMounted(() => load())
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-xs text-white/40 mb-0.5">Metric</dt>
|
||||
<dd class="text-white/80 capitalize">{{ status.tollgate.metric }}</dd>
|
||||
<dd class="text-white/70 capitalize">{{ status.tollgate.metric }}</dd>
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
<dt class="text-xs text-white/40 mb-0.5">Mint URL</dt>
|
||||
<dd class="text-white/80 font-mono text-xs break-all">{{ status.tollgate.mint_url }}</dd>
|
||||
<dd class="text-white/70 font-mono text-xs break-all">{{ status.tollgate.mint_url }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- WiFi interfaces -->
|
||||
<div class="rounded-xl border border-white/10 bg-white/5 p-5">
|
||||
<div class="glass-card p-6">
|
||||
<h2 class="text-sm font-semibold text-white/80 mb-4">
|
||||
WiFi Interfaces
|
||||
<span class="ml-2 text-xs font-normal text-white/40">(AP mode)</span>
|
||||
</h2>
|
||||
|
||||
<div v-if="status.wifi_interfaces.length === 0" class="text-sm text-white/40">
|
||||
No AP interfaces found.
|
||||
<div v-if="status.wifi_interfaces.length === 0" class="text-sm text-white/50">
|
||||
No AP interfaces configured.
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="iface in status.wifi_interfaces"
|
||||
:key="iface.section"
|
||||
class="flex items-start justify-between py-3 border-b border-white/5 last:border-0"
|
||||
class="flex items-start justify-between py-3 border-b border-white/10 last:border-0"
|
||||
>
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-0.5">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user