'use client'
import React, { useState, useEffect } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { ArrowLeft, Save, X } from 'lucide-react'
import { workflowService, Workflow } from '../../../services/workflowService'
import WorkflowStepEditor from '../../../components/WorkflowStepEditor'
export default function EditWorkflowPage() {
const { id } = useParams<{ id: string }>()
const navigate = useNavigate()
const [workflow, setWorkflow] = useState<Workflow | null>(null)
const [loading, setLoading] = useState(true)
const [saving, setSaving] = useState(false)
const [name, setName] = useState('')
const [description, setDescription] = useState('')
const [category, setCategory] = useState<'avatar' | 'vbot' | 'sync' | 'custom'>('custom')
const [tags, setTags] = useState('')
useEffect(() => {
if (id) {
loadWorkflow()
}
}, [id])
const loadWorkflow = async () => {
if (!id) return
setLoading(true)
try {
const data = await workflowService.getWorkflow(id)
setWorkflow(data)
setName(data.name)
setDescription(data.description)
setCategory(data.category)
setTags(data.tags?.join(', ') || '')
} catch (error) {
console.error('Failed to load workflow:', error)
alert(`Failed to load workflow: ${error}`)
navigate('/workflows')
} finally {
setLoading(false)
}
}
const handleSave = async () => {
if (!id || !workflow) return
if (!name.trim()) {
alert('Please enter a workflow name')
return
}
setSaving(true)
try {
const workflowData: Partial<Workflow> = {
...workflow,
name: name.trim(),
description: description.trim(),
category,
tags: tags.split(',').map(t => t.trim()).filter(t => t),
steps: workflow.steps || []
}
await workflowService.updateWorkflow(id, workflowData)
navigate('/workflows')
} catch (error) {
alert(`Failed to update workflow: ${error}`)
} finally {
setSaving(false)
}
}
if (loading) {
return (
<div style={{ minHeight: '100vh', padding: '24px', backgroundColor: '#f8fafc', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<div style={{ textAlign: 'center' }}>
<div style={{
width: '40px',
height: '40px',
border: '4px solid #f3f3f3',
borderTop: '4px solid #2563eb',
borderRadius: '50%',
animation: 'spin 1s linear infinite',
margin: '0 auto 20px'
}} />
<p style={{ color: '#666' }}>Loading workflow...</p>
<style>{`
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
`}</style>
</div>
</div>
)
}
if (!workflow) {
return (
<div style={{ minHeight: '100vh', padding: '24px', backgroundColor: '#f8fafc' }}>
<div style={{ maxWidth: '1200px', margin: '0 auto', textAlign: 'center', padding: '64px' }}>
<h1 style={{ fontSize: '24px', fontWeight: '600', marginBottom: '16px', color: '#111827' }}>
Workflow Not Found
</h1>
<Link
to="/workflows"
style={{
display: 'inline-block',
padding: '12px 24px',
backgroundColor: '#3b82f6',
color: 'white',
textDecoration: 'none',
borderRadius: '8px',
fontSize: '14px',
fontWeight: '500'
}}
>
Back to Workflows
</Link>
</div>
</div>
)
}
return (
<div style={{ minHeight: '100vh', padding: '24px', backgroundColor: '#f8fafc' }}>
<div style={{ maxWidth: '1200px', margin: '0 auto' }}>
{/* Header */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '32px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
<Link
to="/workflows"
style={{
display: 'flex',
alignItems: 'center',
padding: '8px',
borderRadius: '8px',
backgroundColor: 'white',
border: '1px solid #e5e7eb',
textDecoration: 'none',
color: '#374151'
}}
>
<ArrowLeft style={{ width: '20px', height: '20px' }} />
</Link>
<div>
<h1 style={{ fontSize: '32px', fontWeight: '700', margin: '0 0 4px 0', color: '#111827' }}>
Edit Workflow
</h1>
<p style={{ fontSize: '16px', color: '#6b7280', margin: 0 }}>
{workflow.name}
</p>
</div>
</div>
<div style={{ display: 'flex', gap: '12px' }}>
<button
onClick={() => navigate('/workflows')}
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
padding: '12px 24px',
backgroundColor: '#f3f4f6',
color: '#374151',
border: 'none',
borderRadius: '8px',
fontSize: '16px',
fontWeight: '500',
cursor: 'pointer'
}}
>
<X style={{ width: '20px', height: '20px' }} />
Cancel
</button>
<button
onClick={handleSave}
disabled={saving}
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
padding: '12px 24px',
backgroundColor: saving ? '#9ca3af' : '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '8px',
fontSize: '16px',
fontWeight: '500',
cursor: saving ? 'not-allowed' : 'pointer'
}}
>
<Save style={{ width: '20px', height: '20px' }} />
{saving ? 'Saving...' : 'Save Changes'}
</button>
</div>
</div>
{/* Form */}
<div style={{
backgroundColor: 'white',
borderRadius: '12px',
padding: '24px',
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
}}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
{/* Basic Info */}
<div>
<h2 style={{ fontSize: '18px', fontWeight: '600', marginBottom: '16px', color: '#111827' }}>
Basic Information
</h2>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<div>
<label style={{ display: 'block', fontSize: '14px', fontWeight: '500', marginBottom: '8px', color: '#374151' }}>
Workflow Name *
</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="e.g., VRoid to VRChat Avatar"
style={{
width: '100%',
padding: '10px 12px',
border: '1px solid #e5e7eb',
borderRadius: '8px',
fontSize: '14px'
}}
/>
</div>
<div>
<label style={{ display: 'block', fontSize: '14px', fontWeight: '500', marginBottom: '8px', color: '#374151' }}>
Description
</label>
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Describe what this workflow does..."
rows={4}
style={{
width: '100%',
padding: '10px 12px',
border: '1px solid #e5e7eb',
borderRadius: '8px',
fontSize: '14px',
fontFamily: 'inherit',
resize: 'vertical'
}}
/>
</div>
<div>
<label style={{ display: 'block', fontSize: '14px', fontWeight: '500', marginBottom: '8px', color: '#374151' }}>
Category
</label>
<select
value={category}
onChange={(e) => setCategory(e.target.value as any)}
style={{
width: '100%',
padding: '10px 12px',
border: '1px solid #e5e7eb',
borderRadius: '8px',
fontSize: '14px',
backgroundColor: 'white'
}}
>
<option value="avatar">Avatar</option>
<option value="vbot">VBot</option>
<option value="sync">Sync</option>
<option value="custom">Custom</option>
</select>
</div>
<div>
<label style={{ display: 'block', fontSize: '14px', fontWeight: '500', marginBottom: '8px', color: '#374151' }}>
Tags (comma-separated)
</label>
<input
type="text"
value={tags}
onChange={(e) => setTags(e.target.value)}
placeholder="e.g., avatar, vrchat, automation"
style={{
width: '100%',
padding: '10px 12px',
border: '1px solid #e5e7eb',
borderRadius: '8px',
fontSize: '14px'
}}
/>
</div>
</div>
</div>
{/* Workflow Steps */}
<div>
<WorkflowStepEditor
steps={workflow.steps || []}
variables={workflow.variables || []}
onChange={(newSteps) => {
setWorkflow({ ...workflow, steps: newSteps })
}}
/>
</div>
</div>
</div>
</div>
</div>
)
}