/** * TrusteeDashboardView * * Overview dashboard for a Trustee instance. * Shows statistics about positions, documents, and accounting sync status. * Includes a QuickActionBoard for one-click navigation to feature pages. */ import React, { useState, useEffect, useCallback } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useCurrentInstance } from '../../../hooks/useCurrentInstance'; import { useTrusteePositions, useTrusteeDocuments } from '../../../hooks/useTrustee'; import { useApiRequest } from '../../../hooks/useApi'; import { fetchAccountingConfig, fetchSyncStatus, fetchQuickActions, type AccountingConfig, type AccountingSyncStatus, } from '../../../api/trusteeApi'; import { QuickActionBoard, type QuickAction, type QuickActionCategory } from '../../../components/QuickActionBoard'; import styles from './TrusteeViews.module.css'; import { useLanguage } from '../../../providers/language/LanguageContext'; export const TrusteeDashboardView: React.FC = () => { const { t, currentLanguage } = useLanguage(); const navigate = useNavigate(); const { mandateId } = useParams<{ mandateId: string }>(); const { mandate, instance, instanceId } = useCurrentInstance(); const { items: positions, loading: posLoading } = useTrusteePositions(); const { items: documents, loading: docsLoading } = useTrusteeDocuments(); const { request } = useApiRequest(); const [accountingConfig, setAccountingConfig] = useState(null); const [syncItems, setSyncItems] = useState([]); const [accountingLoading, setAccountingLoading] = useState(true); const [quickActions, setQuickActions] = useState([]); const [quickActionCategories, setQuickActionCategories] = useState([]); const [quickActionsLoading, setQuickActionsLoading] = useState(true); useEffect(() => { if (!instanceId) return; const _loadAccountingData = async () => { setAccountingLoading(true); try { const [config, syncData] = await Promise.all([ fetchAccountingConfig(request, instanceId), fetchSyncStatus(request, instanceId), ]); setAccountingConfig(config); setSyncItems(syncData?.items || []); } catch { // Accounting not configured is fine } finally { setAccountingLoading(false); } }; _loadAccountingData(); }, [instanceId, request]); useEffect(() => { if (!instanceId) return; const _loadQuickActions = async () => { setQuickActionsLoading(true); try { const result = await fetchQuickActions(request, instanceId, currentLanguage || 'de'); setQuickActions(result.actions || []); setQuickActionCategories(result.categories || []); } catch { setQuickActions([]); setQuickActionCategories([]); } finally { setQuickActionsLoading(false); } }; _loadQuickActions(); }, [instanceId, request, currentLanguage]); const _handleDispatch = useCallback((action: QuickAction) => { const targetView = action.config?.targetView; if (targetView && mandateId && instanceId) { const tab = action.config?.tab; const path = `/mandates/${mandateId}/trustee/${instanceId}/${targetView}`; navigate(tab ? `${path}?tab=${tab}` : path); } }, [navigate, mandateId, instanceId]); const isLoading = posLoading || docsLoading || accountingLoading; const syncedCount = syncItems.filter(s => s.syncStatus === 'synced').length; const syncErrorCount = syncItems.filter(s => s.syncStatus === 'error').length; return (
📊
{isLoading ? '...' : positions.length}
{t('Positionen')}
📄
{isLoading ? '...' : documents.length}
{t('Dokumente')}
{accountingConfig?.configured ? '✓' : '○'}
{isLoading ? '...' : ( accountingConfig?.configured ? <>{syncedCount} {t('synchronisiert')}{syncErrorCount > 0 && / {syncErrorCount} {t('Fehler')}} : t('Nicht konfiguriert') )}
{t('Buchhaltung')}
👤
{instance?.userRoles?.length ? ( instance.userRoles.map((role: string, idx: number) => (
{t(role)}
)) ) : '-'}
{(instance?.userRoles?.length || 0) === 1 ? t('Deine Rolle') : t('Deine Rollen')}

{t('Instanz-Details')}

{t('Instanz:')} {instance?.instanceLabel}
{t('Mandant:')} {mandate?.label || instance?.mandateLabel || mandate?.name || instance?.mandateName || '-'}
{accountingConfig?.configured && (
{t('Buchhaltungssystem:')} {accountingConfig.displayLabel || accountingConfig.connectorType} {accountingConfig.lastSyncStatus && ` (${t(accountingConfig.lastSyncStatus)})`}
)}
); }; export default TrusteeDashboardView;