import React, { useState } from 'react'; import { AgentDashboard } from './components/AgentDashboard'; import { ClientPortal } from './components/ClientPortal'; import { AuthScreen } from './components/AuthScreen'; import { ToastContainer, ToastMessage, ToastType } from './components/Toast'; import { INITIAL_KB, INITIAL_QUEUES, INITIAL_SETTINGS, INITIAL_TICKETS, MOCK_AGENTS, MOCK_CLIENT_USERS, MOCK_SURVEYS } from './constants'; import { Agent, AppSettings, AppState, ClientUser, KBArticle, Ticket, TicketStatus, SurveyResult, TicketQueue, ChatMessage } from './types'; const App: React.FC = () => { const [state, setState] = useState({ tickets: INITIAL_TICKETS, articles: INITIAL_KB, agents: MOCK_AGENTS, queues: INITIAL_QUEUES, surveys: MOCK_SURVEYS, clientUsers: MOCK_CLIENT_USERS, settings: INITIAL_SETTINGS, currentUser: null, userRole: 'guest' }); const [toasts, setToasts] = useState([]); const showToast = (message: string, type: ToastType = 'info') => { const id = Date.now().toString(); setToasts(prev => [...prev, { id, message, type }]); }; const removeToast = (id: string) => { setToasts(prev => prev.filter(t => t.id !== id)); }; // --- Auth Management --- const handleClientLogin = (email: string, pass: string): boolean => { const user = state.clientUsers.find(u => u.email === email && u.password === pass); if (user) { setState(prev => ({ ...prev, currentUser: user, userRole: 'client' })); showToast(`Bentornato, ${user.name}!`, 'success'); return true; } return false; }; const handleAgentLogin = (email: string, pass: string): boolean => { const agent = state.agents.find(a => a.email === email && a.password === pass); if (agent) { // Set the specific role from the agent object (agent, supervisor, superadmin) setState(prev => ({ ...prev, currentUser: agent, userRole: agent.role })); showToast(`Accesso effettuato come ${agent.role}`, 'success'); return true; } return false; }; const handleClientRegister = (name: string, email: string, pass: string, company: string) => { const newUser: ClientUser = { id: `u${Date.now()}`, name, email, password: pass, company, status: 'active' }; setState(prev => ({ ...prev, clientUsers: [...prev.clientUsers, newUser], currentUser: newUser, userRole: 'client' })); showToast("Registrazione completata con successo!", 'success'); }; const handleLogout = () => { setState(prev => ({ ...prev, currentUser: null, userRole: 'guest' })); showToast("Logout effettuato", 'info'); }; // --- Ticket Management --- const createTicket = (ticketData: Omit) => { const newTicket: Ticket = { ...ticketData, id: `T-${1000 + state.tickets.length + 1}`, createdAt: new Date().toISOString(), status: TicketStatus.OPEN, messages: [], attachments: ticketData.attachments || [] }; setState(prev => ({ ...prev, tickets: [newTicket, ...prev.tickets] })); showToast("Ticket creato correttamente", 'success'); }; const replyToTicket = (ticketId: string, message: string) => { const newMessage: ChatMessage = { id: `m-${Date.now()}`, role: 'user', content: message, timestamp: new Date().toISOString() }; setState(prev => ({ ...prev, tickets: prev.tickets.map(t => t.id === ticketId ? { ...t, messages: [...t.messages, newMessage], status: t.status === TicketStatus.RESOLVED ? TicketStatus.OPEN : t.status } : t ) })); // Toast handled in component for better UX or here }; const updateTicketStatus = (id: string, status: TicketStatus) => { setState(prev => ({ ...prev, tickets: prev.tickets.map(t => t.id === id ? { ...t, status } : t) })); showToast(`Stato ticket aggiornato a ${status}`, 'info'); }; const updateTicketAgent = (id: string, agentId: string) => { setState(prev => ({ ...prev, tickets: prev.tickets.map(t => t.id === id ? { ...t, assignedAgentId: agentId } : t) })); showToast("Agente assegnato con successo", 'success'); }; // --- KB Management --- const addArticle = (article: KBArticle) => { if (!state.settings.features.kbEnabled) { showToast("La funzionalità Knowledge Base è disabilitata.", 'error'); return; } if (state.articles.length >= state.settings.features.maxKbArticles) { showToast(`Limite massimo di articoli (${state.settings.features.maxKbArticles}) raggiunto.`, 'error'); return; } // Check for AI Quota if manually triggering AI generation logic if (article.source === 'ai') { if (!state.settings.features.aiKnowledgeAgentEnabled) { showToast("L'Agente AI per la Knowledge Base è disabilitato.", 'error'); return; } const aiCount = state.articles.filter(a => a.source === 'ai').length; if (aiCount >= state.settings.features.maxAiGeneratedArticles) { showToast(`Limite creazione articoli AI (${state.settings.features.maxAiGeneratedArticles}) raggiunto.`, 'error'); return; } } setState(prev => ({ ...prev, articles: [article, ...prev.articles] })); showToast("Articolo aggiunto con successo", 'success'); }; const updateArticle = (updatedArticle: KBArticle) => { setState(prev => ({ ...prev, articles: prev.articles.map(a => a.id === updatedArticle.id ? updatedArticle : a) })); showToast("Articolo aggiornato", 'success'); }; // --- Survey Management --- const submitSurvey = (surveyData: Omit) => { const newSurvey: SurveyResult = { ...surveyData, id: `s${Date.now()}`, timestamp: new Date().toISOString() }; setState(prev => ({ ...prev, surveys: [...prev.surveys, newSurvey] })); showToast("Grazie per il tuo feedback!", 'success'); }; // --- Settings Management --- const addAgent = (agent: Agent) => { // Quota Validation if (agent.role === 'supervisor') { const supervisorCount = state.agents.filter(a => a.role === 'supervisor').length; if (supervisorCount >= state.settings.features.maxSupervisors) { showToast(`Limite Supervisor (${state.settings.features.maxSupervisors}) raggiunto.`, 'error'); return; } } else if (agent.role === 'agent') { const agentCount = state.agents.filter(a => a.role === 'agent').length; if (agentCount >= state.settings.features.maxAgents) { showToast(`Limite Agenti (${state.settings.features.maxAgents}) raggiunto.`, 'error'); return; } } setState(prev => ({ ...prev, agents: [...prev.agents, agent] })); showToast("Nuovo agente aggiunto", 'success'); }; const updateAgent = (agent: Agent) => { setState(prev => ({ ...prev, agents: prev.agents.map(a => a.id === agent.id ? agent : a) })); showToast("Dati agente aggiornati", 'success'); }; const removeAgent = (id: string) => { setState(prev => ({ ...prev, agents: prev.agents.filter(a => a.id !== id) })); showToast("Agente rimosso", 'info'); }; const addClientUser = (user: ClientUser) => { setState(prev => ({ ...prev, clientUsers: [...prev.clientUsers, user] })); showToast("Utente aggiunto", 'success'); }; const updateClientUser = (user: ClientUser) => { setState(prev => ({ ...prev, clientUsers: prev.clientUsers.map(u => u.id === user.id ? user : u) })); showToast("Utente aggiornato", 'success'); }; const removeClientUser = (id: string) => { setState(prev => ({ ...prev, clientUsers: prev.clientUsers.filter(u => u.id !== id) })); showToast("Utente rimosso", 'info'); }; const updateSettings = (newSettings: AppSettings) => { setState(prev => ({ ...prev, settings: newSettings })); // Toast triggered in component }; // --- Queue Management --- const addQueue = (queue: TicketQueue) => { setState(prev => ({ ...prev, queues: [...prev.queues, queue] })); showToast("Coda creata", 'success'); }; const removeQueue = (id: string) => { setState(prev => ({ ...prev, queues: prev.queues.filter(q => q.id !== id) })); showToast("Coda rimossa", 'info'); }; // Render Logic if (!state.currentUser) { return ( <> ); } // Filter Tickets for Agent: Only show tickets from assigned queues const isAgentOrSupervisor = state.userRole === 'agent' || state.userRole === 'supervisor'; const agentTickets = isAgentOrSupervisor ? state.tickets.filter(t => (state.currentUser as Agent).queues.includes(t.queue)) : state.tickets; // Superadmin sees all return (
{state.userRole === 'client' ? ( t.customerName === state.currentUser?.name)} queues={state.queues} onCreateTicket={createTicket} onReplyTicket={replyToTicket} onSubmitSurvey={submitSurvey} onLogout={handleLogout} showToast={showToast} /> ) : ( )}
); }; export default App;