fix(i-d): Geister-Komponenten eliminiert — AIAssistant-Seite erstellt (Agent-Auswahl + AgentChat, STATIC_COMPONENT_MAP registriert nach C3-Pattern); 5 Ghost-Contact-Detail-Tabs aus Backend-Manifesten entfernt; Production-Build mit AIAssistant-Chunk verifiziert (AIAssistant-DVb66TSo.js); tsc exit=0; ruff clean
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-08-24 21:50:21 +02:00
parent 49ca4c5fb2
commit 962e0ee1f6
9 changed files with 91 additions and 22 deletions
@@ -118,8 +118,8 @@ function normalizeModule(m: ComponentModule): { default: React.ComponentType<any
const STATIC_COMPONENT_MAP: Record<string, LazyComponentFactory> = {
// Pages
'@/pages/AgentDashboard': () => import('@/pages/AgentDashboard').then(normalizeModule),
// NOTE: @/pages/AIAssistant is declared in the backend manifest but does
// not exist as a frontend page — ghost component, see PROGRESS.md.
// BUG (ghost page) fixed in Block I-D: page now exists.
'@/pages/AIAssistant': () => import('@/pages/AIAssistant').then(normalizeModule),
'@/pages/AISettings': () => import('@/pages/AISettings').then(normalizeModule),
'@/pages/AutomationDashboard': () => import('@/pages/AutomationDashboard').then(normalizeModule),
'@/pages/AutomationSettings': () => import('@/pages/AutomationSettings').then(normalizeModule),
+64
View File
@@ -0,0 +1,64 @@
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useAgents } from '@/api/automation';
import { Card } from '@/components/ui/Card';
import { AgentChat } from '@/components/agents/AgentChat';
/**
* AI Assistant page (BUG: ghost page fixed — was declared in the backend
* manifest but did not exist, see PROGRESS.md "Ghost components").
*
* Minimal implementation: pick an agent, chat with it. Full agent management
* lives in the Agent Dashboard.
*/
export default function AIAssistant() {
const { t } = useTranslation();
const { data: agents, isLoading } = useAgents();
const [selectedAgentId, setSelectedAgentId] = useState('');
const selectedAgent = agents?.find((a) => a.id === selectedAgentId);
return (
<div className="p-6 space-y-4" aria-label={t('ai.assistant', 'AI Assistant')}>
<h1 className="text-xl font-semibold text-secondary-900">
{t('ai.assistant', 'AI Assistant')}
</h1>
<Card className="p-4">
<label
htmlFor="assistant-agent-select"
className="block text-sm font-medium text-secondary-700 mb-1"
>
{t('agent.targetAgent', 'Target agent')}
</label>
<select
id="assistant-agent-select"
value={selectedAgentId}
onChange={(e) => setSelectedAgentId(e.target.value)}
className="w-full rounded-lg border border-secondary-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"
>
<option value="">{t('agent.selectTargetAgent', 'Select an agent…')}</option>
{(agents ?? []).map((agent) => (
<option key={agent.id} value={agent.id}>
{agent.name}
</option>
))}
</select>
{!isLoading && (agents ?? []).length === 0 && (
<p className="mt-2 text-sm text-secondary-500">
{t(
'agent.noAgentsHint',
'No agents yet — create one in the Agent Dashboard.'
)}
</p>
)}
</Card>
{selectedAgent && (
<Card className="p-4">
<AgentChat agentId={selectedAgent.id} agentName={selectedAgent.name} />
</Card>
)}
</div>
);
}