From 6d70c5f8a3ed90564b08616a3fb041409916059c Mon Sep 17 00:00:00 2001
From: Clawd <ai@clawd.bot>
Date: Sat, 28 Feb 2026 07:30:40 -0800
Subject: Phase 4: React UI

- Add renderer/src/types.ts with Project, Session, Message, Phase types
- Add renderer/src/styles/globals.css with full styling
  - Dark theme with accent colors
  - Header, document pane, chat pane, action bar layouts
  - Phase indicator, token usage bar, buttons
- Add renderer/src/components/Header.tsx
  - Project/session dropdowns with create buttons
  - Phase indicator showing current workflow state
- Add renderer/src/components/DocumentPane.tsx
  - Markdown viewer/editor with toggle
  - Syntax highlighting for review comments
  - Task checkbox rendering
- Add renderer/src/components/ChatPane.tsx
  - Message list with auto-scroll
  - Input field with Enter to send
  - Loading state indicator
- Add renderer/src/components/ActionBar.tsx
  - Token usage bar with color coding
  - Review/Submit buttons for workflow
  - Permission mode toggle for implement phase
- Add renderer/src/App.tsx
  - Full state management for projects, sessions, messages
  - Claude message subscription
  - Workflow handlers (review, submit, phase advance)
- Update renderer/src/main.tsx to render App
---
 renderer/src/components/Header.tsx | 99 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 renderer/src/components/Header.tsx

(limited to 'renderer/src/components/Header.tsx')

diff --git a/renderer/src/components/Header.tsx b/renderer/src/components/Header.tsx
new file mode 100644
index 0000000..3dcbba9
--- /dev/null
+++ b/renderer/src/components/Header.tsx
@@ -0,0 +1,99 @@
+import React from "react";
+import type { Project, Session, Phase } from "../types";
+
+interface HeaderProps {
+  projects: Project[];
+  sessions: Session[];
+  selectedProject: Project | null;
+  selectedSession: Session | null;
+  onSelectProject: (project: Project | null) => void;
+  onSelectSession: (session: Session | null) => void;
+  onCreateProject: () => void;
+  onCreateSession: () => void;
+}
+
+const phaseLabels: Record<Phase, string> = {
+  research: "Research",
+  plan: "Plan",
+  implement: "Implement",
+};
+
+const phases: Phase[] = ["research", "plan", "implement"];
+
+export function Header({
+  projects,
+  sessions,
+  selectedProject,
+  selectedSession,
+  onSelectProject,
+  onSelectSession,
+  onCreateProject,
+  onCreateSession,
+}: HeaderProps) {
+  return (
+    <header className="header">
+      <div className="header-left">
+        <select
+          value={selectedProject?.id || ""}
+          onChange={(e) => {
+            const project = projects.find((p) => p.id === e.target.value);
+            onSelectProject(project || null);
+            onSelectSession(null);
+          }}
+        >
+          <option value="">Select Project...</option>
+          {projects.map((p) => (
+            <option key={p.id} value={p.id}>
+              {p.name}
+            </option>
+          ))}
+        </select>
+        <button onClick={onCreateProject}>+ Project</button>
+
+        {selectedProject && (
+          <>
+            <select
+              value={selectedSession?.id || ""}
+              onChange={(e) => {
+                const session = sessions.find((s) => s.id === e.target.value);
+                onSelectSession(session || null);
+              }}
+            >
+              <option value="">Select Session...</option>
+              {sessions.map((s) => (
+                <option key={s.id} value={s.id}>
+                  {s.name}
+                </option>
+              ))}
+            </select>
+            <button onClick={onCreateSession}>+ Session</button>
+          </>
+        )}
+      </div>
+
+      <div className="header-right">
+        {selectedSession && (
+          <div className="phase-indicator">
+            {phases.map((phase) => {
+              const phaseIndex = phases.indexOf(phase);
+              const currentIndex = phases.indexOf(selectedSession.phase);
+              const isComplete = phaseIndex < currentIndex;
+              const isActive = phase === selectedSession.phase;
+
+              return (
+                <span
+                  key={phase}
+                  className={`phase-step ${isActive ? "active" : ""} ${
+                    isComplete ? "complete" : ""
+                  }`}
+                >
+                  {phaseLabels[phase]}
+                </span>
+              );
+            })}
+          </div>
+        )}
+      </div>
+    </header>
+  );
+}
-- 
cgit v1.2.3

