feat(runde-5): Startseite mit Agenten-Meetingraum, sticky Chat und Noras Kanäle
Hauptnavigation und Startseite (§2) - Hauptseite «Übersicht» samt Route, Menüeintrag, Hook, Service und den nur dort verwendeten Widgets entfernt; /supply/dashboard leitet auf die Startseite um, damit Lesezeichen nicht ins Leere laufen. - «Meine Objekte» heisst im Menü «Startseite»; die frühere Überschrift «Objektverwaltung» heisst jetzt «Meine Objekte». - Die Startseite scrollt als Ganzes. Die Höhe des Meetingraums rechnet gegen die Viewport-Höhe, damit Titel und Balken «Filter & Übersicht» beim Einstieg auf jeder Monitorgrösse sichtbar bleiben (geprüft 1280–1920 px). Agenten-Meetingraum (§3) - Zentralperspektive aus clip-path-Flächen, ohne 3D-Engine und ohne Animationsbibliothek: rechts geschlossene Wand, links und gegenüber boden- bis deckenhohe Glasfronten mit Blick auf Rhein, Basler Münster, Altstadt und Wettsteinbrücke. - Sitzordnung, Zielrouten, Grössen und Plakettenversatz liegen in einer zentralen Konfiguration (meetingRoomSeats.ts). - Neuer Agent Giorgio, Personalverwalter, sitzt vis-à-vis und führt in «Meine Agenten». Er steht bewusst nicht in AGENT_WORKSPACES: er hat keine Arbeitsseite, sondern ist die Adminfläche selbst. - Auf schmalen Schirmen tritt eine vereinfachte Kachelanordnung an die Stelle der Perspektive; ausgeblendet wird kein Agent. Sticky Chat bei allen Agenten (§5, §9–§11) - Scrollt der Chatkopf unter den globalen Balken, übernimmt dort eine kompakte Fassung mit Porträt, Name, Frage und Eingabefeld. - Ein gemeinsamer Zustand (agentChatStore) statt zweier Chat-Instanzen: Eingabetext und Fokus überstehen den Wechsel in beide Richtungen. - Noras Seite scrollte bisher gar nicht — Chatkopf ausserhalb des Scrollbereichs, zwei getrennt scrollende Spalten darunter. Behoben über den Seitenaufbau, nicht über eine Nora-Sonderlösung. Nora: CRM-Kanal und gemeinsame Lead-Liste (§12, §13) - Dritter Kanal «CRM» mit eigenem Domänentyp, Mockdaten, Provider, Service und Hook nach dem bestehenden Schichtenmuster. - Die Reiter «KI-Signale»/«Netzwerk» sind einer gemeinsamen Liste gewichen. Jede Zeile trägt ihre Kanalherkunft als Badge; die Herkunft steht im Datenmodell (LeadChannel) und wird nicht aus der Darstellung geraten. - Der frühere Reiterbalken ist der Filter «Kanaltyp» mit Alle/KI Signal/ Netzwerk/CRM, Standard «Alle», mit Empty State und Rücksetzung. Produkttour und Profilmenü (§8) - Tour auf die neue Struktur umgeschrieben: Startseite, Meetingraum, Agenten, sticky Chat, Leadkanäle. «Übersicht» kommt nicht mehr vor, «Meine Objekte» bezeichnet nur noch den Objektbereich. - Bereich «Demo-Modus» mit «Verwaltung» und «Bürosuche» entfernt. Geprüft: 413 Tests, Typecheck, Build, ESLint, Token-Schwelle (889/925). Im Browser: Navigation, Agentenklicks aller sechs Plätze, Kanalfilter und Detailschubladen, Sticky Chat bei vier Agenten, 1280–1920 px sowie Tablet- und Mobilbreite, keine 404 für Bilder oder Routen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
d200d4e930
commit
9ed21e33a7
59 files changed
+2545
-1309
No files matched your search
@@ -10,19 +10,36 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { WORKSPACE_CONFIG, getPageNameFromPath } from '../appShellConfig'
|
||||
import { WorkspaceType } from '../../../domain/enums'
|
||||
import { MY_AGENTS_LABEL, ROUTES } from '../../../lib/constants'
|
||||
import { HOME_NAV_LABEL, MY_AGENTS_LABEL, ROUTES } from '../../../lib/constants'
|
||||
import { AGENT_WORKSPACES } from '../../../lib/agentWorkspaces'
|
||||
|
||||
const supplyNav = WORKSPACE_CONFIG[WorkspaceType.SUPPLY].navItems
|
||||
|
||||
describe('Hauptnavigation der Verwaltung', () => {
|
||||
it('führt «Übersicht» nicht mehr (Runde 5, §2.1)', () => {
|
||||
expect(supplyNav.map(item => item.label)).not.toContain('Übersicht')
|
||||
expect(supplyNav.map(item => item.path)).not.toContain(ROUTES.SUPPLY.LEGACY_DASHBOARD)
|
||||
})
|
||||
|
||||
it('beginnt mit der «Startseite» und führt sie nur einmal', () => {
|
||||
expect(supplyNav[0]?.label).toBe(HOME_NAV_LABEL)
|
||||
expect(supplyNav[0]?.path).toBe(ROUTES.SUPPLY.PROPERTIES)
|
||||
expect(supplyNav.filter(item => item.path === ROUTES.SUPPLY.PROPERTIES)).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('startet den Arbeitsbereich auf der Startseite', () => {
|
||||
expect(WORKSPACE_CONFIG[WorkspaceType.SUPPLY].firstPath).toBe(ROUTES.SUPPLY.PROPERTIES)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Navigationseintrag «Meine Agenten»', () => {
|
||||
it('steht direkt unter «Meine Objekte»', () => {
|
||||
it('steht direkt unter der «Startseite»', () => {
|
||||
const labels = supplyNav.map(item => item.label)
|
||||
const objekte = labels.indexOf('Meine Objekte')
|
||||
const startseite = labels.indexOf(HOME_NAV_LABEL)
|
||||
const agenten = labels.indexOf(MY_AGENTS_LABEL)
|
||||
|
||||
expect(objekte).toBeGreaterThanOrEqual(0)
|
||||
expect(agenten).toBe(objekte + 1)
|
||||
expect(startseite).toBeGreaterThanOrEqual(0)
|
||||
expect(agenten).toBe(startseite + 1)
|
||||
})
|
||||
|
||||
it('führt auf den Basispfad des Funktionsbereichs', () => {
|
||||
@@ -64,6 +81,7 @@ describe('Navigationseintrag «Meine Agenten»', () => {
|
||||
|
||||
describe('Seitentitel aus dem Pfad', () => {
|
||||
it('löst Haupt- und Agentenreiter über die Navigation auf', () => {
|
||||
expect(getPageNameFromPath(ROUTES.SUPPLY.PROPERTIES)).toBe(HOME_NAV_LABEL)
|
||||
expect(getPageNameFromPath(ROUTES.SUPPLY.TEAM)).toBe(MY_AGENTS_LABEL)
|
||||
expect(getPageNameFromPath(ROUTES.SUPPLY.AGENT_FERDI)).toBe('Ferdi')
|
||||
expect(getPageNameFromPath(ROUTES.SUPPLY.AGENT_BRUNO)).toBe('Bruno')
|
||||
|
||||
Reference in new issue
Block a user