mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-06-16 22:06:52 +08:00
feat: 优化主题色
This commit is contained in:
@@ -36,7 +36,7 @@ export default defineConfig({
|
||||
ui({
|
||||
ui: {
|
||||
colors: {
|
||||
primary: 'green',
|
||||
primary: 'pink', // 使用自定义 pink 作为主色
|
||||
neutral: 'slate',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user