mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
feat(insight): add top-level insight navigation
This commit is contained in:
1 parent
618af4b5b9
commit
38206716b7
15 files changed
+165
-15
No files matched your search
@@ -50,6 +50,9 @@ const showContactsEntry = computed(() =>
|
||||
})
|
||||
)
|
||||
|
||||
// 是否在洞察页
|
||||
const isInsightPage = computed(() => route.path === '/insight')
|
||||
|
||||
// 重命名相关状态
|
||||
const showRenameModal = ref(false)
|
||||
const renameTarget = ref<AnalysisSession | null>(null)
|
||||
@@ -462,21 +465,32 @@ function getAvatarColorClass(session: AnalysisSession, isActive: boolean) {
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<!-- 新建分析 -->
|
||||
<SidebarButton
|
||||
icon="i-heroicons-plus"
|
||||
:title="t('layout.newAnalysis')"
|
||||
:active="isHomePage"
|
||||
@click="handleImport"
|
||||
/>
|
||||
<SidebarButton
|
||||
v-if="showContactsEntry"
|
||||
icon="i-lucide-users"
|
||||
icon-class="scale-90"
|
||||
:title="t('layout.relationships')"
|
||||
:active="isPeoplePage"
|
||||
@click="openContacts"
|
||||
/>
|
||||
<div class="space-y-1">
|
||||
<!-- 新建分析 -->
|
||||
<SidebarButton
|
||||
icon="i-heroicons-plus"
|
||||
:title="t('layout.newAnalysis')"
|
||||
:active="isHomePage"
|
||||
@click="handleImport"
|
||||
/>
|
||||
|
||||
<SidebarButton
|
||||
v-if="showContactsEntry"
|
||||
icon="i-lucide-users"
|
||||
icon-class="scale-90"
|
||||
:title="t('layout.relationships')"
|
||||
:active="isPeoplePage"
|
||||
@click="openContacts"
|
||||
/>
|
||||
|
||||
<!-- 洞察 -->
|
||||
<SidebarButton
|
||||
icon="i-heroicons-presentation-chart-bar"
|
||||
:title="t('layout.insight')"
|
||||
:active="isInsightPage"
|
||||
@click="router.push('/insight')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Session List -->
|
||||
|
||||
@@ -13,6 +13,7 @@ import views from './views.json'
|
||||
import wordFilter from './wordFilter.json'
|
||||
import contacts from './contacts.json'
|
||||
import relationships from './relationships.json'
|
||||
import insight from './insight.json'
|
||||
|
||||
export default {
|
||||
common,
|
||||
@@ -30,4 +31,5 @@ export default {
|
||||
wordFilter,
|
||||
contacts,
|
||||
relationships,
|
||||
insight,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "Insights",
|
||||
"placeholder": "Global insights are coming soon, stay tuned",
|
||||
"tabs": {
|
||||
"overview": "Overview",
|
||||
"trends": "Trends",
|
||||
"ranking": "Ranking"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
"newAnalysis": "New Analysis",
|
||||
"contacts": "Contacts",
|
||||
"relationships": "Relationships",
|
||||
"insight": "Insights",
|
||||
"tools": "Tools",
|
||||
"chatHistory": "Chat History",
|
||||
"manage": "Manage",
|
||||
"noRecords": "No records",
|
||||
"searchPlaceholder": "Search conversation name",
|
||||
|
||||
@@ -13,6 +13,7 @@ import views from './views.json'
|
||||
import wordFilter from './wordFilter.json'
|
||||
import contacts from './contacts.json'
|
||||
import relationships from './relationships.json'
|
||||
import insight from './insight.json'
|
||||
|
||||
export default {
|
||||
common,
|
||||
@@ -30,4 +31,5 @@ export default {
|
||||
wordFilter,
|
||||
contacts,
|
||||
relationships,
|
||||
insight,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "インサイト",
|
||||
"placeholder": "グローバルインサイト機能は近日公開予定です",
|
||||
"tabs": {
|
||||
"overview": "概要",
|
||||
"trends": "トレンド",
|
||||
"ranking": "ランキング"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
"newAnalysis": "新しいチャットを分析",
|
||||
"contacts": "連絡先",
|
||||
"relationships": "関係",
|
||||
"insight": "インサイト",
|
||||
"tools": "ツール",
|
||||
"chatHistory": "チャット履歴",
|
||||
"manage": "管理",
|
||||
"noRecords": "記録がありません",
|
||||
"searchPlaceholder": "チャット名を検索",
|
||||
|
||||
@@ -13,6 +13,7 @@ import views from './views.json'
|
||||
import wordFilter from './wordFilter.json'
|
||||
import contacts from './contacts.json'
|
||||
import relationships from './relationships.json'
|
||||
import insight from './insight.json'
|
||||
|
||||
export default {
|
||||
common,
|
||||
@@ -30,4 +31,5 @@ export default {
|
||||
wordFilter,
|
||||
contacts,
|
||||
relationships,
|
||||
insight,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "洞察",
|
||||
"placeholder": "全局洞察功能正在建设中,敬请期待",
|
||||
"tabs": {
|
||||
"overview": "总览",
|
||||
"trends": "趋势",
|
||||
"ranking": "排行"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
"newAnalysis": "分析新对话",
|
||||
"contacts": "联系人",
|
||||
"relationships": "关系",
|
||||
"insight": "洞察",
|
||||
"tools": "实用工具",
|
||||
"chatHistory": "聊天对话",
|
||||
"manage": "管理",
|
||||
"noRecords": "暂无记录",
|
||||
"searchPlaceholder": "搜索对话名称",
|
||||
|
||||
@@ -13,6 +13,7 @@ import views from './views.json'
|
||||
import wordFilter from './wordFilter.json'
|
||||
import contacts from './contacts.json'
|
||||
import relationships from './relationships.json'
|
||||
import insight from './insight.json'
|
||||
|
||||
export default {
|
||||
common,
|
||||
@@ -30,4 +31,5 @@ export default {
|
||||
wordFilter,
|
||||
contacts,
|
||||
relationships,
|
||||
insight,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "洞察",
|
||||
"placeholder": "全域洞察功能正在建設中,敬請期待",
|
||||
"tabs": {
|
||||
"overview": "總覽",
|
||||
"trends": "趨勢",
|
||||
"ranking": "排行"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
"newAnalysis": "分析新對話",
|
||||
"contacts": "聯絡人",
|
||||
"relationships": "關係",
|
||||
"insight": "洞察",
|
||||
"tools": "實用工具",
|
||||
"chatHistory": "聊天紀錄",
|
||||
"manage": "管理",
|
||||
"noRecords": "暫無紀錄",
|
||||
"searchPlaceholder": "搜尋聊天名稱",
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import PageHeader from '@/components/layout/PageHeader.vue'
|
||||
import EmptyState from '@/components/UI/EmptyState.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const tabs = [
|
||||
{ id: 'overview', labelKey: 'insight.tabs.overview', icon: 'i-heroicons-chart-pie' },
|
||||
{ id: 'trends', labelKey: 'insight.tabs.trends', icon: 'i-heroicons-presentation-chart-line' },
|
||||
{ id: 'ranking', labelKey: 'insight.tabs.ranking', icon: 'i-heroicons-trophy' },
|
||||
]
|
||||
|
||||
const activeTab = ref('overview')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-full flex-col bg-white dark:bg-gray-900" style="padding-top: var(--titlebar-area-height)">
|
||||
<PageHeader
|
||||
:title="t('insight.title')"
|
||||
icon="i-heroicons-presentation-chart-bar"
|
||||
icon-class="bg-pink-600 text-white dark:bg-pink-500 dark:text-white"
|
||||
size="compact"
|
||||
>
|
||||
<!-- Tab 栏 -->
|
||||
<div class="mt-3 flex items-center gap-0.5 overflow-x-auto scrollbar-hide">
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
:key="tab.id"
|
||||
class="flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-sm font-medium transition-all"
|
||||
:class="[
|
||||
activeTab === tab.id
|
||||
? 'bg-pink-500 text-white 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"
|
||||
>
|
||||
<UIcon :name="tab.icon" class="h-4 w-4" />
|
||||
<span class="whitespace-nowrap">{{ t(tab.labelKey) }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</PageHeader>
|
||||
|
||||
<!-- Tab 内容区 -->
|
||||
<div class="relative flex-1 overflow-y-auto">
|
||||
<div class="h-full">
|
||||
<Transition name="tab-slide" mode="out-in">
|
||||
<div :key="activeTab" class="flex h-full items-center justify-center">
|
||||
<EmptyState :text="t('insight.placeholder')" icon="✨" padding="lg" />
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.tab-slide-enter-active,
|
||||
.tab-slide-leave-active {
|
||||
transition:
|
||||
opacity 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.tab-slide-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
.tab-slide-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
</style>
|
||||
@@ -27,6 +27,11 @@ export const appRoutes: RouteRecordRaw[] = [
|
||||
name: 'private-chat',
|
||||
component: () => import('@/pages/private-chat/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/insight',
|
||||
name: 'insight',
|
||||
component: () => import('@/pages/insight/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/people',
|
||||
component: () => import('@/pages/people/index.vue'),
|
||||
|
||||
Reference in new issue
Block a user