fix(ui): improve dashboard responsiveness and layout

Adjust grid gaps, padding, and font sizes for better mobile and desktop display; add responsive classes and truncate text for improved usability.
This commit is contained in:
jgor20
2026-01-11 12:02:31 +00:00
parent f9dd71f411
commit aafa636ee5

View File

@@ -47,107 +47,109 @@
<!-- Actual Content (首次加载完成后显示) -->
<div x-show="!$store.data.initialLoad" class="space-y-6">
<!-- Stats Grid -->
<div class="grid grid-cols-2 sm:grid-cols-5 gap-3">
<div class="grid grid-cols-2 sm:grid-cols-5 gap-2 lg:gap-3">
<div
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-6 hover:border-cyan-500/30 hover:bg-cyan-500/5 transition-all duration-300 group relative cursor-pointer"
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-3 lg:p-4 hover:border-cyan-500/30 hover:bg-cyan-500/5 transition-all duration-300 group relative cursor-pointer min-w-0"
@click="$store.global.activeTab = 'accounts'"
:title="$store.global.t('clickToViewAllAccounts')">
<!-- Icon 移到右上角,缩小并变灰 -->
<!-- Icon -->
<div class="absolute top-3 right-3 text-gray-700/40 group-hover:text-cyan-400/70 transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-5 h-5 stroke-current">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-4 h-4 sm:w-5 sm:h-5 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0z">
</path>
</svg>
</div>
<!-- 数字放大为主角 -->
<div class="stat-value text-white font-mono text-4xl font-bold mb-1" x-text="stats.total"></div>
<div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate"
<!-- Value -->
<div class="stat-value text-white font-mono text-2xl lg:text-3xl font-bold mb-1 truncate" x-text="stats.total"></div>
<!-- Title -->
<div class="stat-title text-gray-500 font-mono text-[10px] uppercase tracking-wider truncate"
x-text="$store.global.t('totalAccounts')"></div>
<!-- Desc -->
<div class="stat-desc text-cyan-400/60 text-[10px] truncate flex items-center gap-1">
<span x-text="$store.global.t('linkedAccounts')"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<span x-text="$store.global.t('linkedAccounts')" class="truncate"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
<!-- Subscription Tier Distribution -->
<div class="flex items-center gap-2 mt-2 text-[10px] font-mono" x-show="stats.subscription">
<!-- Tiers -->
<div class="flex items-center gap-1 mt-2 text-[10px] font-mono flex-wrap" x-show="stats.subscription">
<template x-if="stats.subscription?.ultra > 0">
<span class="px-1.5 py-0.5 rounded bg-yellow-500/10 text-yellow-400 border border-yellow-500/30">
<span x-text="stats.subscription.ultra"></span> Ultra
<span x-text="stats.subscription.ultra"></span> U
</span>
</template>
<template x-if="stats.subscription?.pro > 0">
<span class="px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-400 border border-blue-500/30">
<span x-text="stats.subscription.pro"></span> Pro
<span x-text="stats.subscription.pro"></span> P
</span>
</template>
<template x-if="stats.subscription?.free > 0">
<span class="px-1.5 py-0.5 rounded bg-gray-500/10 text-gray-400 border border-gray-500/30">
<span x-text="stats.subscription.free"></span> Free
<span x-text="stats.subscription.free"></span> F
</span>
</template>
</div>
</div>
<div
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-6 hover:border-green-500/30 hover:bg-green-500/5 transition-all duration-300 group relative cursor-pointer"
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-3 lg:p-4 hover:border-green-500/30 hover:bg-green-500/5 transition-all duration-300 group relative cursor-pointer min-w-0"
@click="$store.global.activeTab = 'models'"
:title="$store.global.t('clickToViewModels')">
<div class="absolute top-3 right-3 text-gray-700/40 group-hover:text-green-400/70 transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-5 h-5 stroke-current">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-4 h-4 sm:w-5 sm:h-5 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div class="stat-value text-white font-mono text-4xl font-bold mb-1" x-text="stats.active"></div>
<div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate"
<div class="stat-value text-white font-mono text-2xl lg:text-3xl font-bold mb-1 truncate" x-text="stats.active"></div>
<div class="stat-title text-gray-500 font-mono text-[10px] uppercase tracking-wider truncate"
x-text="$store.global.t('active')"></div>
<div class="stat-desc text-green-400/60 text-[10px] truncate flex items-center gap-1">
<span x-text="$store.global.t('operational')"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<span x-text="$store.global.t('operational')" class="truncate"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
</div>
<div
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-6 hover:border-red-500/30 hover:bg-red-500/5 transition-all duration-300 group relative cursor-pointer"
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-3 lg:p-4 hover:border-red-500/30 hover:bg-red-500/5 transition-all duration-300 group relative cursor-pointer min-w-0"
@click="$store.global.activeTab = 'accounts'"
:title="$store.global.t('clickToViewLimitedAccounts')">
<div class="absolute top-3 right-3 text-gray-700/40 group-hover:text-red-500/70 transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-5 h-5 stroke-current">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-4 h-4 sm:w-5 sm:h-5 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div class="stat-value text-white font-mono text-4xl font-bold mb-1" x-text="stats.limited"></div>
<div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate"
<div class="stat-value text-white font-mono text-2xl lg:text-3xl font-bold mb-1 truncate" x-text="stats.limited"></div>
<div class="stat-title text-gray-500 font-mono text-[10px] uppercase tracking-wider truncate"
x-text="$store.global.t('rateLimited')"></div>
<div class="stat-desc text-red-500/60 text-[10px] truncate flex items-center gap-1">
<span x-text="$store.global.t('cooldown')"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<span x-text="$store.global.t('cooldown')" class="truncate"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
</div>
<div
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-6 hover:border-orange-500/30 hover:bg-orange-500/5 transition-all duration-300 group relative cursor-pointer"
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-3 lg:p-4 hover:border-orange-500/30 hover:bg-orange-500/5 transition-all duration-300 group relative cursor-pointer min-w-0"
@click="$store.global.activeTab = 'models'"
:title="$store.global.t('clickToViewModels')">
<div class="absolute top-3 right-3 text-gray-700/40 group-hover:text-orange-500/70 transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-5 h-5 stroke-current">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="w-4 h-4 sm:w-5 sm:h-5 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path>
</svg>
</div>
<div class="stat-value text-white font-mono text-4xl font-bold mb-1" x-text="stats.modelUsage ? stats.modelUsage.limited : 0"></div>
<div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate"
<div class="stat-value text-white font-mono text-2xl lg:text-3xl font-bold mb-1 truncate" x-text="stats.modelUsage ? stats.modelUsage.limited : 0"></div>
<div class="stat-title text-gray-500 font-mono text-[10px] lg:text-xs uppercase tracking-wider truncate"
x-text="$store.global.t('quotasDepletedTitle')"></div>
<div class="stat-desc text-orange-500/60 text-[10px] truncate flex items-center gap-1">
<span x-text="$store.global.t('outOfTracked', {total: stats.modelUsage ? stats.modelUsage.total : 0})"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<span x-text="$store.global.t('outOfTracked', {total: stats.modelUsage ? stats.modelUsage.total : 0})" class="truncate"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
@@ -155,9 +157,9 @@
<!-- Global Quota Chart -->
<div
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-6 h-full flex items-center justify-between gap-3 overflow-hidden relative group hover:border-space-border/60 transition-colors col-span-2 sm:col-span-1">
class="stat bg-space-900/40 border border-space-border/30 rounded-xl p-3 lg:p-4 h-full flex flex-row sm:flex-col xl:flex-row items-center sm:items-start xl:items-center justify-between gap-3 overflow-hidden relative group hover:border-space-border/60 transition-colors col-span-2 sm:col-span-1 min-w-0">
<!-- Chart Container -->
<div class="h-14 w-14 lg:h-16 lg:w-16 relative flex-shrink-0">
<div class="h-14 w-14 lg:h-16 lg:w-16 relative flex-shrink-0 self-center sm:self-auto xl:self-center">
<canvas id="quotaChart"></canvas>
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">
<div class="text-[10px] font-bold text-white font-mono" x-text="stats.overallHealth + '%'">%</div>
@@ -165,21 +167,21 @@
</div>
<!-- Legend / Info -->
<div class="flex flex-col justify-center gap-2 flex-grow min-w-0">
<div class="flex flex-col justify-center gap-1 flex-grow min-w-0 w-full">
<div class="flex items-center justify-between">
<span class="text-[10px] text-gray-500 uppercase tracking-wider font-mono truncate"
x-text="$store.global.t('globalQuota')">Global Quota</span>
</div>
<!-- Custom Legend -->
<div class="space-y-1">
<div class="space-y-0.5">
<div class="flex items-center justify-between text-[10px] text-gray-400 cursor-pointer hover:text-neon-purple transition-colors group/legend"
@click="$store.global.activeTab = 'models'; $nextTick(() => { $store.data.filters.family = 'claude'; $store.data.computeQuotaRows(); })"
:title="$store.global.t('clickToFilterClaude')">
<div class="flex items-center gap-1.5 truncate">
<div class="w-1.5 h-1.5 rounded-full bg-neon-purple flex-shrink-0"></div>
<span class="truncate" x-text="$store.global.t('familyClaude')">Claude</span>
<svg class="w-2.5 h-2.5 opacity-0 group-hover/legend:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg class="w-2.5 h-2.5 opacity-0 group-hover/legend:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
@@ -190,7 +192,7 @@
<div class="flex items-center gap-1.5 truncate">
<div class="w-1.5 h-1.5 rounded-full bg-neon-green flex-shrink-0"></div>
<span class="truncate" x-text="$store.global.t('familyGemini')">Gemini</span>
<svg class="w-2.5 h-2.5 opacity-0 group-hover/legend:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg class="w-2.5 h-2.5 opacity-0 group-hover/legend:opacity-100 transition-opacity flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
@@ -199,7 +201,6 @@
</div>
</div>
</div>
<!-- Usage Trend Chart -->
<div class="view-card">
<!-- Header with Stats and Filter -->