/** * Zammad Plugin Dashboard Component * Main dashboard for Zammad plugin showing tickets, statistics, and quick actions */ import React, { useState, useEffect } from 'react'; import { Box, Grid, Card, CardContent, Typography, Button, Chip, Alert, Table, TableBody, TableCell, TableHead, TableRow, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, LinearProgress, Tooltip } from '@mui/material'; import { Refresh as RefreshIcon, Sync as SyncIcon, Analytics as AnalyticsIcon, Assignment as TicketIcon, AutoAwesome as AIIcon, Settings as SettingsIcon, OpenInNew as OpenIcon } from '@mui/icons-material'; interface ZammadTicket { id: string; title: string; status: string; priority: string; customer_id: string; created_at: string; ai_summary?: string; } interface ZammadStats { configurations: number; total_tickets: number; tickets_with_summaries: number; recent_tickets: number; summary_rate: number; last_sync: string; } export const ZammadDashboard: React.FC = () => { const [tickets, setTickets] = useState([]); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [selectedTicket, setSelectedTicket] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); const [syncing, setSyncing] = useState(false); useEffect(() => { loadDashboardData(); }, []); const loadDashboardData = async () => { setLoading(true); setError(null); try { // Load statistics const statsResponse = await fetch('/api/v1/plugins/zammad/statistics'); if (statsResponse.ok) { const statsData = await statsResponse.json(); setStats(statsData); } // Load recent tickets const ticketsResponse = await fetch('/api/v1/plugins/zammad/tickets?limit=10'); if (ticketsResponse.ok) { const ticketsData = await ticketsResponse.json(); setTickets(ticketsData.tickets || []); } } catch (err) { setError('Failed to load dashboard data'); console.error('Dashboard load error:', err); } finally { setLoading(false); } }; const handleSyncTickets = async () => { setSyncing(true); try { const response = await fetch('/api/v1/plugins/zammad/tickets/sync', { method: 'GET' }); if (response.ok) { const result = await response.json(); // Reload dashboard data after sync await loadDashboardData(); // Show success message with sync count console.log(`Synced ${result.synced_count} tickets`); } else { throw new Error('Sync failed'); } } catch (err) { setError('Failed to sync tickets'); } finally { setSyncing(false); } }; const handleTicketClick = (ticket: ZammadTicket) => { setSelectedTicket(ticket); setDialogOpen(true); }; const handleSummarizeTicket = async (ticketId: string) => { try { const response = await fetch(`/api/v1/plugins/zammad/tickets/${ticketId}/summarize`, { method: 'POST' }); if (response.ok) { // Show success message console.log('Summarization started'); } } catch (err) { console.error('Summarization failed:', err); } }; const getStatusColor = (status: string) => { switch (status.toLowerCase()) { case 'open': return 'error'; case 'pending': return 'warning'; case 'closed': return 'success'; default: return 'default'; } }; const getPriorityColor = (priority: string) => { switch (priority) { case '3 high': return 'error'; case '2 normal': return 'warning'; case '1 low': return 'success'; default: return 'default'; } }; return ( {/* Header */} Zammad Dashboard {error && ( {error} )} {loading && } {/* Statistics Cards */} {stats && ( {stats.total_tickets} Total Tickets {stats.tickets_with_summaries} AI Summaries {stats.summary_rate}% Summary Rate {stats.recent_tickets} Recent (7 days) )} {/* Recent Tickets Table */} Recent Tickets {tickets.length === 0 ? ( No tickets found. Try syncing with Zammad. ) : ( Title Status Priority AI Summary Actions {tickets.map((ticket) => ( handleTicketClick(ticket)}> {ticket.title} {ticket.ai_summary ? ( ) : ( )} { e.stopPropagation(); handleSummarizeTicket(ticket.id); }} disabled={!!ticket.ai_summary} > ))}
)}
{/* Ticket Detail Dialog */} setDialogOpen(false)} maxWidth="md" fullWidth > Ticket Details {selectedTicket && ( {selectedTicket.title} Customer: {selectedTicket.customer_id} Created: {new Date(selectedTicket.created_at).toLocaleString()} {selectedTicket.ai_summary && ( AI Summary {selectedTicket.ai_summary} )} )} {selectedTicket && !selectedTicket.ai_summary && ( )}
); };