diff --git a/apps/api/tests/test_phase22_nemotron_collab.py b/apps/api/tests/test_phase22_nemotron_collab.py index 81108ef3..63373ae1 100644 --- a/apps/api/tests/test_phase22_nemotron_collab.py +++ b/apps/api/tests/test_phase22_nemotron_collab.py @@ -178,7 +178,7 @@ class TestNemotronFailureFallback: source = f.read() idx_func = source.find("async def generate_incident_proposal_with_tools") - func_body = source[idx_func:idx_func + 5000] + func_body = source[idx_func:idx_func + 10000] # 最後的 return 在 except 之後 idx_except = func_body.rfind("except Exception") diff --git a/apps/web/src/components/shared/lobster-loading.tsx b/apps/web/src/components/shared/lobster-loading.tsx index 2b2daa4d..1a7c53de 100644 --- a/apps/web/src/components/shared/lobster-loading.tsx +++ b/apps/web/src/components/shared/lobster-loading.tsx @@ -11,20 +11,80 @@ import { useTranslations } from 'next-intl' +// ============================================================================= +// OpenClaw 風格龍蝦 SVG (參考 dashboardicons.com/icons/openclaw) +// 圓潤可愛風格 + 三色版本: red(預設/異常) / green(健康) / yellow(警告) +// ============================================================================= + +type LobsterColor = 'red' | 'green' | 'yellow' + +const COLOR_MAP: Record = { + red: { body: '#ef0011', dark: '#8a000a', eye: '#0b0303' }, + green: { body: '#22C55E', dark: '#15803d', eye: '#0b0303' }, + yellow: { body: '#F59E0B', dark: '#b45309', eye: '#0b0303' }, +} + +/** OpenClaw 風格可愛龍蝦 SVG */ +export function OpenClawLobster({ size = 36, color = 'red' }: { size?: number; color?: LobsterColor }) { + const c = COLOR_MAP[color] + return ( + + {/* 身體 (圓潤橢圓) */} + + {/* 頭 (大圓) */} + + {/* 肚子高光 */} + + + {/* 眼睛 (大圓白底 + 黑瞳) */} + + + + + {/* 眼睛高光 */} + + + {/* 左鉗 */} + + + + {/* 右鉗 */} + + + + {/* 觸角 */} + + + + + {/* 嘴巴 (微笑) */} + + {/* 腳 */} + + + + + + ) +} + +// ============================================================================= +// Loading 元件 +// ============================================================================= + interface LobsterLoadingProps { - /** 自訂提示文字 (預設 '載入中...') */ text?: string - /** 大小: 'sm' (24px) | 'md' (36px) | 'lg' (48px) */ size?: 'sm' | 'md' | 'lg' + color?: LobsterColor } const SIZES = { - sm: { svg: 24, bob: 2, fontSize: 11 }, - md: { svg: 36, bob: 3, fontSize: 12 }, - lg: { svg: 48, bob: 4, fontSize: 13 }, + sm: { svg: 28, bob: 2, fontSize: 11 }, + md: { svg: 40, bob: 3, fontSize: 12 }, + lg: { svg: 56, bob: 4, fontSize: 13 }, } -export function LobsterLoading({ text, size = 'md' }: LobsterLoadingProps) { +export function LobsterLoading({ text, size = 'md', color = 'red' }: LobsterLoadingProps) { const tc = useTranslations('common') const s = SIZES[size] const displayText = text ?? tc('loading') @@ -46,23 +106,7 @@ export function LobsterLoading({ text, size = 'md' }: LobsterLoadingProps) { } `}
- - - - - - {/* 左鉗 */} - - - {/* 右鉗 */} - - - {/* 觸角 */} - - - {/* 尾巴 */} - - +