// The admin app: header, notices, and the screen for the current menu page. import { Notice } from '@wordpress/components'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { post } from '../shared/api.ts'; import type { PluginNotice } from '../shared/types.ts'; import { adminPage } from './boot.ts'; import { ErrorNotice, ExternalButton } from './components/ui.tsx'; import { AppProvider, useApp } from './context.tsx'; import { useQuery } from './nav.ts'; import { ChatWidget } from './screens/ChatWidget.tsx'; import { Knowledge } from './screens/Knowledge.tsx'; import { Overview } from './screens/Overview.tsx'; import { Settings } from './screens/Settings.tsx'; import { Standins } from './screens/Standins.tsx'; import { Welcome } from './screens/Welcome.tsx'; function Header() { const { boot, state, connected } = useApp(); const domain = state.connection.site?.domain || state.environment.homeDomain; let chip = __('Not connected', 'stand-chat'); if (connected) chip = state.connection.reconnect ? __('Reconnect needed', 'stand-chat') : `${__('Connected', 'stand-chat')} · ${domain}`; else if (state.settings.site_id) chip = `${__('Site ID set', 'stand-chat')} · ${domain}`; return (
{__('Stand Chat', 'stand-chat')} {chip}
{(connected || state.settings.site_id) && {__('Open Chats', 'stand-chat')}}
); } export function noticeAction(kind: string): () => void { switch (kind) { case 'address': return () => { window.location.href = adminPage('stand-chat', { view: 'address' }); }; case 'check': return () => { // Reloaded either way: the screen then shows the check's result, or the one before. const reload = (): void => window.location.reload(); void post('/installation/check').then(reload, reload); }; case 'settings_privacy': return () => { window.location.href = adminPage('stand-chat-settings', { tab: 'privacy' }); }; case 'settings_connection': return () => { window.location.href = adminPage('stand-chat-settings', { tab: 'connection' }); }; case 'who_answers': return () => { window.location.href = adminPage('stand-chat', { focus: 'who' }); }; default: return () => undefined; } } function Notices() { const { state, setState } = useApp(); const [error, setError] = useState(null); const dismiss = async (notice: PluginNotice): Promise => { setError(null); try { const result = await post<{ notices: PluginNotice[] }>(`/notices/${notice.id}/dismiss`); setState({ ...state, notices: result.notices }); } catch (caught) { // The notice stays, and says why. setError(caught); } }; if (!state.notices.length) return null; return (
{state.notices.map((notice) => ( void dismiss(notice)} actions={notice.action ? [{ label: notice.action.label, onClick: noticeAction(notice.action.kind), variant: 'link' }] : []} > {notice.message} ))}
); } function Screen() { const { boot, connected } = useApp(); const query = useQuery(); switch (boot.screen) { case 'standins': return ; case 'knowledge': return ; case 'widget': return ; case 'settings': return ; case 'overview': case 'welcome': default: return connected ? : ; } } function Root() { const { settingsError } = useApp(); return (
{settingsError ? (
) : null}
); } export function App() { return ( ); }