'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Switch } from '@/components/ui/switch'; import { ArrowLeft, Workflow, Bot, Cog, ListFilter, History, FileText, Settings, CheckCircle2, XCircle, Clock, Zap, Brain, Activity, } from 'lucide-react'; interface ExecutionStats { total: number; completed: number; failed: number; skipped: number; robotic: number; ai: number; hybrid: number; } export default function WorkflowDashboardPage() { const [enabled, setEnabled] = useState(false); const [stats, setStats] = useState({ total: 0, completed: 0, failed: 0, skipped: 0, robotic: 0, ai: 0, hybrid: 0 }); const [recentExecutions, setRecentExecutions] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { loadDashboard(); }, []); const loadDashboard = async () => { setIsLoading(true); try { const [settingsRes, execRes] = await Promise.all([ fetch('/api/workflow/settings'), fetch('/api/workflow/executions?limit=10'), ]); if (settingsRes.ok) { const settings = await settingsRes.json(); setEnabled(settings.workflow_engine_enabled?.value ?? false); } if (execRes.ok) { const execData = await execRes.json(); setRecentExecutions(execData.data || []); // Calculate stats from recent executions const all = execData.data || []; setStats({ total: execData.total || 0, completed: all.filter((e: any) => e.status === 'completed').length, failed: all.filter((e: any) => e.status === 'failed').length, skipped: all.filter((e: any) => e.status === 'skipped').length, robotic: all.filter((e: any) => e.classification_method === 'robotic').length, ai: all.filter((e: any) => e.classification_method === 'ai').length, hybrid: all.filter((e: any) => e.classification_method === 'hybrid').length, }); } } catch (error) { console.error('Failed to load dashboard:', error); } finally { setIsLoading(false); } }; const toggleEngine = async () => { try { const newValue = !enabled; await fetch('/api/workflow/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ workflow_engine_enabled: newValue }), }); setEnabled(newValue); } catch (error) { console.error('Failed to toggle engine:', error); } }; const navCards = [ { title: 'Classification Rules', description: 'Keyword-based rules for ticket classification', href: '/admin/workflow/classification', icon: Bot, color: 'text-blue-500', }, { title: 'Filter Rules', description: 'Exclusion/inclusion filters for ticket processing', href: '/admin/workflow/rules', icon: ListFilter, color: 'text-orange-500', }, { title: 'AI Templates', description: 'Prompt templates for AI-assisted classification', href: '/admin/workflow/templates', icon: Brain, color: 'text-purple-500', }, { title: 'Execution History', description: 'View past workflow executions and results', href: '/admin/workflow/history', icon: History, color: 'text-green-500', }, { title: 'Settings', description: 'AI providers, thresholds, and delays', href: '/admin/workflow/settings', icon: Settings, color: 'text-gray-500', }, ]; return (
{/* Header */}

Workflow Engine

Automated ticket triage and classification

{enabled ? 'Engine Active' : 'Engine Disabled'} {enabled ? 'ON' : 'OFF'}
{/* Stats Cards */}

Total Executions

{stats.total}

Completed

{stats.completed}

Robotic

{stats.robotic}

AI/Hybrid

{stats.ai + stats.hybrid}

{/* Navigation Cards */}
{navCards.map((card) => (
{card.title}
{card.description}
))}
{/* Recent Executions */}
Recent Executions Last 10 workflow runs
{recentExecutions.length === 0 ? (

No executions yet. Workflow engine will process incoming tickets when enabled.

) : (
{recentExecutions.map((exec) => (
{exec.status === 'completed' && } {exec.status === 'failed' && } {exec.status === 'skipped' && } {exec.status === 'running' && }
{exec.ticket_number ? `Ticket #${exec.ticket_number}` : `Entity ${exec.entity_id}`} {new Date(exec.created_at).toLocaleString()}
{exec.branch && ( {exec.branch} )} {exec.classification_method || 'n/a'} {exec.duration_ms && ( {exec.duration_ms}ms )}
))}
)}
); }