From f92cbefed9c11f50d9cc2c6c2791e1753ed7bcc5 Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Fri, 24 Apr 2026 02:42:23 -0400 Subject: [PATCH] =?UTF-8?q?feat(pilot):=20ChatTabStrip=20component=20?= =?UTF-8?q?=E2=80=94=20[Chat]=20[Script=20Builder=20=E2=97=8F]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two-tab strip for the chat region. Parent controls mounting (strip only appears when the fix needs a script drafted). Indicator dot signals in-progress draft state. Tab switching via onChange callback; parent handles display:none toggling so tab contents preserve state. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/components/pilot/ChatTabStrip.tsx | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 frontend/src/components/pilot/ChatTabStrip.tsx diff --git a/frontend/src/components/pilot/ChatTabStrip.tsx b/frontend/src/components/pilot/ChatTabStrip.tsx new file mode 100644 index 00000000..7d610e25 --- /dev/null +++ b/frontend/src/components/pilot/ChatTabStrip.tsx @@ -0,0 +1,79 @@ +/** + * ChatTabStrip — two-tab strip at the top of the chat region: + * [Chat] [Script Builder ●] + * + * Visibility is controlled by the parent (AssistantChatPage) — this + * component renders whenever it's mounted. The parent decides whether + * to mount it based on fix state. + * + * Tab switching uses onChange; the parent toggles display:none on the + * tab contents so state is preserved across switches. + */ +import { cn } from '@/lib/utils' + +export type ChatTab = 'chat' | 'script_builder' + +export interface ChatTabStripProps { + active: ChatTab + onChange: (tab: ChatTab) => void + /** When true, shows the amber indicator dot on the Script Builder tab. */ + scriptBuilderHasProgress?: boolean +} + +export function ChatTabStrip({ + active, onChange, scriptBuilderHasProgress, +}: ChatTabStripProps) { + return ( +
+ onChange('chat')} + /> + onChange('script_builder')} + indicator={scriptBuilderHasProgress} + /> +
+ ) +} + +function TabButton({ + label, active, onClick, indicator, +}: { + label: string + active: boolean + onClick: () => void + indicator?: boolean +}) { + return ( + + ) +} + +export default ChatTabStrip