diff --git a/frontend/src/pages/FlowBuilder.tsx b/frontend/src/pages/FlowBuilder.tsx index 7b46efb..479f022 100644 --- a/frontend/src/pages/FlowBuilder.tsx +++ b/frontend/src/pages/FlowBuilder.tsx @@ -12,7 +12,7 @@ import ReactFlow, { NodeTypes, } from 'reactflow'; import 'reactflow/dist/style.css'; -import { Button, message, Space } from 'antd'; +import { Button, message, Space, Dropdown } from 'antd'; import { SaveOutlined, ArrowLeftOutlined } from '@ant-design/icons'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiClient } from '../api/client'; @@ -42,11 +42,140 @@ const WaitInputNode = ({ data }: { data: any }) => ( ); +const ButtonsNode = ({ data }: { data: any }) => ( +
+ 🔘 Botones +
{data.config?.buttons?.length || 0} opciones
+
+); + +const SetVariableNode = ({ data }: { data: any }) => ( +
+ 📝 Variable +
{data.config?.variable || 'Sin nombre'}
+
+); + +const SwitchNode = ({ data }: { data: any }) => ( +
+ 🔀 Switch +
{data.config?.cases?.length || 0} casos
+
+); + +const DelayNode = ({ data }: { data: any }) => ( +
+ ⏱️ Delay +
{data.config?.seconds || 0}s
+
+); + +const RandomNode = ({ data }: { data: any }) => ( +
+ 🎲 Random +
A/B Test
+
+); + +const LoopNode = ({ data }: { data: any }) => ( +
+ 🔄 Loop +
Max: {data.config?.max_iterations || 10}
+
+); + +const GoToNode = ({ data }: { data: any }) => ( +
+ ➡️ GoTo +
{data.config?.target_node || 'Sin destino'}
+
+); + +const ValidateEmailNode = () => ( +
+ ✉️ Validar Email +
+); + +const ValidatePhoneNode = () => ( +
+ 📱 Validar Teléfono +
+); + +const ValidateNumberNode = () => ( +
+ 🔢 Validar Número +
+); + +const ValidateDateNode = () => ( +
+ 📅 Validar Fecha +
+); + +const ValidateRegexNode = () => ( +
+ 🔍 Validar Regex +
+); + +const ValidateOptionsNode = () => ( +
+ 📋 Validar Opciones +
+); + +const JavaScriptNode = ({ data }: { data: any }) => ( +
+ 📜 JavaScript +
Script
+
+); + +const HttpRequestNode = ({ data }: { data: any }) => ( +
+ 🌐 HTTP Request +
{data.config?.method || 'GET'} {data.config?.url?.slice(0, 20) || ''}
+
+); + +const AIResponseNode = ({ data }: { data: any }) => ( +
+ 🤖 AI Response +
GPT
+
+); + +const AISentimentNode = () => ( +
+ 💭 AI Sentiment +
+); + const nodeTypes: NodeTypes = { trigger: TriggerNode, message: MessageNode, condition: ConditionNode, wait_input: WaitInputNode, + buttons: ButtonsNode, + set_variable: SetVariableNode, + switch: SwitchNode, + delay: DelayNode, + random: RandomNode, + loop: LoopNode, + goto: GoToNode, + validate_email: ValidateEmailNode, + validate_phone: ValidatePhoneNode, + validate_number: ValidateNumberNode, + validate_date: ValidateDateNode, + validate_regex: ValidateRegexNode, + validate_options: ValidateOptionsNode, + javascript: JavaScriptNode, + http_request: HttpRequestNode, + ai_response: AIResponseNode, + ai_sentiment: AISentimentNode, }; interface Flow { @@ -124,10 +253,59 @@ export default function FlowBuilder() { {flow?.name} - - - - + addNode('trigger') }, + { key: 'message', label: '💬 Mensaje', onClick: () => addNode('message') }, + { key: 'buttons', label: '🔘 Botones', onClick: () => addNode('buttons') }, + { key: 'wait_input', label: '⏳ Esperar Input', onClick: () => addNode('wait_input') }, + { key: 'set_variable', label: '📝 Variable', onClick: () => addNode('set_variable') }, + ], + }} + > + + + addNode('condition') }, + { key: 'switch', label: '🔀 Switch', onClick: () => addNode('switch') }, + { key: 'delay', label: '⏱️ Delay', onClick: () => addNode('delay') }, + { key: 'random', label: '🎲 Random', onClick: () => addNode('random') }, + { key: 'loop', label: '🔄 Loop', onClick: () => addNode('loop') }, + { key: 'goto', label: '➡️ GoTo', onClick: () => addNode('goto') }, + ], + }} + > + + + addNode('validate_email') }, + { key: 'validate_phone', label: '📱 Teléfono', onClick: () => addNode('validate_phone') }, + { key: 'validate_number', label: '🔢 Número', onClick: () => addNode('validate_number') }, + { key: 'validate_date', label: '📅 Fecha', onClick: () => addNode('validate_date') }, + { key: 'validate_regex', label: '🔍 Regex', onClick: () => addNode('validate_regex') }, + { key: 'validate_options', label: '📋 Opciones', onClick: () => addNode('validate_options') }, + ], + }} + > + + + addNode('javascript') }, + { key: 'http_request', label: '🌐 HTTP Request', onClick: () => addNode('http_request') }, + { key: 'ai_response', label: '🤖 AI Response', onClick: () => addNode('ai_response') }, + { key: 'ai_sentiment', label: '💭 AI Sentiment', onClick: () => addNode('ai_sentiment') }, + ], + }} + > + +