From ddb5c56e91ffef71684919c8c749c1e497aa40a2 Mon Sep 17 00:00:00 2001 From: fcarraUniSa Date: Tue, 17 Feb 2026 11:45:35 +0100 Subject: [PATCH] Update AgentDashboard.tsx --- components/AgentDashboard.tsx | 855 ++++++++++------------------------ 1 file changed, 253 insertions(+), 602 deletions(-) diff --git a/components/AgentDashboard.tsx b/components/AgentDashboard.tsx index 2273399..c32d5df 100644 --- a/components/AgentDashboard.tsx +++ b/components/AgentDashboard.tsx @@ -43,7 +43,9 @@ import { Key, Archive, Inbox, - Send + Send, + Eye, + EyeOff } from 'lucide-react'; interface AgentDashboardProps { @@ -60,6 +62,8 @@ interface AgentDashboardProps { onReplyTicket: (ticketId: string, message: string) => void; addArticle: (article: KBArticle) => void; updateArticle: (article: KBArticle) => void; + deleteArticle?: (id: string) => void; // New Prop + markTicketsAsAnalyzed?: (ticketIds: string[]) => void; // New Prop addAgent: (agent: Agent) => void; updateAgent: (agent: Agent) => void; removeAgent: (id: string) => void; @@ -202,6 +206,8 @@ export const AgentDashboard: React.FC = ({ onReplyTicket, addArticle, updateArticle, + deleteArticle, + markTicketsAsAnalyzed, addAgent, updateAgent, removeAgent, @@ -252,7 +258,7 @@ export const AgentDashboard: React.FC = ({ // KB Editor State const [isEditingKB, setIsEditingKB] = useState(false); - const [newArticle, setNewArticle] = useState>({ type: 'article', category: 'General' }); + const [newArticle, setNewArticle] = useState>({ type: 'article', category: 'General', visibility: 'public' }); const [isFetchingUrl, setIsFetchingUrl] = useState(false); // AI State @@ -269,6 +275,11 @@ export const AgentDashboard: React.FC = ({ const [newQueueForm, setNewQueueForm] = useState>({ name: '', description: '' }); const [tempSettings, setTempSettings] = useState(settings); + // Sync tempSettings with settings prop + useEffect(() => { + setTempSettings(settings); + }, [settings]); + // Email Template Editor State const [editingTemplate, setEditingTemplate] = useState(null); const [isTestingSmtp, setIsTestingSmtp] = useState(false); @@ -358,6 +369,8 @@ export const AgentDashboard: React.FC = ({ setIsAiAnalyzing(true); setAiSuggestions([]); + + // Pass ALL tickets. The service filters resolved ones. const suggestions = await generateNewKBArticle( settings.aiConfig.apiKey, tickets, @@ -365,10 +378,23 @@ export const AgentDashboard: React.FC = ({ settings.aiConfig.provider, settings.aiConfig.model ); + if (suggestions) { setAiSuggestions(suggestions); + if (suggestions.length === 0) { + showToast("Nessuna nuova lacuna identificata dall'AI nei ticket recenti.", 'info'); + } + + // Mark current resolved & unanalyzed tickets as analyzed so we don't process them again + const ticketsToMark = tickets + .filter(t => t.status === TicketStatus.RESOLVED && !t.hasBeenAnalyzed) + .map(t => t.id); + + if (ticketsToMark.length > 0 && markTicketsAsAnalyzed) { + markTicketsAsAnalyzed(ticketsToMark); + } } else { - showToast("Nessuna lacuna identificata dall'AI.", 'info'); + showToast("Errore durante l'analisi AI.", 'error'); } setIsAiAnalyzing(false); }; @@ -381,10 +407,11 @@ export const AgentDashboard: React.FC = ({ category: suggestion.category, type: 'article', source: 'ai', + visibility: 'internal', // Default AI suggestions to internal for review lastUpdated: new Date().toISOString().split('T')[0] }); setAiSuggestions(prev => prev.filter((_, i) => i !== index)); - showToast("Articolo aggiunto alla KB", 'success'); + showToast("Articolo aggiunto alla KB (Visibilità: Interna)", 'success'); }; const discardAiArticle = (index: number) => { @@ -414,6 +441,7 @@ export const AgentDashboard: React.FC = ({ type: newArticle.type || 'article', url: newArticle.url, source: newArticle.source || 'manual', + visibility: newArticle.visibility || 'public', lastUpdated: new Date().toISOString().split('T')[0] }; @@ -424,7 +452,7 @@ export const AgentDashboard: React.FC = ({ } setIsEditingKB(false); - setNewArticle({ type: 'article', category: 'General' }); + setNewArticle({ type: 'article', category: 'General', visibility: 'public' }); } }; @@ -571,32 +599,12 @@ export const AgentDashboard: React.FC = ({ }, 1500); }; - const handleSaveTemplate = () => { - if (editingTemplate) { - let updatedTemplates = [...tempSettings.emailTemplates]; - if (editingTemplate.id === 'new') { - updatedTemplates.push({ ...editingTemplate, id: `t${Date.now()}` }); - } else { - updatedTemplates = updatedTemplates.map(t => t.id === editingTemplate.id ? editingTemplate : t); - } - setTempSettings({ ...tempSettings, emailTemplates: updatedTemplates }); - setEditingTemplate(null); - } - }; - - const handleDeleteTemplate = (id: string) => { - setTempSettings({ - ...tempSettings, - emailTemplates: tempSettings.emailTemplates.filter(t => t.id !== id) - }); - }; - const handleSaveSettings = () => { setIsSaving(true); - // Simulate API call using prop updateSettings(tempSettings); setTimeout(() => { setIsSaving(false); + showToast("Impostazioni salvate con successo!", "success"); }, 800); }; @@ -652,75 +660,34 @@ export const AgentDashboard: React.FC = ({

{currentUser.role === 'superadmin' ? 'Super Admin' : currentUser.role === 'supervisor' ? 'Supervisor Workspace' : 'Agent Workspace'}

+ {/* ... Profile Footer ... */}
-
-
-
- {currentUser.name} -
-
-

{currentUser.name}

-

{currentUser.queues.join(', ')}

+
+
+
+ {currentUser.name} +
+
+

{currentUser.name}

+

{currentUser.queues.join(', ')}

+
-
- -
+ +
{/* Main Content */}
- {/* SETTINGS VIEW - PERMISSION GATED */} + {/* SETTINGS VIEW */} {view === 'settings' && canAccessSettings && (
@@ -765,9 +732,99 @@ export const AgentDashboard: React.FC = ({
- {/* SYSTEM SETTINGS TAB */} - {settingsTab === 'system' && canManageGlobalSettings && ( -
+ {/* AI CONFIG TAB WITH CUSTOMIZATION */} + {settingsTab === 'ai' && canManageTeam && ( +
+

Integrazione AI

+ + {/* Provider & Key */} +
+

Motore AI

+
+ + +
+
+ + setTempSettings({...tempSettings, aiConfig: {...tempSettings.aiConfig, model: e.target.value}})} + /> +
+
+ + setTempSettings({...tempSettings, aiConfig: {...tempSettings.aiConfig, apiKey: e.target.value}})} + /> +
+
+ + {/* Chat Agent Customization */} +
+

+ Personalizzazione Chatbot +

+
+
+ +
+
+ AI Avatar +
+ setTempSettings({...tempSettings, aiConfig: {...tempSettings.aiConfig, agentAvatar: e.target.value}})} + /> +
+
+
+
+ + setTempSettings({...tempSettings, aiConfig: {...tempSettings.aiConfig, agentName: e.target.value}})} + /> +
+
+ +