import React, { useState, useEffect } from 'react'; import { Play, Plus, Trash2, Save, Rocket, Clock, FileText } from 'lucide-react'; import { Workflow, WorkflowStep, Note } from '../types'; import { STORAGE_KEYS, DEFAULT_WORKFLOWS } from '../constants'; interface WorkflowPanelProps { templates: Note[]; onStartWorkflow: (workflow: Workflow) => void; } export const WorkflowPanel: React.FC = ({ templates, onStartWorkflow }) => { const [workflows, setWorkflows] = useState(() => { const stored = localStorage.getItem(STORAGE_KEYS.WORKFLOWS); return stored ? JSON.parse(stored) : DEFAULT_WORKFLOWS; }); const [isEditing, setIsEditing] = useState(false); const [editingWorkflow, setEditingWorkflow] = useState(null); useEffect(() => { localStorage.setItem(STORAGE_KEYS.WORKFLOWS, JSON.stringify(workflows)); }, [workflows]); const handleCreateNew = () => { setEditingWorkflow({ id: `workflow-${Date.now()}`, name: 'New Workflow', description: '', steps: [{ templateId: '', delayMinutes: 0 }] }); setIsEditing(true); }; const handleSave = () => { if (!editingWorkflow) return; if (!editingWorkflow.name.trim()) { alert('Workflow name is required.'); return; } if (editingWorkflow.steps.some(s => !s.templateId)) { alert('All steps must have a selected template.'); return; } setWorkflows(prev => { const existingIndex = prev.findIndex(w => w.id === editingWorkflow.id); if (existingIndex >= 0) { const newWorkflows = [...prev]; newWorkflows[existingIndex] = editingWorkflow; return newWorkflows; } return [...prev, editingWorkflow]; }); setIsEditing(false); setEditingWorkflow(null); }; const handleDelete = (id: string) => { if (confirm('Delete this workflow?')) { setWorkflows(prev => prev.filter(w => w.id !== id)); } }; const addStep = () => { if (editingWorkflow) { setEditingWorkflow({ ...editingWorkflow, steps: [...editingWorkflow.steps, { templateId: '', delayMinutes: 30 }] }); } }; const removeStep = (index: number) => { if (editingWorkflow && editingWorkflow.steps.length > 1) { const newSteps = [...editingWorkflow.steps]; newSteps.splice(index, 1); setEditingWorkflow({ ...editingWorkflow, steps: newSteps }); } }; const updateStep = (index: number, field: keyof WorkflowStep, value: string | number) => { if (editingWorkflow) { const newSteps = [...editingWorkflow.steps]; newSteps[index] = { ...newSteps[index], [field]: value }; setEditingWorkflow({ ...editingWorkflow, steps: newSteps }); } }; return (

Workflow Builder

Create sequences of templates that fire on a timer.

{!isEditing && ( )}
{isEditing && editingWorkflow ? (

Edit Workflow

setEditingWorkflow({ ...editingWorkflow, name: e.target.value })} className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none transition-all" placeholder="e.g. Code Review & Deploy" />
setEditingWorkflow({ ...editingWorkflow, description: e.target.value })} className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none transition-all text-sm" placeholder="What does this sequence do?" />
{editingWorkflow.steps.map((step, idx) => (
{idx + 1}
updateStep(idx, 'delayMinutes', parseInt(e.target.value) || 0)} disabled={idx === 0} className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm outline-none focus:ring-2 focus:ring-indigo-500 disabled:bg-gray-100 disabled:text-gray-400" />
{idx > 0 && ( )}
))}
) : (
{workflows.map(wf => (
{wf.id !== 'hf-deployment-cue' && ( )}

{wf.name} {wf.id === 'hf-deployment-cue' && System}

{wf.description || 'No description provided.'}

Sequence
{wf.steps.map((step, idx) => (
{idx + 1}. {templates.find(t => t.id === step.templateId)?.title || step.templateId} {step.delayMinutes > 0 && ( +{step.delayMinutes}m )}
))}
))} {workflows.length === 0 && (

No workflows created yet.

)}
)}
); };