import React, { useState } from 'react'; import { Sparkles, Loader2, ArrowRight, RotateCcw } from 'lucide-react'; import { appsMetadata } from '../constants/appsMetadata'; const LS_KEY = 'wpbot_ai_gen_settings'; const findApp = (id) => appsMetadata.find(a => a.id === id); const findActionName = (appId, actionId) => { const app = findApp(appId); if (!app) return actionId; if (app.categories) { for (const cat of app.categories) { const found = cat.actions?.find(a => a.id === actionId); if (found) return found.name; } } if (app.actions) { const found = app.actions.find(a => a.id === actionId); if (found) return found.name; } return actionId; }; const APP_VISUAL = { wordpress: { title: 'WordPress', icon: 'W', iconBg: 'bg-blue-600' }, woocommerce: { title: 'WooCommerce', icon: 'WC', iconBg: 'bg-purple-600' }, wpforms: { title: 'WPForms', icon: 'F', iconBg: 'bg-orange-500' }, cf7: { title: 'Contact Form 7', icon: 'C7', iconBg: 'bg-black' }, fluent_forms: { title: 'Fluent Forms', icon: 'FF', iconBg: 'bg-green-600' }, webhook: { title: 'Webhook', icon: 'Wh', iconBg: 'bg-violet-600' }, facebook: { title: 'Facebook', icon: 'fb', iconBg: 'bg-blue-600' }, google_sheets: { title: 'Google Sheets', icon: 'GS', iconBg: 'bg-green-600' }, mail: { title: 'Mail', icon: 'M', iconBg: 'bg-gray-700' }, telegram: { title: 'Telegram', icon: 'Tg', iconBg: 'bg-blue-500' }, whatsapp: { title: 'WhatsApp', icon: 'WA', iconBg: 'bg-green-500' }, instagram: { title: 'Instagram', icon: 'Ig', iconBg: 'bg-pink-500' }, linkedin: { title: 'LinkedIn', icon: 'In', iconBg: 'bg-sky-600' }, openai: { title: 'OpenAI', icon: 'OA', iconBg: 'bg-emerald-600' }, claude: { title: 'Claude', icon: 'CL', iconBg: 'bg-amber-700' }, gemini: { title: 'Gemini', icon: 'GE', iconBg: 'bg-blue-500' }, grok: { title: 'Grok AI', icon: 'GK', iconBg: 'bg-slate-900' }, mistral: { title: 'Mistral AI', icon: 'MI', iconBg: 'bg-orange-600' }, openrouter: { title: 'OpenRouter', icon: 'OR', iconBg: 'bg-indigo-600' }, fluentcrm: { title: 'FluentCRM', icon: 'FC', iconBg: 'bg-blue-700' }, filters: { title: 'Filters', icon: 'FT', iconBg: 'bg-yellow-500' }, iterator: { title: 'Iterator', icon: '↻', iconBg: 'bg-amber-500' }, iterator_end: { title: 'Iterator End', icon: '⏹', iconBg: 'bg-amber-700' }, api: { title: 'API', icon: 'A', iconBg: 'bg-slate-700' }, mailboxlayer: { title: 'MailboxLayer', icon: 'ML', iconBg: 'bg-blue-600' }, mailrefine: { title: 'MailRefine', icon: 'MR', iconBg: 'bg-violet-600' }, }; const PROVIDERS = [ { id: 'openai', name: 'OpenAI', models: ['gpt-4o-mini', 'gpt-4o', 'gpt-4-turbo'] }, { id: 'claude', name: 'Claude', models: ['claude-3-5-sonnet-20240620', 'claude-3-haiku-20240307'] }, { id: 'gemini', name: 'Gemini', models: ['gemini-1.5-flash', 'gemini-2.0-flash', 'gemini-1.5-pro'] }, ]; function computePositions(nodes, connections) { const childrenOf = {}; connections.forEach(({ from, to }) => { if (!childrenOf[from]) childrenOf[from] = []; childrenOf[from].push(to); }); const pos = {}; const visited = new Set(); const queue = [{ idx: 0, x: 100, y: 200 }]; while (queue.length) { const { idx, x, y } = queue.shift(); if (visited.has(idx)) continue; visited.add(idx); pos[idx] = { x, y }; const kids = childrenOf[idx] || []; const spread = (kids.length - 1) * 160; kids.forEach((child, i) => { if (!visited.has(child)) { queue.push({ idx: child, x: x + 300, y: y - spread / 2 + i * 160 }); } }); } return pos; } function buildWorkflowData(aiResult) { const { nodes: aiNodes, connections: aiConns } = aiResult; const positions = computePositions(aiNodes, aiConns); const nodes = aiNodes.map((n, idx) => { const visual = APP_VISUAL[n.appId] || { title: n.appId, icon: '?', iconBg: 'bg-gray-500' }; return { id: idx === 0 ? 'node-trigger-1' : `node-action-${idx}`, type: n.type, title: visual.title, subtitle: findActionName(n.appId, n.actionId), position: positions[idx] || { x: 100 + idx * 300, y: 200 }, icon: visual.icon, iconBg: visual.iconBg, actionNumber: idx + 1, appData: findApp(n.appId) || null, }; }); const connections = aiConns.map((c, idx) => ({ id: `conn-${idx + 1}`, from: c.from === 0 ? 'node-trigger-1' : `node-action-${c.from}`, to: c.to === 0 ? 'node-trigger-1' : `node-action-${c.to}`, fromHandle: 'right', toHandle: 'left', })); return { nodes, connections }; } const AiWorkflowGenerator = ({ onSelect }) => { const [settings, setSettings] = useState(() => { try { return JSON.parse(localStorage.getItem(LS_KEY) || '{}'); } catch { return {}; } }); const [prompt, setPrompt] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [result, setResult] = useState(null); const provider = settings.provider || 'openai'; const apiKey = settings.api_key || ''; const models = PROVIDERS.find(p => p.id === provider)?.models || []; const model = settings.model && models.includes(settings.model) ? settings.model : models[0]; const updateSettings = (patch) => { const next = { ...settings, ...patch }; setSettings(next); localStorage.setItem(LS_KEY, JSON.stringify(next)); }; const handleGenerate = async () => { if (!prompt.trim()) { setError('Please describe your workflow.'); return; } if (!apiKey.trim()) { setError('Please enter your API key.'); return; } setError(''); setResult(null); setLoading(true); try { const response = await fetch(`${window.wpbotAutomator.apiUrl}/generate-workflow`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': window.wpbotAutomator.nonce, }, body: JSON.stringify({ provider, api_key: apiKey, model, prompt: prompt.trim() }), }); const data = await response.json(); if (!response.ok || !data.success) { setError(data.message || data.code || 'Failed to generate. Please try again.'); return; } setResult(data.workflow); } catch { setError('Network error. Please try again.'); } finally { setLoading(false); } }; const handleUse = () => { if (!result) return; onSelect({ id: null, name: result.name, description: result.description, workflow_data: buildWorkflowData(result), }); }; return (

Describe your automation in plain English and AI will build the workflow for you.

{/* Prompt */}