From 8e67efa0923ce0adfe239fd0f029c5c9d237d672 Mon Sep 17 00:00:00 2001 From: Ida Date: Wed, 27 May 2026 10:07:00 +0200 Subject: [PATCH] feat: Bot antowrten im Vollbild --- src/pages/views/teamsbot/Teamsbot.module.css | 46 +++++ .../views/teamsbot/TeamsbotSessionView.tsx | 159 +++++++++++++----- 2 files changed, 159 insertions(+), 46 deletions(-) diff --git a/src/pages/views/teamsbot/Teamsbot.module.css b/src/pages/views/teamsbot/Teamsbot.module.css index 19414b2..e1b5e03 100644 --- a/src/pages/views/teamsbot/Teamsbot.module.css +++ b/src/pages/views/teamsbot/Teamsbot.module.css @@ -851,6 +851,52 @@ background: var(--surface-alt, #fafafa); } +.panelTitleBar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + padding: 0.75rem 1rem; + border-bottom: 1px solid var(--border-color, #e0e0e0); + background: var(--surface-alt, #fafafa); + flex-shrink: 0; +} + +.panelTitleBar .panelTitle { + padding: 0; + border: none; + background: none; + flex: 1; + min-width: 0; +} + +.panelExpandBtn { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + padding: 0; + border: 1px solid var(--border-color, #e0e0e0); + border-radius: 4px; + background: var(--surface-color, #fff); + color: var(--text-secondary, #666); + cursor: pointer; + flex-shrink: 0; + transition: background 0.15s, color 0.15s, border-color 0.15s; +} + +.panelExpandBtn:hover { + background: var(--surface-alt, #f5f5f5); + color: var(--primary-color, #4A90D9); + border-color: var(--primary-color, #4A90D9); +} + +.popupPanelList { + max-height: none; + padding: 0; +} + .transcriptList, .responseList { flex: 1; diff --git a/src/pages/views/teamsbot/TeamsbotSessionView.tsx b/src/pages/views/teamsbot/TeamsbotSessionView.tsx index 9e8febd..151f73c 100644 --- a/src/pages/views/teamsbot/TeamsbotSessionView.tsx +++ b/src/pages/views/teamsbot/TeamsbotSessionView.tsx @@ -25,6 +25,7 @@ import styles from './Teamsbot.module.css'; import { useLanguage } from '../../../providers/language/LanguageContext'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; +import { Popup } from '../../../components/UiComponents/Popup'; /** * TeamsbotSessionView - Live session view with real-time transcript and bot responses. @@ -54,6 +55,8 @@ export const TeamsbotSessionView: React.FC = () => { const [screenshotsLoading, setScreenshotsLoading] = useState(false); const [screenshotsLoaded, setScreenshotsLoaded] = useState(false); const [screenshotsExpanded, setScreenshotsExpanded] = useState(false); + const [transcriptPopupOpen, setTranscriptPopupOpen] = useState(false); + const [botResponsesPopupOpen, setBotResponsesPopupOpen] = useState(false); const [ttsStatusEvents, setTtsStatusEvents] = useState { return colors[Math.abs(hash) % colors.length]; }; + const _renderExpandIcon = () => ( + + + + ); + + const _renderTranscriptList = (endRef?: React.RefObject) => ( + <> + {transcripts.map((seg) => ( +
+ {_formatTime(seg.timestamp)} + + {seg.speaker || t('Unbekannt')}: + + {seg.text} +
+ ))} + {endRef &&
} + {transcripts.length === 0 && ( +
{t('Noch kein Transkript vorhanden')}
+ )} + + ); + + const _renderBotResponsesList = () => ( + <> + {botResponses.map((r) => ( +
+
+ {r.detectedIntent} + {_formatTime(r.timestamp || '')} +
+
+ {r.responseText || ''} +
+ {r.reasoning && ( +
+ {t('Begründung: {text}', { text: r.reasoning })} +
+ )} + {(r.modelName || r.processingTime != null) && ( +
+ {r.modelName || ''} + {r.processingTime != null && {r.processingTime.toFixed(1)}s} + {r.priceCHF != null && {r.priceCHF.toFixed(4)} CHF} +
+ )} +
+ ))} + {botResponses.length === 0 && ( +
{t('Noch keine Botantworten')}
+ )} + + ); + if (loading) return
{t('Sitzung laden')}
; if (noSessions) return (
@@ -1154,63 +1215,69 @@ export const TeamsbotSessionView: React.FC = () => {
{/* Left: Transcript */}
-

- {t('Transkript ({count} Segmente)', { count: transcripts.length })} -

+
+

+ {t('Transkript ({count} Segmente)', { count: transcripts.length })} +

+ +
- {transcripts.map((seg) => ( -
- {_formatTime(seg.timestamp)} - - {seg.speaker || t('Unbekannt')}: - - {seg.text} -
- ))} -
- {transcripts.length === 0 && ( -
{t('Noch kein Transkript vorhanden')}
- )} + {_renderTranscriptList(transcriptEndRef)}
{/* Right: Bot Responses */}
-

Bot-Antworten ({botResponses.length})

+
+

Bot-Antworten ({botResponses.length})

+ +
- {botResponses.map((r) => ( -
-
- {r.detectedIntent} - {_formatTime(r.timestamp || '')} -
-
- {r.responseText || ''} -
- {r.reasoning && ( -
- {t('Begründung: {text}', { text: r.reasoning })} -
- )} - {(r.modelName || r.processingTime != null) && ( -
- {r.modelName || ''} - {r.processingTime != null && {r.processingTime.toFixed(1)}s} - {r.priceCHF != null && {r.priceCHF.toFixed(4)} CHF} -
- )} -
- ))} - {botResponses.length === 0 && ( -
{t('Noch keine Botantworten')}
- )} + {_renderBotResponsesList()}
+ setTranscriptPopupOpen(false)} + size="fullscreen" + closeOnBackdropClick + > +
+ {_renderTranscriptList()} +
+
+ + setBotResponsesPopupOpen(false)} + size="fullscreen" + closeOnBackdropClick + > +
+ {_renderBotResponsesList()} +
+
+ {/* Summary (for ended sessions) */} {session.summary && (