Remove AI analysis and rank cities by recent DEB performance

This commit is contained in:
2569718930@qq.com
2026-04-05 07:13:00 +08:00
parent 343c5c9c2f
commit a5b5711863
17 changed files with 124 additions and 905 deletions
+16 -5
View File
@@ -21,6 +21,10 @@ function toRiskGroup(level?: string): RiskGroupKey {
return "other";
}
function toPerformanceGroup(city: CityListItem): RiskGroupKey {
return toRiskGroup(city.deb_recent_tier);
}
function normalizeExpandedGroups(
value: unknown,
): Record<RiskGroupKey, boolean> {
@@ -60,11 +64,17 @@ export function CitySidebar() {
const sortedCities = useMemo(
() =>
[...store.cities].sort((a, b) => {
const aGroup = toRiskGroup(a.risk_level);
const bGroup = toRiskGroup(b.risk_level);
const aGroup = toPerformanceGroup(a);
const bGroup = toPerformanceGroup(b);
const aHitRate = Number(a.deb_recent_hit_rate ?? -1);
const bHitRate = Number(b.deb_recent_hit_rate ?? -1);
const aSamples = Number(a.deb_recent_sample_count ?? 0);
const bSamples = Number(b.deb_recent_sample_count ?? 0);
return (
(riskOrder[aGroup] ?? 3) -
(riskOrder[bGroup] ?? 3) ||
bHitRate - aHitRate ||
bSamples - aSamples ||
a.display_name.localeCompare(b.display_name)
);
}),
@@ -79,7 +89,7 @@ export function CitySidebar() {
other: [],
};
sortedCities.forEach((city) => {
groups[toRiskGroup(city.risk_level)].push(city);
groups[toPerformanceGroup(city)].push(city);
});
return groups;
}, [sortedCities]);
@@ -88,7 +98,7 @@ export function CitySidebar() {
if (!selectedCity) return;
const selected = store.cities.find((city) => city.name === selectedCity);
if (!selected) return;
const groupKey = toRiskGroup(selected.risk_level);
const groupKey = toPerformanceGroup(selected);
setExpandedGroups((current) =>
current[groupKey] ? current : { ...current, [groupKey]: true },
);
@@ -200,6 +210,7 @@ export function CitySidebar() {
const deviationSeverity =
snapshot?.deviation_monitor?.severity || "normal";
const secondaryText = deviationText || peakTempText;
const performanceTier = toPerformanceGroup(city);
return (
<button
@@ -213,7 +224,7 @@ export function CitySidebar() {
}
>
<div className="city-item-main">
<span className={clsx("risk-dot", city.risk_level)} />
<span className={clsx("risk-dot", performanceTier)} />
<span className="city-name-text">{city.display_name}</span>
<span
className={clsx(
@@ -19,7 +19,6 @@ import {
getRiskBadgeLabel,
getTemperatureChartData,
getWeatherSummary,
parseAiAnalysis,
} from "@/lib/dashboard-utils";
function EmptyState({ text }: { text: string }) {
@@ -760,35 +759,6 @@ export function ForecastTable() {
);
}
export function AiAnalysis() {
const { data } = useCityData();
const { t } = useI18n();
if (!data) return null;
const ai = parseAiAnalysis(data.ai_analysis);
return (
<section className="ai-section">
<h3>{t("section.ai")}</h3>
<div className="ai-box">
{!ai.summary && ai.bullets.length === 0 ? (
<span className="ai-placeholder">{t("section.aiEmpty")}</span>
) : (
<>
{ai.summary && <div className="ai-summary">{ai.summary}</div>}
{ai.bullets.length > 0 && (
<ul className="ai-list">
{ai.bullets.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
)}
</>
)}
</div>
</section>
);
}
export function RiskInfo() {
const { data } = useCityData();
const { t } = useI18n();
@@ -4,7 +4,6 @@ import React from "react";
import {
BarChart2,
Target,
ShieldAlert,
Zap,
Info,
Activity,
@@ -23,7 +22,7 @@ export function AnalyticsPanel({
data,
t = {}, // Default empty for now, can be expanded via context or props
}: AnalyticsPanelProps) {
const { overview, market_scan, models, ai_analysis } = data;
const { overview, market_scan, models } = data;
const modelEntries = Object.entries(models)
.filter(([_, v]) => v !== undefined && v !== null)
@@ -222,25 +221,6 @@ export function AnalyticsPanel({
))}
</div>
</section>
{ai_analysis && (
<section className="pt-2">
<div className="flex items-center gap-2 mb-3">
<Activity className="h-3 w-3 text-amber-500" />
<span className="text-[10px] font-black uppercase tracking-[0.15em] text-zinc-400">
AI COGNITIVE ANALYSIS
</span>
</div>
<div className="rounded-lg border border-zinc-800 bg-zinc-900/30 p-4 relative overflow-hidden group">
<div className="absolute top-0 right-0 p-2 opacity-20">
<ShieldAlert className="w-8 h-8 text-amber-500" />
</div>
<p className="text-[11px] leading-relaxed text-zinc-400 relative z-10 font-medium">
{ai_analysis}
</p>
</div>
</section>
)}
</div>
{/* Execute Scan Footer */}