// App shell
const NAV = [
{ id: 'dashboard', icon: 'DB', label: 'Dashboard' },
{ id: 'calendar', icon: 'CAL', label: 'Calendar' },
{ id: 'agent', icon: 'AG', label: 'Agent Settings' },
{ id: 'kb', icon: 'KB', label: 'Knowledge Base' },
{ id: 'logs', icon: 'LOG', label: 'Call Logs' },
{ id: 'whatsapp', icon: 'WA', label: 'WhatsApp Inbox' },
{ id: 'crm', icon: 'CRM', label: 'CRM Contacts' },
{ id: 'automations', icon: 'AUTO', label: 'Automations' },
{ id: 'outbound', icon: 'OUT', label: 'Outbound Calls' },
{ id: 'language', icon: 'LANG', label: 'Language Preset' },
{ id: 'demo', icon: 'DEMO', label: 'Demo Link' },
];
function Sidebar({ page, setPage, badgeCounts }) {
return (
);
}
function TopBar({ page }) {
const item = NAV.find(n => n.id === page);
const now = new Date();
const dateStr = now.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
return (
SPX AI
{'>'}
{item?.label}
);
}
function App() {
const PAGE_KEY = 'spxai_page';
const [page, setPage] = React.useState(() => {
try { return localStorage.getItem(PAGE_KEY) || localStorage.getItem('rxai_page') || 'dashboard'; } catch { return 'dashboard'; }
});
const [badgeCounts, setBadgeCounts] = React.useState({ whatsapp: 0, automations: 0 });
const [visitedPages, setVisitedPages] = React.useState(() => new Set([page]));
React.useEffect(() => {
try {
localStorage.setItem(PAGE_KEY, page);
localStorage.removeItem('rxai_page');
} catch {}
}, [page]);
React.useEffect(() => {
setVisitedPages(prev => {
if (prev.has(page)) return prev;
const next = new Set(prev);
next.add(page);
return next;
});
}, [page]);
React.useEffect(() => {
fetch('/api/whatsapp/conversations')
.then(r => r.json())
.then(data => {
const items = Array.isArray(data) ? data : (Array.isArray(data?.items) ? data.items : []);
const unread = items.reduce((a, c) => a + (parseInt(c.unread_count) || 0), 0);
setBadgeCounts(p => ({ ...p, whatsapp: unread }));
})
.catch(() => {});
}, []);
const pages = {
dashboard: DashboardPage,
calendar: CalendarPage,
agent: AgentSettingsPage,
kb: KBPage,
logs: CallLogsPage,
whatsapp: WhatsAppPage,
crm: CRMPage,
automations: AutomationsPage,
outbound: OutboundPage,
language: LanguagePage,
demo: DemoPage,
};
const renderedPages = Array.from(visitedPages).map(pageId => {
const PageComponent = pages[pageId] || DashboardPage;
const isActive = pageId === page;
return (
);
});
return (
);
}
Object.assign(window, { App });