From f739eedb473b7ea0e777fab2fa7aa4958f3f3571 Mon Sep 17 00:00:00 2001 From: Shad Date: Mon, 15 Jun 2026 00:18:25 +0000 Subject: [PATCH] =?UTF-8?q?feat(wizard):=20per-phase=20preview=20=E2=80=94?= =?UTF-8?q?=20graph=20in=20Analyze,=20form=20in=20Generate=20(#8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.css | 68 +++++++++++++++++++++++++++ src/scenes/Wizard.tsx | 104 ++++++++++++++++++++++++------------------ 2 files changed, 128 insertions(+), 44 deletions(-) diff --git a/src/index.css b/src/index.css index c8ac383..3e8b98d 100644 --- a/src/index.css +++ b/src/index.css @@ -2260,3 +2260,71 @@ select.studio-input { background: var(--bp-paper); } } .global-banner-warn { background: #fff6e0; color: #5a3a00; border-color: #b08a4a; } [data-theme="dark"] .global-banner-warn { background: #3a2a0a; color: #ffd690; border-color: #6b4a14; } + +/* Wizard per-phase preview: graph + form */ +.wizard-preview-graph { + display: flex; + flex-direction: column; + gap: 0; +} +.wizard-graph-node { + display: flex; + flex-direction: column; + align-items: stretch; + position: relative; + padding-bottom: 4px; +} +.wizard-graph-bubble { + display: grid; + grid-template-columns: 22px 1fr; + align-items: center; + gap: 8px; + padding: 8px 10px; + border: 1px solid color-mix(in srgb, var(--bp-navy) 25%, transparent); + background: var(--bp-paper); + font-size: 12px; +} +.wizard-graph-bubble.kind-agent { background: color-mix(in srgb, var(--bp-amber) 18%, var(--bp-paper)); border-color: color-mix(in srgb, var(--bp-amber) 60%, var(--bp-navy)); } +.wizard-graph-bubble.kind-system { background: color-mix(in srgb, var(--bp-navy) 10%, var(--bp-paper)); } +.wizard-graph-idx { font-family: var(--bp-mono); font-size: 10px; color: var(--bp-muted); text-align: right; } +.wizard-graph-name { color: var(--bp-navy); font-weight: 600; line-height: 1.3; } +.wizard-graph-meta { + font-family: var(--bp-mono); + font-size: 9.5px; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--bp-muted); + padding: 2px 0 0 30px; +} +.wizard-graph-edge { + width: 1px; + height: 12px; + background: color-mix(in srgb, var(--bp-navy) 35%, transparent); + margin: 4px 0 4px 10px; +} + +.wizard-form-preview { + display: flex; + flex-direction: column; + gap: 8px; + padding: 10px; + border: 1px dashed color-mix(in srgb, var(--bp-navy) 25%, transparent); + background: color-mix(in srgb, var(--bp-paper) 70%, var(--bp-canvas)); +} +.wizard-form-field { display: flex; flex-direction: column; gap: 3px; } +.wizard-form-label { + font-family: var(--bp-mono); + font-size: 10px; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--bp-muted); +} +.wizard-form-input { + padding: 6px 8px; + font-size: 12px; + border: 1px solid color-mix(in srgb, var(--bp-navy) 25%, transparent); + background: var(--bp-paper); + color: var(--bp-navy); + font-family: inherit; +} +.wizard-form-input:disabled { opacity: 0.7; } diff --git a/src/scenes/Wizard.tsx b/src/scenes/Wizard.tsx index daa524a..3dda0eb 100644 --- a/src/scenes/Wizard.tsx +++ b/src/scenes/Wizard.tsx @@ -263,59 +263,75 @@ export default function Wizard() { ); + const renderGraphPreview = () => ( +
+
Flow · {draft.nodes.length} step{draft.nodes.length === 1 ? "" : "s"}
+
+ {draft.nodes.map((n, i) => ( +
+
+ {i + 1} + {n.display_name || "Untitled"} +
+
+ {({ human: "Manual", agent: "Assistant", system: "System" } as Record)[n.dispatch_kind || "human"]} +
+ {i < draft.nodes.length - 1 &&
} +
+ ))} +
+
+ ); + + const renderFormPreview = () => ( +
+
Form preview · what users will fill in
+
+ {draft.fields.filter((f) => f.name).length === 0 ? ( +
Add fields on the left to see the form here.
+ ) : ( + draft.fields.filter((f) => f.name).map((f, i) => ( +
+ + {f.type === "boolean" ? ( + + ) : f.type === "number" ? ( + + ) : ( + + )} +
+ )) + )} +
+
+ ); + + const renderRulesPreview = () => ( +
+
Rules · {draft.rules.filter((r) => r.trim()).length}
+
    + {draft.rules.filter((r) => r.trim()).map((r, i) =>
  • {r}
  • )} + {draft.rules.filter((r) => r.trim()).length === 0 && ( +
  • No rules typed yet
  • + )} +
+
+ ); + const renderPreviewPane = () => { if (draft.nodes.length === 0 && draft.fields.length === 0 && draft.rules.length === 0) return null; return ( ); };