feat: [US-019] - Editor toolbar

Add toolbar component with buttons for adding nodes (Dialogue, Choice,
Variable) and managing projects (Save, Export, Import). Buttons are
styled with TailwindCSS and wired to placeholder handlers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Gustavo Henrique Santos Souza de Miranda 2026-01-21 12:45:11 -03:00
parent e530606cef
commit 9aa2aa48f0
2 changed files with 116 additions and 12 deletions

View File

@ -13,6 +13,7 @@ import ReactFlow, {
Edge, Edge,
} from 'reactflow' } from 'reactflow'
import 'reactflow/dist/style.css' import 'reactflow/dist/style.css'
import Toolbar from '@/components/editor/Toolbar'
import type { FlowchartData, FlowchartNode, FlowchartEdge } from '@/types/flowchart' import type { FlowchartData, FlowchartNode, FlowchartEdge } from '@/types/flowchart'
type FlowchartEditorProps = { type FlowchartEditorProps = {
@ -57,19 +58,54 @@ export default function FlowchartEditor({
[setEdges] [setEdges]
) )
// Placeholder handlers - functionality will be added in future stories
const handleAddDialogue = useCallback(() => {
// TODO: Implement in US-021
}, [])
const handleAddChoice = useCallback(() => {
// TODO: Implement in US-023
}, [])
const handleAddVariable = useCallback(() => {
// TODO: Implement in US-026
}, [])
const handleSave = useCallback(() => {
// TODO: Implement in US-034
}, [])
const handleExport = useCallback(() => {
// TODO: Implement in US-035
}, [])
const handleImport = useCallback(() => {
// TODO: Implement in US-036
}, [])
return ( return (
<div className="h-full w-full"> <div className="flex h-full w-full flex-col">
<ReactFlow <Toolbar
nodes={nodes} onAddDialogue={handleAddDialogue}
edges={edges} onAddChoice={handleAddChoice}
onNodesChange={onNodesChange} onAddVariable={handleAddVariable}
onEdgesChange={onEdgesChange} onSave={handleSave}
onConnect={onConnect} onExport={handleExport}
fitView onImport={handleImport}
> />
<Background variant={BackgroundVariant.Dots} gap={16} size={1} /> <div className="flex-1">
<Controls position="bottom-right" /> <ReactFlow
</ReactFlow> nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
>
<Background variant={BackgroundVariant.Dots} gap={16} size={1} />
<Controls position="bottom-right" />
</ReactFlow>
</div>
</div> </div>
) )
} }

View File

@ -0,0 +1,68 @@
'use client'
type ToolbarProps = {
onAddDialogue: () => void
onAddChoice: () => void
onAddVariable: () => void
onSave: () => void
onExport: () => void
onImport: () => void
}
export default function Toolbar({
onAddDialogue,
onAddChoice,
onAddVariable,
onSave,
onExport,
onImport,
}: ToolbarProps) {
return (
<div className="flex items-center justify-between border-b border-zinc-200 bg-zinc-50 px-4 py-2 dark:border-zinc-700 dark:bg-zinc-800">
<div className="flex items-center gap-2">
<span className="mr-2 text-sm font-medium text-zinc-500 dark:text-zinc-400">
Add Node:
</span>
<button
onClick={onAddDialogue}
className="rounded bg-blue-500 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-zinc-800"
>
Dialogue
</button>
<button
onClick={onAddChoice}
className="rounded bg-green-500 px-3 py-1.5 text-sm font-medium text-white hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 dark:focus:ring-offset-zinc-800"
>
Choice
</button>
<button
onClick={onAddVariable}
className="rounded bg-orange-500 px-3 py-1.5 text-sm font-medium text-white hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-2 dark:focus:ring-offset-zinc-800"
>
Variable
</button>
</div>
<div className="flex items-center gap-2">
<button
onClick={onSave}
className="rounded border border-zinc-300 bg-white px-3 py-1.5 text-sm font-medium text-zinc-700 hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:border-zinc-600 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600 dark:focus:ring-offset-zinc-800"
>
Save
</button>
<button
onClick={onExport}
className="rounded border border-zinc-300 bg-white px-3 py-1.5 text-sm font-medium text-zinc-700 hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:border-zinc-600 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600 dark:focus:ring-offset-zinc-800"
>
Export
</button>
<button
onClick={onImport}
className="rounded border border-zinc-300 bg-white px-3 py-1.5 text-sm font-medium text-zinc-700 hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:border-zinc-600 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600 dark:focus:ring-offset-zinc-800"
>
Import
</button>
</div>
</div>
)
}