aboutsummaryrefslogtreecommitdiffstats
path: root/renderer/src/components/NewSessionModal.tsx
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-03-04 21:36:32 -0800
committerbndw <ben@bdw.to>2026-03-04 21:36:32 -0800
commit73d2680b83ccbdbd8dfec2d319533e98b379b830 (patch)
tree193eaf5157edcf12d06dde85fb44efaf3aae2004 /renderer/src/components/NewSessionModal.tsx
parentb6405dd6a4ba65fc5dc6746db7be7be7d0bb29f3 (diff)
feat: Thread optional `phase` param into `db/sessions.ts::cre… (+7 more)
- ✅ Thread optional `phase` param into `db/sessions.ts::createSession()` - ✅ Thread optional `phase` param into `ipc/handlers.ts` sessions:create handler - ✅ Thread optional `phase` param into `preload.ts` createSession API - ✅ Update Plan phase system prompt to gracefully handle missing research.md - ✅ Update Implement phase system prompt to gracefully handle missing plan.md - ✅ Create `renderer/src/components/NewSessionModal.tsx` - ✅ Update `App.tsx`: add modal state, split handler, add modal JSX - ✅ Add modal CSS to `globals.css`
Diffstat (limited to 'renderer/src/components/NewSessionModal.tsx')
-rw-r--r--renderer/src/components/NewSessionModal.tsx60
1 files changed, 60 insertions, 0 deletions
diff --git a/renderer/src/components/NewSessionModal.tsx b/renderer/src/components/NewSessionModal.tsx
new file mode 100644
index 0000000..ad5dae9
--- /dev/null
+++ b/renderer/src/components/NewSessionModal.tsx
@@ -0,0 +1,60 @@
1import React, { useState, useEffect } from "react";
2import type { Phase } from "../types";
3
4interface NewSessionModalProps {
5 onConfirm: (phase: Phase) => void;
6 onCancel: () => void;
7}
8
9const phaseOptions: { phase: Phase; label: string; description: string }[] = [
10 { phase: "research", label: "Research", description: "Understand the codebase and requirements" },
11 { phase: "plan", label: "Plan", description: "Create a detailed implementation strategy" },
12 { phase: "implement", label: "Implement", description: "Execute the implementation plan" },
13];
14
15export function NewSessionModal({ onConfirm, onCancel }: NewSessionModalProps) {
16 const [selected, setSelected] = useState<Phase>("research");
17
18 // Close on Escape
19 useEffect(() => {
20 const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onCancel(); };
21 window.addEventListener("keydown", onKey);
22 return () => window.removeEventListener("keydown", onKey);
23 }, [onCancel]);
24
25 return (
26 <div className="modal-backdrop" onClick={onCancel}>
27 <div className="modal" onClick={(e) => e.stopPropagation()}>
28
29 <div className="modal-header">
30 <span className="modal-title">New Session</span>
31 <button className="modal-close" onClick={onCancel}>×</button>
32 </div>
33
34 <div className="modal-body">
35 <p className="modal-prompt">Choose where to start</p>
36 <div className="phase-cards">
37 {phaseOptions.map(({ phase, label, description }) => (
38 <button
39 key={phase}
40 className={`phase-card${selected === phase ? " selected" : ""}`}
41 onClick={() => setSelected(phase)}
42 >
43 <span className="phase-card-label">{label}</span>
44 <span className="phase-card-desc">{description}</span>
45 </button>
46 ))}
47 </div>
48 </div>
49
50 <div className="modal-footer">
51 <button className="modal-btn-secondary" onClick={onCancel}>Cancel</button>
52 <button className="modal-btn-primary" onClick={() => onConfirm(selected)}>
53 Create
54 </button>
55 </div>
56
57 </div>
58 </div>
59 );
60}