From 25835e065e8328fec242b160ffce96c49c0a6374 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 4 Jul 2026 11:52:14 +0800 Subject: [PATCH] feat(ui): UI/UX sweep for all P2 panels (Option A - Light Mode Glassmorphism) --- .../components/errors/error-overview-card.tsx | 119 ++--- .../components/errors/error-trend-chart.tsx | 130 ++---- .../components/errors/recent-issues-list.tsx | 200 +++----- .../src/components/errors/ux-audit-card.tsx | 181 +++----- .../src/components/panels/ActionLogsPanel.tsx | 436 +++++++----------- .../src/components/panels/AutoRepairPanel.tsx | 340 ++++++++------ apps/web/src/components/panels/DriftPanel.tsx | 315 +++++++------ .../web/src/components/panels/ErrorsPanel.tsx | 41 +- .../src/components/panels/MonitoringPanel.tsx | 215 +++++---- .../src/components/panels/TicketsPanel.tsx | 209 +++++---- apps/web/tsconfig.tsbuildinfo | 2 +- 11 files changed, 1016 insertions(+), 1172 deletions(-) diff --git a/apps/web/src/components/errors/error-overview-card.tsx b/apps/web/src/components/errors/error-overview-card.tsx index 4053478c1..8ec1b2ede 100644 --- a/apps/web/src/components/errors/error-overview-card.tsx +++ b/apps/web/src/components/errors/error-overview-card.tsx @@ -4,15 +4,7 @@ * ErrorOverviewCard - #41 錯誤統計卡片 * ===================================== * Phase 10: Sentry + OpenClaw + UI 整合 - * - * Nothing.tech 視覺規範: - * - 純白底色 (bg-white) - * - 極細淺灰邊框 (border border-gray-200) - * - 無圓角或微圓角 (rounded-sm) - * - 嚴禁陰影 (shadow-none) - * - * 建立: 2026-03-26 (台北時區) - * 建立者: Claude Code (#41 Error UI) + * 2026-07-04 Codex: UI/UX 全面升級 (Option A 明亮模式) */ import { useTranslations } from 'next-intl' @@ -20,10 +12,6 @@ import { cn } from '@/lib/utils' import { AlertTriangle, Bug, Clock, TrendingUp, TrendingDown, Minus } from 'lucide-react' import type { ErrorStatsResponse } from '@/lib/api-client' -// ============================================================================= -// Component Props -// ============================================================================= - interface ErrorOverviewCardProps { stats: ErrorStatsResponse | null loading?: boolean @@ -32,10 +20,6 @@ interface ErrorOverviewCardProps { className?: string } -// ============================================================================= -// Component -// ============================================================================= - export function ErrorOverviewCard({ stats, loading = false, @@ -45,135 +29,116 @@ export function ErrorOverviewCard({ }: ErrorOverviewCardProps) { const t = useTranslations('errors') - // Loading state if (loading) { return ( -
-
-
+
+
+
-
-
+
+
-
-
+
+
) } - // Error state if (error) { return ( -
-
- +
+
+ {error}
) } - // Empty state if (!stats) { return ( -
-
- -

{t('noData')}

+
+
+ +

{t('noData')}

) } - // Trend indicator const TrendIcon = changePercent > 0 ? TrendingUp : changePercent < 0 ? TrendingDown : Minus - const trendColor = changePercent > 0 ? 'text-red-500' : changePercent < 0 ? 'text-green-500' : 'text-gray-400' + const trendColor = changePercent > 0 ? 'text-[#9f2f25]' : changePercent < 0 ? 'text-[#17602a]' : 'text-[#77736a]' return ( -
- {/* Header */} -
+
+
- -

{t('overview')}

+ +

{t('overview')}

{changePercent !== 0 && ( -
- +
+ {Math.abs(changePercent).toFixed(1)}%
)}
- {/* Stats Grid */} -
+
{/* Unresolved Issues */} -
-
+
+
{stats.unresolved_issues}
-
+
{t('unresolvedIssues')}
{/* 24h Errors */} -
-
- - +
+
+ + {stats.error_count_24h}
-
+
{t('errors24h')}
{/* Critical Count */} -
-
- - +
+
+ + {stats.critical_count}
-
+
{t('criticalErrors')}
{/* Total Issues */} -
-
+
+
{stats.total_issues}
-
+
{t('totalIssues')}
- {/* Projects */} {stats.projects.length > 0 && ( -
-
- {t('projects')}: {stats.projects.join(', ')} +
+
+ {t('projects')}: {stats.projects.join(', ')}
)} diff --git a/apps/web/src/components/errors/error-trend-chart.tsx b/apps/web/src/components/errors/error-trend-chart.tsx index e9f8af255..f303dd06a 100644 --- a/apps/web/src/components/errors/error-trend-chart.tsx +++ b/apps/web/src/components/errors/error-trend-chart.tsx @@ -4,15 +4,7 @@ * ErrorTrendChart - #43 錯誤趨勢圖表 * =================================== * Phase 10: Sentry + OpenClaw + UI 整合 - * - * Nothing.tech 視覺規範: - * - 純白底色 (bg-white) - * - 極細淺灰邊框 (border border-gray-200) - * - 無圓角或微圓角 (rounded-sm) - * - 嚴禁陰影 (shadow-none) - * - * 建立: 2026-03-26 (台北時區) - * 建立者: Claude Code (#43 Error UI) + * 2026-07-04 Codex: UI/UX 全面升級 (Option A 明亮模式) */ import { useMemo } from 'react' @@ -21,10 +13,6 @@ import { cn } from '@/lib/utils' import { TrendingUp, TrendingDown, Minus, Activity } from 'lucide-react' import type { ErrorTrendResponse, ErrorTrendPoint } from '@/lib/api-client' -// ============================================================================= -// Component Props -// ============================================================================= - interface ErrorTrendChartProps { data: ErrorTrendResponse | null loading?: boolean @@ -34,13 +22,9 @@ interface ErrorTrendChartProps { className?: string } -// ============================================================================= -// Sparkline Component -// ============================================================================= - function Sparkline({ data, - width = 200, + width = 280, height = 60, }: { data: ErrorTrendPoint[] @@ -81,21 +65,19 @@ function Sparkline({ if (data.length === 0) { return ( - + ) } return ( - - {/* Area fill */} + - {/* Line */} - {/* Gradient definition */} - - + + ) } -// ============================================================================= -// Period Selector Component -// ============================================================================= - function PeriodSelector({ activePeriod, onChange, @@ -134,16 +111,16 @@ function PeriodSelector({ ] return ( -
+
{periods.map(({ value, label }) => ( - {/* External Link */} {issue.permalink && ( e.stopPropagation()} - className="text-gray-400 hover:text-gray-600" + className="text-[#77736a] transition-colors hover:text-[#4A90D9]" > )} - +
- {/* AI Analysis Result */} {analysis && analysis.status === 'completed' && analysis.analysis && ( -
-
- - {t('aiAnalysis')} +
+
+ + {t('aiAnalysis')} {analysis.analysis.severity}
-
- {t('rootCause')}: {analysis.analysis.root_cause} +
+ {t('rootCause')}: {analysis.analysis.root_cause}
-
- {t('fixSummary')}: {analysis.analysis.fix_recommendation.summary} +
+ {t('fixSummary')}: {analysis.analysis.fix_recommendation.summary}
-
+
{t('category')}: {analysis.analysis.category} | {t('confidence')}: {(analysis.analysis.confidence * 100).toFixed(0)}%
@@ -234,10 +201,6 @@ function IssueItem({ ) } -// ============================================================================= -// Main Component -// ============================================================================= - export function RecentIssuesList({ issues, loading = false, @@ -247,24 +210,20 @@ export function RecentIssuesList({ }: RecentIssuesListProps) { const t = useTranslations('errors') - // Loading state if (loading) { return ( -
-
-
+
+
+
-
+
{[1, 2, 3].map((i) => ( -
-
-
-
-
-
+
+
+
+
+
+
@@ -274,14 +233,10 @@ export function RecentIssuesList({ ) } - // Error state if (error) { return ( -
-
+
+
{error}
@@ -289,37 +244,28 @@ export function RecentIssuesList({ ) } - // Empty state if (issues.length === 0) { return ( -
-
- -

{t('noIssues')}

+
+
+ +

{t('noIssues')}

) } return ( -
- {/* Header */} -
+
+
- -

{t('recentIssues')}

- ({issues.length}) + +

{t('recentIssues')}

+ ({issues.length})
- {/* Issues List */} -
+
{issues.map((issue) => ( -
-