feat: 优化主题色

This commit is contained in:
digua
2025-11-28 00:15:20 +08:00
parent b5e0ce9ea9
commit 035db60645
11 changed files with 54 additions and 46 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ export default defineConfig({
ui({
ui: {
colors: {
primary: 'green',
primary: 'pink', // 使用自定义 pink 作为主色
neutral: 'slate',
},
},
+15 -6
View File
@@ -1,8 +1,17 @@
@import "tailwindcss";
@import "@nuxt/ui";
@import 'tailwindcss';
@import '@nuxt/ui';
/* 配置主题颜色 */
:root {
--ui-primary: var(--color-green-500);
--ui-neutral: var(--color-slate-500);
/* 自定义主题颜色 - 使用 @theme static 定义色板 */
@theme static {
--color-pink-50: #fff1f2;
--color-pink-100: #fee5e8;
--color-pink-200: #fccfd5;
--color-pink-300: #faa7b4;
--color-pink-400: #f7758c;
--color-pink-500: #ee4567;
--color-pink-600: #de335e;
--color-pink-700: #b81844;
--color-pink-800: #a01d42;
--color-pink-900: #84173b;
--color-pink-950: #4a071c;
}
+7 -6
View File
@@ -148,7 +148,7 @@ onMounted(loadData)
<!-- Loading State -->
<div v-if="isLoading && !session" class="flex h-full items-center justify-center">
<div class="text-center">
<UIcon name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-indigo-500" />
<UIcon name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-pink-500" />
<p class="mt-2 text-sm text-gray-500">加载分析数据...</p>
</div>
</div>
@@ -161,7 +161,7 @@ onMounted(loadData)
<!-- Session Info -->
<div class="flex items-center gap-3">
<div
class="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-500 to-purple-600"
class="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-pink-400 to-pink-600"
>
<UIcon name="i-heroicons-chat-bubble-left-right" class="h-5 w-5 text-white" />
</div>
@@ -188,14 +188,14 @@ onMounted(loadData)
</div>
<!-- Tabs -->
<div class="mt-4 flex gap-1">
<div class="mt-4 flex items-center gap-1">
<button
v-for="tab in tabs"
:key="tab.id"
class="flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-all"
:class="[
activeTab === tab.id
? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-300'
? 'bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-300'
: 'text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800',
]"
@click="activeTab = tab.id"
@@ -203,7 +203,8 @@ onMounted(loadData)
<UIcon :name="tab.icon" class="h-4 w-4" />
{{ tab.label }}
</button>
<UITabs v-model="selectedYear" :items="yearOptions" size="sm" />
<!-- 年份选择器靠右 -->
<UITabs v-model="selectedYear" :items="yearOptions" size="sm" class="ml-auto" />
</div>
</div>
@@ -215,7 +216,7 @@ onMounted(loadData)
class="absolute inset-0 z-10 flex items-center justify-center bg-gray-50/80 dark:bg-gray-950/80"
>
<div class="text-center">
<UIcon name="i-heroicons-arrow-path" class="h-6 w-6 animate-spin text-indigo-500" />
<UIcon name="i-heroicons-arrow-path" class="h-6 w-6 animate-spin text-pink-500" />
<p class="mt-2 text-sm text-gray-500">更新数据...</p>
</div>
</div>
+2 -2
View File
@@ -55,6 +55,7 @@ function confirmDelete(id: string, event: Event) {
}
async function handleDelete(id: string) {
console.log(2333)
await chatStore.deleteSession(id)
deleteConfirmId.value = null
}
@@ -152,8 +153,7 @@ function cancelDelete() {
<div class="p-3">
<p class="mb-3 text-sm">确定删除此分析记录</p>
<div class="flex justify-end gap-2">
<UButton size="xs" color="gray" variant="ghost" @click="cancelDelete">取消</UButton>
<UButton size="xs" color="red" @click="handleDelete(session.id)">删除</UButton>
<UButton size="xs" color="red" @click="handleDelete(session.id)">确定删除</UButton>
</div>
</div>
</template>
+13 -17
View File
@@ -122,18 +122,18 @@ function getProgressText(): string {
<!-- Hero Section -->
<div class="mb-12 text-center">
<div
class="mb-6 inline-flex items-center justify-center rounded-3xl bg-white p-4 shadow-lg shadow-purple-100 ring-1 ring-gray-100 dark:bg-gray-900 dark:shadow-purple-900/20 dark:ring-gray-800"
class="mb-6 inline-flex items-center justify-center rounded-3xl bg-white p-4 shadow-lg shadow-pink-100 ring-1 ring-gray-100 dark:bg-gray-900 dark:shadow-pink-900/20 dark:ring-gray-800"
:class="[isImporting ? '' : 'animate-bounce']"
>
<UIcon v-if="!isImporting" name="i-heroicons-sparkles" class="h-8 w-8 text-purple-500" />
<UIcon v-else name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-purple-500" />
<UIcon v-if="!isImporting" name="i-heroicons-sparkles" class="h-8 w-8 text-pink-500" />
<UIcon v-else name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-pink-500" />
</div>
<h1
class="mb-4 bg-linear-to-r from-purple-600 via-pink-500 to-orange-400 bg-clip-text text-5xl font-black tracking-tight text-transparent sm:text-6xl"
class="mb-4 bg-linear-to-r from-pink-600 via-pink-500 to-rose-400 bg-clip-text text-5xl font-black tracking-tight text-transparent sm:text-6xl"
>
ChatLab
</h1>
<p class="text-lg font-medium text-gray-500 dark:text-gray-400">获取你的聊天记录分析报告</p>
<p class="text-lg font-medium text-gray-500 dark:text-gray-400">你的AI聊天分析实验室</p>
</div>
<!-- Feature Cards -->
@@ -141,7 +141,7 @@ function getProgressText(): string {
<div
v-for="feature in features"
:key="feature.title"
class="group relative transform cursor-default rounded-2xl border border-gray-100 bg-white p-6 shadow-sm transition-all duration-300 hover:-translate-y-2 hover:shadow-xl hover:shadow-purple-500/10 dark:border-gray-800 dark:bg-gray-900"
class="group relative transform cursor-default rounded-2xl border border-gray-100 bg-white p-6 shadow-sm transition-all duration-300 hover:-translate-y-2 hover:shadow-xl hover:shadow-pink-500/10 dark:border-gray-800 dark:bg-gray-900"
:style="{ animationDelay: feature.delay }"
>
<div class="mb-4 text-4xl transition-transform duration-300 group-hover:scale-110">
@@ -156,11 +156,11 @@ function getProgressText(): string {
<div class="flex flex-col items-center space-y-6">
<!-- Import Drop Zone -->
<div
class="group relative flex w-full max-w-2xl cursor-pointer flex-col items-center justify-center rounded-2xl border-2 border-dashed border-purple-300 bg-white px-12 py-12 transition-all duration-300 hover:border-purple-400 hover:bg-purple-50/50 focus:outline-none focus:ring-4 focus:ring-purple-500/20 dark:border-purple-700 dark:bg-gray-900 dark:hover:border-purple-500 dark:hover:bg-purple-900/10"
class="group relative flex w-full max-w-2xl cursor-pointer flex-col items-center justify-center rounded-2xl border-2 border-dashed border-pink-300 bg-white px-12 py-12 transition-all duration-300 hover:border-pink-400 hover:bg-pink-50/50 focus:outline-none focus:ring-4 focus:ring-pink-500/20 dark:border-pink-700 dark:bg-gray-900 dark:hover:border-pink-500 dark:hover:bg-pink-900/10"
:class="{
'border-purple-500 bg-purple-50 dark:border-purple-400 dark:bg-purple-900/20': isDragOver && !isImporting,
'border-pink-500 bg-pink-50 dark:border-pink-400 dark:bg-pink-900/20': isDragOver && !isImporting,
'cursor-not-allowed opacity-70': isImporting,
'hover:scale-[1.02] hover:shadow-xl hover:shadow-purple-500/10': !isImporting,
'hover:scale-[1.02] hover:shadow-xl hover:shadow-pink-500/10': !isImporting,
}"
@click="!isImporting && handleImport()"
@dragover="handleDragOver"
@@ -169,19 +169,15 @@ function getProgressText(): string {
>
<!-- Icon -->
<div
class="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-linear-to-br from-purple-100 to-pink-100 transition-transform duration-300 dark:from-purple-900/30 dark:to-pink-900/30"
class="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-linear-to-br from-pink-100 to-rose-100 transition-transform duration-300 dark:from-pink-900/30 dark:to-rose-900/30"
:class="{ 'scale-110': isDragOver && !isImporting, 'animate-pulse': isImporting }"
>
<UIcon
v-if="!isImporting"
name="i-heroicons-arrow-up-tray"
class="h-8 w-8 text-purple-600 transition-transform group-hover:-translate-y-1 dark:text-purple-400"
/>
<UIcon
v-else
name="i-heroicons-arrow-path"
class="h-8 w-8 animate-spin text-purple-600 dark:text-purple-400"
class="h-8 w-8 text-pink-600 transition-transform group-hover:-translate-y-1 dark:text-pink-400"
/>
<UIcon v-else name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-pink-600 dark:text-pink-400" />
</div>
<!-- Text -->
@@ -190,7 +186,7 @@ function getProgressText(): string {
<!-- 导入中显示进度 -->
<p class="mb-4 text-lg font-semibold text-gray-900 dark:text-white">{{ getProgressText() }}</p>
<div class="mx-auto w-full max-w-md">
<UProgress :value="importProgress.progress" size="md" color="purple" />
<UProgress :value="importProgress.progress" size="md" color="pink" />
</div>
<p class="mt-3 text-sm text-gray-500 dark:text-gray-400">
{{ importProgress.message }}
+2 -2
View File
@@ -95,7 +95,7 @@ function getRankBadge(index: number): string {
<template>
<div class="space-y-6">
<!-- 群聊身份卡 -->
<div class="rounded-2xl bg-linear-to-br from-indigo-500 via-purple-500 to-pink-500 p-6 text-white shadow-lg">
<div class="rounded-2xl bg-linear-to-br from-pink-400 via-pink-500 to-pink-600 p-6 text-white shadow-lg">
<div class="flex items-start justify-between">
<div>
<h2 class="text-2xl font-bold">{{ session.name }}</h2>
@@ -211,7 +211,7 @@ function getRankBadge(index: number): string {
<span class="font-medium text-gray-900 dark:text-white">{{ member.name }}</span>
<span class="text-sm text-gray-500">{{ member.messageCount }}</span>
</div>
<ProgressBar :percentage="member.percentage" color="from-indigo-500 to-purple-500" />
<ProgressBar :percentage="member.percentage" color="from-pink-400 to-pink-600" />
</div>
</div>
</div>
+6 -6
View File
@@ -105,13 +105,13 @@ const avgDailyMessages = computed(() => {
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900">
<p class="text-xs font-medium text-gray-500 dark:text-gray-400">最活跃时段</p>
<p class="mt-1 text-2xl font-bold text-indigo-600 dark:text-indigo-400">{{ peakHour?.hour || 0 }}:00</p>
<p class="mt-1 text-2xl font-bold text-pink-600 dark:text-pink-400">{{ peakHour?.hour || 0 }}:00</p>
<p class="mt-1 text-xs text-gray-400">{{ peakHour?.messageCount || 0 }} 条消息</p>
</div>
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900">
<p class="text-xs font-medium text-gray-500 dark:text-gray-400">最活跃日期</p>
<p class="mt-1 text-2xl font-bold text-purple-600 dark:text-purple-400">
<p class="mt-1 text-2xl font-bold text-pink-600 dark:text-pink-400">
{{ peakDay ? dayjs(peakDay.date).format('MM/DD') : '-' }}
</p>
<p class="mt-1 text-xs text-gray-400">{{ peakDay?.messageCount || 0 }} 条消息</p>
@@ -153,28 +153,28 @@ const avgDailyMessages = computed(() => {
<div class="text-xs text-gray-500 dark:text-gray-400">凌晨 0-6点</div>
<div class="mt-1 text-lg font-semibold text-gray-900 dark:text-white">{{ lateNightRatio }}%</div>
<div class="mx-auto mt-2 h-1 w-full max-w-16 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800">
<div class="h-full rounded-full bg-indigo-300 transition-all" :style="{ width: `${lateNightRatio}%` }" />
<div class="h-full rounded-full bg-pink-300 transition-all" :style="{ width: `${lateNightRatio}%` }" />
</div>
</div>
<div class="text-center">
<div class="text-xs text-gray-500 dark:text-gray-400">上午 6-12点</div>
<div class="mt-1 text-lg font-semibold text-gray-900 dark:text-white">{{ morningRatio }}%</div>
<div class="mx-auto mt-2 h-1 w-full max-w-16 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800">
<div class="h-full rounded-full bg-indigo-400 transition-all" :style="{ width: `${morningRatio}%` }" />
<div class="h-full rounded-full bg-pink-400 transition-all" :style="{ width: `${morningRatio}%` }" />
</div>
</div>
<div class="text-center">
<div class="text-xs text-gray-500 dark:text-gray-400">下午 12-18点</div>
<div class="mt-1 text-lg font-semibold text-gray-900 dark:text-white">{{ afternoonRatio }}%</div>
<div class="mx-auto mt-2 h-1 w-full max-w-16 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800">
<div class="h-full rounded-full bg-indigo-500 transition-all" :style="{ width: `${afternoonRatio}%` }" />
<div class="h-full rounded-full bg-pink-500 transition-all" :style="{ width: `${afternoonRatio}%` }" />
</div>
</div>
<div class="text-center">
<div class="text-xs text-gray-500 dark:text-gray-400">晚上 18-24点</div>
<div class="mt-1 text-lg font-semibold text-gray-900 dark:text-white">{{ eveningRatio }}%</div>
<div class="mx-auto mt-2 h-1 w-full max-w-16 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800">
<div class="h-full rounded-full bg-indigo-600 transition-all" :style="{ width: `${eveningRatio}%` }" />
<div class="h-full rounded-full bg-pink-600 transition-all" :style="{ width: `${eveningRatio}%` }" />
</div>
</div>
</div>
+1 -1
View File
@@ -8,7 +8,7 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
color: 'from-indigo-500 to-purple-500',
color: 'from-pink-400 to-pink-600',
height: 8,
showLabel: false,
animated: true,
+4 -4
View File
@@ -47,11 +47,11 @@ function getBarColor(index: number): string {
'from-amber-400 to-orange-500',
'from-gray-300 to-gray-400',
'from-amber-600 to-amber-700',
'from-indigo-400 to-purple-500',
'from-pink-400 to-rose-500',
'from-pink-400 to-pink-600',
'from-pink-300 to-rose-500',
'from-cyan-400 to-blue-500',
'from-green-400 to-emerald-500',
'from-violet-400 to-purple-500',
'from-rose-400 to-pink-500',
]
return colors[index % colors.length]
}
@@ -75,7 +75,7 @@ function getBarColor(index: number): string {
<!-- 头像占位 -->
<div
v-if="showAvatar"
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-linear-to-br from-indigo-100 to-purple-100 text-sm font-medium text-indigo-600 dark:from-indigo-900/30 dark:to-purple-900/30 dark:text-indigo-400"
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-linear-to-br from-pink-100 to-rose-100 text-sm font-medium text-pink-600 dark:from-pink-900/30 dark:to-rose-900/30 dark:text-pink-400"
>
{{ member.name.slice(0, 1) }}
</div>
+2
View File
@@ -3,6 +3,7 @@ import App from './App.vue'
import { router } from './routes/'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import ui from '@nuxt/ui/vue-plugin'
import './assets/styles/main.css'
const app = createApp(App)
@@ -12,5 +13,6 @@ pinia.use(piniaPluginPersistedstate)
app.use(pinia)
app.use(router)
app.use(ui)
app.mount('#app')
+1 -1
View File
@@ -14,7 +14,7 @@ const { currentSessionId, isInitialized } = storeToRefs(chatStore)
<template v-if="!isInitialized">
<div class="flex h-full w-full items-center justify-center">
<div class="text-center">
<UIcon name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-indigo-500" />
<UIcon name="i-heroicons-arrow-path" class="h-8 w-8 animate-spin text-pink-500" />
<p class="mt-2 text-sm text-gray-500">加载中...</p>
</div>
</div>