| import { useState } from "react"; |
| import { runDemo } from "../content/api"; |
| import type { DemoResult, SimpleWorkflowCard, WorkflowCard } from "../content/types"; |
|
|
| interface WorkflowShowcaseProps { |
| demoWorkflows: WorkflowCard[]; |
| creatorWorkflows: SimpleWorkflowCard[]; |
| enterpriseWorkflows: SimpleWorkflowCard[]; |
| demoMode: boolean; |
| } |
|
|
| export function WorkflowShowcase({ |
| demoWorkflows, |
| creatorWorkflows, |
| enterpriseWorkflows, |
| demoMode, |
| }: WorkflowShowcaseProps) { |
| const [selectedId, setSelectedId] = useState<string>(demoWorkflows[0]?.id ?? ""); |
| const [result, setResult] = useState<DemoResult["result"] | null>(null); |
| const [loading, setLoading] = useState(false); |
|
|
| async function handleRun(workflowId: string) { |
| setSelectedId(workflowId); |
| setLoading(true); |
| try { |
| const response = await runDemo(workflowId); |
| setResult(response.result); |
| } finally { |
| setLoading(false); |
| } |
| } |
|
|
| return ( |
| <div className="workflow-stack"> |
| <div className="demo-workbench"> |
| <div className="workbench-copy"> |
| <h3>Controlled demo workflows</h3> |
| <p> |
| {demoMode |
| ? "Demo responses are simulated from local metadata so the Space remains polished without private infrastructure." |
| : "Responses can be switched to live behavior later without changing the surface model."} |
| </p> |
| </div> |
| <div className="workflow-grid"> |
| {demoWorkflows.map((workflow) => ( |
| <article key={workflow.id} className="workflow-card"> |
| <div className="workflow-head"> |
| <h4>{workflow.title}</h4> |
| <span className="route-pill">{workflow.route}</span> |
| </div> |
| <p>{workflow.summary}</p> |
| <p className="workflow-outcome">{workflow.outcome}</p> |
| <button |
| type="button" |
| className="button ghost" |
| onClick={() => handleRun(workflow.id)} |
| disabled={loading && selectedId === workflow.id} |
| > |
| {loading && selectedId === workflow.id ? "Running..." : "Preview demo"} |
| </button> |
| </article> |
| ))} |
| </div> |
| <div className="demo-console"> |
| <div className="console-head"> |
| <h4>Demo console</h4> |
| <span>{selectedId || "select a workflow"}</span> |
| </div> |
| {result ? ( |
| <div className="console-body"> |
| <strong>{result.headline}</strong> |
| <p>{result.details}</p> |
| <code>{result.artifact}</code> |
| </div> |
| ) : ( |
| <div className="console-body muted"> |
| <p>Select a workflow to view the simulated output contract.</p> |
| </div> |
| )} |
| </div> |
| </div> |
| |
| <div className="lane-grid"> |
| <div className="lane-card"> |
| <h3>Creator workflows</h3> |
| {creatorWorkflows.map((workflow) => ( |
| <article key={workflow.title}> |
| <h4>{workflow.title}</h4> |
| <p>{workflow.summary}</p> |
| </article> |
| ))} |
| </div> |
| <div className="lane-card"> |
| <h3>Enterprise / VoiceOps workflows</h3> |
| {enterpriseWorkflows.map((workflow) => ( |
| <article key={workflow.title}> |
| <h4>{workflow.title}</h4> |
| <p>{workflow.summary}</p> |
| </article> |
| ))} |
| </div> |
| </div> |
| </div> |
| ); |
| } |
|
|