refactor: tighten private analytics header

This commit is contained in:
aits2026
2026-03-10 12:24:42 +08:00
parent 6911132c95
commit 74e974177c
4 changed files with 43 additions and 40 deletions

View File

@@ -2,6 +2,8 @@
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
min-height: 28px;
padding: 4px 0;
background: transparent;
@@ -107,9 +109,28 @@
}
}
.chat-analysis-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
margin-left: auto;
flex-wrap: wrap;
}
@media (max-width: 768px) {
.chat-analysis-header {
align-items: flex-start;
flex-wrap: wrap;
}
.chat-analysis-breadcrumb {
flex-wrap: wrap;
row-gap: 4px;
}
.chat-analysis-actions {
width: 100%;
justify-content: flex-start;
}
}

View File

@@ -1,5 +1,5 @@
import { ChevronDown, ChevronLeft } from 'lucide-react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
import { useNavigate } from 'react-router-dom'
import './ChatAnalysisHeader.scss'
@@ -7,6 +7,7 @@ export type ChatAnalysisMode = 'private' | 'group'
interface ChatAnalysisHeaderProps {
currentMode: ChatAnalysisMode
actions?: ReactNode
}
const MODE_CONFIG: Record<ChatAnalysisMode, { label: string; path: string }> = {
@@ -20,7 +21,7 @@ const MODE_CONFIG: Record<ChatAnalysisMode, { label: string; path: string }> = {
}
}
function ChatAnalysisHeader({ currentMode }: ChatAnalysisHeaderProps) {
function ChatAnalysisHeader({ currentMode, actions }: ChatAnalysisHeaderProps) {
const navigate = useNavigate()
const currentLabel = MODE_CONFIG[currentMode].label
const [menuOpen, setMenuOpen] = useState(false)
@@ -95,6 +96,8 @@ function ChatAnalysisHeader({ currentMode }: ChatAnalysisHeaderProps) {
)}
</div>
</div>
{actions ? <div className="chat-analysis-actions">{actions}</div> : null}
</div>
)
}

View File

@@ -8,10 +8,6 @@
.error-container {
flex: 1;
}
.page-header {
margin-bottom: 16px;
}
}
// 加载和错误状态
@@ -69,24 +65,6 @@
}
}
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 16px;
h1 {
margin: 0;
}
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
}
@keyframes spin {
from {
transform: rotate(0deg);

View File

@@ -424,6 +424,19 @@ function AnalyticsPage() {
</div>
)
const analyticsHeaderActions = (
<>
<button className="btn btn-secondary" onClick={handleRefresh} disabled={isLoading}>
<RefreshCw size={16} className={isLoading ? 'spin' : ''} />
{isLoading ? '刷新中...' : '刷新'}
</button>
<button className="btn btn-secondary" onClick={openExcludeDialog}>
<UserMinus size={16} />
{excludedUsernames.size > 0 ? ` (${excludedUsernames.size})` : ''}
</button>
</>
)
if (isLoading && !isLoaded) {
return renderPageShell(
<div className="loading-container">
@@ -463,21 +476,9 @@ function AnalyticsPage() {
}
return renderPageShell(
<>
<div className="page-header">
<h1></h1>
<div className="header-actions">
<button className="btn btn-secondary" onClick={handleRefresh} disabled={isLoading}>
<RefreshCw size={16} className={isLoading ? 'spin' : ''} />
{isLoading ? '刷新中...' : '刷新'}
</button>
<button className="btn btn-secondary" onClick={openExcludeDialog}>
<UserMinus size={16} />
{excludedUsernames.size > 0 ? ` (${excludedUsernames.size})` : ''}
</button>
</div>
</div>
return (
<div className="analytics-page-shell">
<ChatAnalysisHeader currentMode="private" actions={analyticsHeaderActions} />
<div className="page-scroll">
<section className="page-section">
<div className="stats-overview">
@@ -625,7 +626,7 @@ function AnalyticsPage() {
</div>
</div>
)}
</>
</div>
)
}