Skip to content

Commit ace69aa

Browse files
committed
feat: 更新 LLM 侧边栏,添加 LLM 导航项并优化布局
1 parent 85d3d33 commit ace69aa

2 files changed

Lines changed: 66 additions & 80 deletions

File tree

src/components/layout/navItems.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414

1515
export const NAV_ITEMS = [
1616
{ to: "/dashboard", icon: LayoutDashboard, labelKey: "dashboard:title" },
17+
{ to: "/llm-insights", icon: Bot, labelKey: "llm:navTitle" },
1718
{ to: "/dashboard-insights", icon: Sparkles, labelKey: "dashboard:insightWorkspace.title" },
1819
{ to: "/widgets", icon: Layers, labelKey: "widgets:widgetCenter" },
1920
{ to: "/limits", icon: Bell, labelKey: "limits:title" },
@@ -22,6 +23,5 @@ export const NAV_ITEMS = [
2223
{ to: "/categories", icon: Tag, labelKey: "categories:title" },
2324
{ to: "/goals", icon: Target, labelKey: "goals:title" },
2425
{ to: "/focus", icon: Focus, labelKey: "focus:title" },
25-
{ to: "/llm-insights", icon: Bot, labelKey: "llm:navTitle" },
2626
{ to: "/settings", icon: Settings, labelKey: "settings:title" },
2727
] as const;

src/pages/LlmInsights/index.tsx

Lines changed: 65 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
Sparkles,
77
Send,
88
Loader2,
9-
RotateCcw,
109
AlertCircle,
1110
Bot,
1211
User,
@@ -554,74 +553,78 @@ export default function LlmInsights() {
554553

555554
{/* Main chat */}
556555
<div className="flex-1 flex flex-col min-w-0">
557-
<div className="flex items-center justify-between px-6 py-4 border-b border-surface-border">
558-
<div>
556+
<div className="flex items-center justify-between gap-4 px-6 py-4 border-b border-surface-border">
557+
<div className="min-w-0 flex-shrink-0">
559558
<h1 className="text-xl font-bold text-text-primary flex items-center gap-2">
560-
<Sparkles size={20} className="text-accent-blue" />
559+
<Sparkles size={20} className="text-accent-blue flex-shrink-0" />
561560
{t("llm:pageTitle")}
562561
</h1>
563562
<p className="text-text-muted text-xs mt-0.5">{t("llm:pageSubtitle")}</p>
564563
</div>
565-
<div className="flex items-center gap-2">
566-
<select
567-
value={range}
568-
onChange={(e) => setRange(e.target.value as AnalysisRange)}
569-
className="ui-field text-xs py-1.5 pr-7"
570-
disabled={loading}
571-
>
572-
{(
573-
[
574-
["today", t("llm:rangeToday")],
575-
["yesterday", t("llm:rangeYesterday")],
576-
["last_7_days", t("llm:rangeLast7Days")],
577-
["last_30_days", t("llm:rangeLast30Days")],
578-
["this_week", t("llm:rangeThisWeek")],
579-
["last_week", t("llm:rangeLastWeek")],
580-
["custom", t("llm:rangeCustom")],
581-
] as [AnalysisRange, string][]
582-
).map(([value, label]) => (
583-
<option key={value} value={value}>
584-
{label}
585-
</option>
586-
))}
587-
</select>
588-
589-
{range === "custom" && (
590-
<div className="flex items-center gap-1.5">
591-
<input
592-
type="date"
593-
value={customRange.start}
594-
max={customRange.end}
595-
onChange={(e) =>
596-
setCustomRange((prev) => ({ ...prev, start: e.target.value }))
597-
}
598-
disabled={loading}
599-
className="ui-field text-xs py-1.5 px-2"
600-
title={t("llm:startDate")}
601-
/>
602-
<span className="text-text-muted text-xs">-</span>
603-
<input
604-
type="date"
605-
value={customRange.end}
606-
min={customRange.start}
607-
onChange={(e) =>
608-
setCustomRange((prev) => ({ ...prev, end: e.target.value }))
609-
}
610-
disabled={loading}
611-
className="ui-field text-xs py-1.5 px-2"
612-
title={t("llm:endDate")}
613-
/>
614-
</div>
615-
)}
564+
<div className="flex items-center flex-wrap justify-end gap-2">
565+
<div className="flex items-center gap-2">
566+
<select
567+
value={range}
568+
onChange={(e) => setRange(e.target.value as AnalysisRange)}
569+
className="ui-field text-xs h-8 py-0 pr-7"
570+
disabled={loading}
571+
>
572+
{(
573+
[
574+
["today", t("llm:rangeToday")],
575+
["yesterday", t("llm:rangeYesterday")],
576+
["last_7_days", t("llm:rangeLast7Days")],
577+
["last_30_days", t("llm:rangeLast30Days")],
578+
["this_week", t("llm:rangeThisWeek")],
579+
["last_week", t("llm:rangeLastWeek")],
580+
["custom", t("llm:rangeCustom")],
581+
] as [AnalysisRange, string][]
582+
).map(([value, label]) => (
583+
<option key={value} value={value}>
584+
{label}
585+
</option>
586+
))}
587+
</select>
588+
589+
{range === "custom" && (
590+
<div className="flex items-center gap-1.5">
591+
<input
592+
type="date"
593+
value={customRange.start}
594+
max={customRange.end}
595+
onChange={(e) =>
596+
setCustomRange((prev) => ({ ...prev, start: e.target.value }))
597+
}
598+
disabled={loading}
599+
className="ui-field text-xs h-8 py-0 px-2"
600+
title={t("llm:startDate")}
601+
/>
602+
<span className="text-text-muted text-xs">-</span>
603+
<input
604+
type="date"
605+
value={customRange.end}
606+
min={customRange.start}
607+
onChange={(e) =>
608+
setCustomRange((prev) => ({ ...prev, end: e.target.value }))
609+
}
610+
disabled={loading}
611+
className="ui-field text-xs h-8 py-0 px-2"
612+
title={t("llm:endDate")}
613+
/>
614+
</div>
615+
)}
616+
</div>
616617

617618
<div ref={selectorRef} className="relative">
618619
<button
619620
onClick={() => setSelectorOpen((v) => !v)}
620621
disabled={providerIds.length === 0}
621-
className="inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg border border-surface-border text-text-secondary hover:bg-surface-hover hover:border-surface-border/80 transition-colors disabled:opacity-50"
622+
className="inline-flex items-center gap-1.5 text-xs h-8 px-2.5 rounded-lg border border-surface-border text-text-secondary hover:bg-surface-hover hover:border-surface-border/80 transition-colors disabled:opacity-50"
622623
>
623-
{activeProvider ? providerDisplayLabel(activeProvider) : t("llm:noProvider")}
624-
<ChevronDown size={13} className={clsx("transition-transform", selectorOpen && "rotate-180")} />
624+
<span className="truncate max-w-[120px]">
625+
{activeProvider ? providerDisplayLabel(activeProvider) : t("llm:noProvider")}
626+
</span>
627+
<ChevronDown size={13} className={clsx("flex-shrink-0 transition-transform", selectorOpen && "rotate-180")} />
625628
</button>
626629

627630
{selectorOpen && (
@@ -659,7 +662,7 @@ export default function LlmInsights() {
659662
<button
660663
onClick={() => void handleSummarize()}
661664
disabled={loading}
662-
className="inline-flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-xl border border-surface-border text-text-secondary hover:bg-surface-hover transition-colors disabled:opacity-50"
665+
className="inline-flex items-center gap-1.5 text-xs h-8 px-3 rounded-xl border border-surface-border text-text-secondary hover:bg-surface-hover transition-colors disabled:opacity-50 whitespace-nowrap"
663666
title={t("llm:summarizeTitle")}
664667
>
665668
<FoldVertical size={13} />
@@ -670,12 +673,10 @@ export default function LlmInsights() {
670673
<button
671674
onClick={() => void runAnalysis()}
672675
disabled={loading}
673-
className="inline-flex items-center gap-1.5 px-4 py-2 rounded-xl text-sm font-medium
676+
className="inline-flex items-center gap-1.5 h-8 px-3 rounded-xl text-xs font-medium
674677
bg-gradient-to-r from-accent-blue to-accent-purple text-white
675-
shadow-[0_4px_14px_rgba(108,142,191,0.35)]
676-
hover:shadow-[0_6px_20px_rgba(108,142,191,0.48)] hover:-translate-y-0.5
677-
active:translate-y-0 disabled:opacity-60 disabled:cursor-not-allowed
678-
transition-all duration-200"
678+
hover:opacity-90 disabled:opacity-60 disabled:cursor-not-allowed
679+
transition-opacity whitespace-nowrap"
679680
>
680681
{loading && !visibleMessages.some((m) => m.role === "assistant") ? (
681682
<Loader2 size={14} className="animate-spin" />
@@ -802,21 +803,6 @@ export default function LlmInsights() {
802803
>
803804
{loading ? <Loader2 size={16} className="animate-spin" /> : <Send size={16} />}
804805
</button>
805-
<button
806-
onClick={() => {
807-
setConversation((prev) => (prev ? { ...prev, messages: [] } : prev));
808-
if (conversation) {
809-
const cleared: LlmConversation = { ...conversation, messages: [], updated_at: new Date().toISOString() };
810-
void saveConversation(cleared);
811-
}
812-
}}
813-
disabled={loading || !conversation || conversation.messages.length === 0}
814-
className="p-2 rounded-xl border border-surface-border text-text-secondary hover:bg-surface-hover disabled:opacity-50 transition-colors"
815-
title={t("llm:newAnalysis")}
816-
aria-label={t("llm:newAnalysis")}
817-
>
818-
<RotateCcw size={16} />
819-
</button>
820806
</div>
821807
</div>
822808
</div>

0 commit comments

Comments
 (0)