chordia-ui 3.4.0 → 3.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Timeline.cjs.js +1 -6
- package/dist/Timeline.cjs.js.map +1 -1
- package/dist/Timeline.es.js +129 -597
- package/dist/Timeline.es.js.map +1 -1
- package/dist/TranscriptCard.cjs.js +7 -0
- package/dist/TranscriptCard.cjs.js.map +1 -0
- package/dist/TranscriptCard.es.js +474 -0
- package/dist/TranscriptCard.es.js.map +1 -0
- package/dist/UpdatedInteractionRecording.cjs.js +1 -1
- package/dist/UpdatedInteractionRecording.cjs.js.map +1 -1
- package/dist/UpdatedInteractionRecording.es.js +516 -420
- package/dist/UpdatedInteractionRecording.es.js.map +1 -1
- package/dist/components/UpdatedInteractionDetails.cjs.js +2 -2
- package/dist/components/UpdatedInteractionDetails.cjs.js.map +1 -1
- package/dist/components/UpdatedInteractionDetails.es.js +304 -285
- package/dist/components/UpdatedInteractionDetails.es.js.map +1 -1
- package/dist/components/media.cjs.js +1 -1
- package/dist/components/media.cjs.js.map +1 -1
- package/dist/components/media.es.js +9 -8
- package/dist/components/media.es.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs2.js +1 -1
- package/dist/index.cjs2.js.map +1 -1
- package/dist/index.cjs3.js +2 -2
- package/dist/index.cjs3.js.map +1 -1
- package/dist/index.es.js +53 -52
- package/dist/index.es.js.map +1 -1
- package/dist/index.es2.js +1 -1
- package/dist/index.es2.js.map +1 -1
- package/dist/index.es3.js +11 -4
- package/dist/index.es3.js.map +1 -1
- package/dist/pages/interactionDetails.cjs.js +2 -2
- package/dist/pages/interactionDetails.cjs.js.map +1 -1
- package/dist/pages/interactionDetails.es.js +17 -16
- package/dist/pages/interactionDetails.es.js.map +1 -1
- package/package.json +1 -1
- package/src/components/UpdatedInteractionDetails/UpdatedInteractionDetails.jsx +125 -107
- package/src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx +342 -178
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdatedInteractionRecording.cjs.js","sources":["../src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx"],"sourcesContent":["import { useRef, useState, forwardRef, useImperativeHandle } from 'react';\nimport {\n Play, Pause, RotateCcw, RotateCw,\n ChevronDown,\n AudioLines, PlayCircle, PauseCircle,\n} from 'lucide-react';\nimport Timeline from '../media/Timeline.jsx';\nimport TranscriptCard from '../media/TranscriptCard.jsx';\n\nfunction fmtTime(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\n/* ── Demo data for static preview ── */\nconst DEMO_SEGMENTS = {\n David: [\n { start: 0, end: 0.08 },\n { start: 0.18, end: 0.22 },\n { start: 0.38, end: 0.42 },\n { start: 0.55, end: 0.58 },\n { start: 0.68, end: 0.72 },\n { start: 0.82, end: 0.88 },\n { start: 0.94, end: 1 },\n ],\n Customer: [\n { start: 0.1, end: 0.16 },\n { start: 0.24, end: 0.36 },\n { start: 0.44, end: 0.52 },\n { start: 0.6, end: 0.66 },\n { start: 0.74, end: 0.80 },\n ],\n};\n\nconst DEMO_TRANSCRIPT = [\n { speaker: 'David', type: 'agent', time: '00:04', text: 'Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?' },\n { speaker: 'Customer', type: 'customer', time: '00:12', text: 'Hi, Steve. This is Sandra with Botai Catering.' },\n { speaker: 'David', type: 'agent', time: '00:18', text: 'Hello. How are you?' },\n { speaker: 'Customer', type: 'customer', time: '00:20', text: \"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too.\" },\n { speaker: 'David', type: 'agent', time: '00:21', text: 'Oh, interesting. Okay. Can you swing by with it one of these days?' },\n];\n\n/* ── Component ── */\nconst UpdatedInteractionRecording = forwardRef(function UpdatedInteractionRecording({\n audioUrl,\n timelineSegments = [],\n durationSeconds = 0,\n currentTimeSeconds = 0,\n timelinePlaying = false,\n playbackRate = 1,\n onSeek,\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n audioRef,\n transcript,\n highlightedTurns = new Set(),\n activeTurnIndex,\n activeDemoIndex = 1,\n turnObservations = {},\n setExpandedSignals,\n onTurnPlayPause,\n}, ref) {\n const scrollRef = useRef(null);\n const [demoSeekTime, setDemoSeekTime] = useState(null);\n const [demoRate, setDemoRate] = useState(playbackRate || 1);\n const [demoPlaying, setDemoPlaying] = useState(timelinePlaying);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [activeDemoIdx, setActiveDemoIdx] = useState(activeDemoIndex);\n\n /* Compute which transcript card matches current playback time */\n const computeActiveIdx = (timeSec) => {\n for (let i = DEMO_TRANSCRIPT.length - 1; i >= 0; i--) {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[i].time);\n if (timeSec >= turnTime) return i;\n }\n return 0;\n };\n\n const parseTimeStr = (timeStr) => {\n if (!timeStr) return 0;\n const parts = timeStr.split(':').map(Number);\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n };\n\n const SPEED_OPTIONS = [1, 1.25, 1.5, 2];\n const isDemo = !audioUrl;\n const activeRate = isDemo ? demoRate : playbackRate;\n const activePlaying = isDemo ? demoPlaying : timelinePlaying;\n\n /* Expose seekTo for parent to call via ref */\n useImperativeHandle(ref, () => ({\n seekTo: (timeSec) => {\n handleSeek(timeSec);\n setDemoPlaying(true);\n // Scroll to matching transcript card\n const idx = computeActiveIdx(timeSec);\n setActiveDemoIdx(idx);\n setTimeout(() => {\n const cards = scrollRef.current?.children;\n if (cards?.[idx]) {\n cards[idx].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 50);\n },\n }));\n\n /* Handle seek — updates local demo state or calls parent onSeek */\n const handleSeek = (timeSeconds) => {\n const clamped = Math.max(0, Math.min(timeSeconds, durationSeconds || 156));\n if (onSeek) onSeek(clamped);\n setDemoSeekTime(clamped);\n setActiveDemoIdx(computeActiveIdx(clamped));\n };\n\n const handleTogglePlay = () => {\n if (onTogglePlay) onTogglePlay();\n else setDemoPlaying((prev) => !prev);\n };\n\n const handleSeekBack = () => {\n if (onSeekBack) onSeekBack();\n else handleSeek(Math.max(0, (demoSeekTime ?? 0) - 10));\n };\n\n const handleSeekForward = () => {\n if (onSeekForward) onSeekForward();\n else {\n const demoDur = durationSeconds || 156;\n handleSeek(Math.min(demoDur, (demoSeekTime ?? 0) + 10));\n }\n };\n\n const handleSetRate = (rate) => {\n if (onSetPlaybackRate) onSetPlaybackRate(rate);\n setDemoRate(rate);\n setShowSpeedMenu(false);\n };\n\n /* Handle transcript card play/pause */\n const handleDemoTurnPlayPause = (idx) => {\n if (activeDemoIdx === idx && demoPlaying) {\n setDemoPlaying(false);\n } else {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[idx]?.time);\n setActiveDemoIdx(idx);\n setDemoPlaying(true);\n handleSeek(turnTime);\n }\n };\n\n /* transcript turn builder */\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const fmt = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n return `${fmt(startMs)}\\u2013${endMs != null ? fmt(endMs) : fmt(startMs)}`;\n };\n\n const turns = transcript?.messages?.length\n ? transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: timelinePlaying && activeTurnIndex === i\n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map((obs) => ({\n ...obs,\n onClick: () => {\n setExpandedSignals?.((prev) => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }))\n : null;\n\n const demoDuration = durationSeconds || 156;\n const effectiveTime = demoSeekTime != null ? demoSeekTime : (durationSeconds > 0 ? currentTimeSeconds : 0);\n const progress = demoDuration > 0 ? (effectiveTime / demoDuration) * 100 : 0;\n const demoCurrentTime = Math.round(effectiveTime);\n\n return (\n <div style={{\n display: 'flex',\n padding: 24,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 24,\n borderRadius: 8,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n }}>\n\n {/* ════════════════════════════════════════\n RECORDING SECTION\n ════════════════════════════════════════ */}\n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 16 }}>\n\n {/* ── Row 1: Title + Controls — Figma: Frame 35, horizontal, space-between, center ── */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24 }}>\n <span style={{\n fontSize: 15, fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n Recording\n </span>\n\n {/* Frame 34: controls — horizontal, gap: 12, center */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flex: 1, justifyContent: 'center' }}>\n {/* Skip back 10s */}\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n <button onClick={handleSeekBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCcw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n\n {/* Play / Pause — 32x32 dark circle */}\n <button onClick={handleTogglePlay} style={{\n background: 'var(--Grey-Strong, #2E3236)',\n border: 'none', cursor: 'pointer',\n width: 32, height: 32, borderRadius: 48,\n padding: 0,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {activePlaying\n ? <Pause size={14} color=\"#FFF\" fill=\"#FFF\" />\n : <Play size={14} color=\"#FFF\" fill=\"#FFF\" strokeWidth={1.5} style={{ marginLeft: 2 }} />\n }\n </button>\n\n {/* Skip forward 10s */}\n <button onClick={handleSeekForward} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n </div>\n\n {/* Speed pill with dropdown */}\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => setShowSpeedMenu((prev) => !prev)}\n style={{\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 20,\n padding: '0 5px 0 10px',\n height: 24,\n minWidth: 56,\n cursor: 'pointer',\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,\n }}\n >\n {activeRate}x\n <ChevronDown size={12} color=\"#808183\" />\n </button>\n\n {showSpeedMenu && (\n <div style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(0,0,0,0.1)',\n zIndex: 10,\n overflow: 'hidden',\n minWidth: 80,\n }}>\n {SPEED_OPTIONS.map((speed) => (\n <button\n key={speed}\n onClick={() => handleSetRate(speed)}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n border: 'none',\n background: activeRate === speed ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: activeRate === speed ? 600 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n textAlign: 'left',\n }}\n >\n {speed}x\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2: Progress bar ── */}\n {audioUrl ? (\n <>\n <Timeline\n segments={timelineSegments}\n durationSeconds={durationSeconds}\n currentTimeSeconds={currentTimeSeconds}\n onSeek={onSeek}\n showControls={false}\n hasRecording\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n />\n <audio ref={audioRef} preload=\"none\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n </>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Time label + scrubber bar */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{\n fontSize: 13, fontWeight: 600,\n color: progress > 0 ? 'var(--Green-Primary, #00925F)' : 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {fmtTime(demoCurrentTime)}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const pct = Math.max(0, Math.min(1, clickX / rect.width));\n const seekTime = pct * demoDuration;\n handleSeek(seekTime);\n }}\n style={{\n flex: 1, height: 16,\n position: 'relative',\n display: 'flex', alignItems: 'center',\n cursor: 'pointer',\n }}\n >\n {/* Background track — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n pointerEvents: 'none',\n }} />\n {/* Played portion — Figma: #00925F, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, top: '50%',\n transform: 'translateY(-50%)',\n width: `${progress}%`,\n height: 4, borderRadius: 2,\n background: 'var(--Green-Primary, #00925F)',\n pointerEvents: 'none',\n }} />\n {/* Scrubber handle — Figma ellipse */}\n <svg\n width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: 'absolute',\n left: `${progress}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n }}\n >\n <path\n d=\"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z\"\n fill=\"#FFF\"\n stroke=\"#00925F\"\n strokeWidth=\"2\"\n />\n </svg>\n </div>\n </div>\n\n {/* ── Row 3: Speaker timeline bars + playback indicator ── */}\n <div style={{ position: 'relative', paddingBottom: 30, cursor: 'pointer' }}>\n {['David', 'Customer'].map((speaker, rowIdx) => (\n <div key={speaker} style={{\n display: 'flex', alignItems: 'center', gap: 8,\n height: 20,\n marginBottom: rowIdx === 0 ? 4 : 0,\n }}>\n <span style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {speaker}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n handleSeek(pct * demoDuration);\n }}\n style={{\n flex: 1, height: 6,\n position: 'relative', borderRadius: 3,\n cursor: 'pointer',\n }}\n >\n {/* Thin baseline — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n top: '50%', transform: 'translateY(-50%)',\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n }} />\n {/* Speech segments */}\n {DEMO_SEGMENTS[speaker].map((seg, i) => (\n <div key={i} style={{\n position: 'absolute',\n left: `${seg.start * 100}%`,\n width: `${(seg.end - seg.start) * 100}%`,\n top: 0, bottom: 0, borderRadius: 3,\n background: speaker === 'David'\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n }} />\n ))}\n </div>\n </div>\n ))}\n\n {/* ── Playback position: dotted line + avatar + time tooltip ── */}\n <div style={{\n position: 'absolute',\n left: 68, /* 60 label + 8 gap */\n right: 0,\n top: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}>\n {/* Dotted vertical line */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n top: 0,\n height: 44, /* spans both rows */\n transform: 'translateX(-50%)',\n borderLeft: '1.5px dashed var(--Grey-Muted, #808183)',\n opacity: 0.5,\n }} />\n\n {/* Time tooltip — Figma: Frame 30, bg=#2E3236, pad 4 6, r=4, 14px/600/#FFF */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n bottom: 0,\n transform: 'translateX(-50%)',\n background: 'var(--Grey-Strong, #2E3236)',\n color: 'var(--Grey-White, #FFF)',\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n padding: '4px 6px',\n borderRadius: 4,\n whiteSpace: 'nowrap',\n }}>\n {fmtTime(demoCurrentTime)}\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* ════════════════════════════════════════\n TRANSCRIPT SECTION\n ════════════════════════════════════════ */}\n {/* Figma: Frame 49, vertical, gap: 16 */}\n <div style={{\n width: '100%',\n display: 'flex', flexDirection: 'column', gap: 16,\n }}>\n {/* ── Header: Transcript ── */}\n <div style={{\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n paddingBottom: 16,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n Transcript\n </span>\n </div>\n\n {/* ── Cards ── */}\n {turns ? (\n <div id=\"transcript-container\" ref={scrollRef} style={{ maxHeight: 600, overflowY: 'auto' }}>\n <TranscriptCard\n turns={turns}\n audioUrl={audioUrl}\n activeTurnIndex={activeTurnIndex}\n autoScrollActiveTurn={timelinePlaying}\n isExternalPlaying={timelinePlaying}\n onTurnPlayPause={onTurnPlayPause}\n />\n </div>\n ) : (\n <div ref={scrollRef} style={{\n display: 'flex', flexDirection: 'column',\n maxHeight: 600, overflowY: 'auto',\n }}>\n {DEMO_TRANSCRIPT.map((card, i) => {\n const isActive = i === activeDemoIdx && demoPlaying;\n const isCustomer = card.type === 'customer';\n\n return (\n <div key={i} style={{\n display: 'flex',\n padding: 16,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 16,\n alignSelf: 'stretch',\n borderTop: i > 0 ? '1px solid var(--Grey-absent, #D9D9D9)' : 'none',\n background: isActive ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n }}>\n {/* Frame 40: Speaker name + time — horizontal, space-between, center */}\n <div style={{\n display: 'flex', alignItems: 'center',\n justifyContent: 'space-between', width: '100%',\n gap: 8,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n color: isCustomer ? 'var(--Grey-Strong, #2E3236)' : 'var(--Grey-Muted, #808183)',\n }}>\n {card.speaker}\n </span>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {isActive && (\n <>\n <AudioLines size={12} color=\"#2E3236\" />\n <AudioLines size={12} color=\"#2E3236\" />\n </>\n )}\n <span style={{\n fontSize: 13, fontWeight: 400,\n lineHeight: 1.2,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n {card.time}\n </span>\n </div>\n </div>\n\n {/* Frame 39: Play/Pause icon + text — horizontal, gap: 8 */}\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, width: '100%' }}>\n <button\n onClick={() => handleDemoTurnPlayPause(i)}\n style={{\n background: 'none', border: 'none',\n cursor: 'pointer', padding: 0,\n flexShrink: 0,\n display: 'flex',\n }}\n >\n {isActive ? (\n <PauseCircle size={17} color=\"#2E3236\" strokeWidth={1.5} />\n ) : (\n <PlayCircle size={17} color=\"#808183\" strokeWidth={1} />\n )}\n </button>\n <p style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n margin: 0,\n flex: 1,\n }}>\n {card.text}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n});\n\nexport default UpdatedInteractionRecording;\n"],"names":["fmtTime","seconds","m","s","DEMO_SEGMENTS","DEMO_TRANSCRIPT","UpdatedInteractionRecording","forwardRef","audioUrl","timelineSegments","durationSeconds","currentTimeSeconds","timelinePlaying","playbackRate","onSeek","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","audioRef","transcript","highlightedTurns","activeTurnIndex","activeDemoIndex","turnObservations","setExpandedSignals","onTurnPlayPause","ref","scrollRef","useRef","demoSeekTime","setDemoSeekTime","useState","demoRate","setDemoRate","demoPlaying","setDemoPlaying","showSpeedMenu","setShowSpeedMenu","activeDemoIdx","setActiveDemoIdx","computeActiveIdx","timeSec","i","turnTime","parseTimeStr","timeStr","parts","SPEED_OPTIONS","isDemo","activeRate","activePlaying","useImperativeHandle","handleSeek","idx","cards","_a","timeSeconds","clamped","handleTogglePlay","prev","handleSeekBack","handleSeekForward","handleSetRate","rate","handleDemoTurnPlayPause","formatTimeRange","startMs","endMs","fmt","ms","minutes","turns","_b","obs","el","demoDuration","effectiveTime","progress","demoCurrentTime","jsxs","jsx","RotateCcw","Pause","Play","RotateCw","ChevronDown","speed","Fragment","Timeline","e","rect","clickX","seekTime","speaker","rowIdx","pct","seg","TranscriptCard","card","isActive","isCustomer","AudioLines","PauseCircle","PlayCircle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UpdatedInteractionRecording.cjs.js","sources":["../src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx"],"sourcesContent":["import { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport {\n Play, Pause, RotateCcw, RotateCw,\n ChevronDown,\n AudioLines, PlayCircle, PauseCircle,\n FileSignal,\n} from 'lucide-react';\nimport Timeline from '../media/Timeline.jsx';\n\nfunction fmtTime(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\n/* ── Demo data for static preview ── */\nconst DEMO_SEGMENTS = {\n Agent: [\n { start: 0, end: 0.08 },\n { start: 0.18, end: 0.22 },\n { start: 0.38, end: 0.42 },\n { start: 0.55, end: 0.58 },\n { start: 0.68, end: 0.72 },\n { start: 0.82, end: 0.88 },\n { start: 0.94, end: 1 },\n ],\n Customer: [\n { start: 0.1, end: 0.16 },\n { start: 0.24, end: 0.36 },\n { start: 0.44, end: 0.52 },\n { start: 0.6, end: 0.66 },\n { start: 0.74, end: 0.80 },\n ],\n};\n\nconst DEMO_TRANSCRIPT = [\n { speaker: 'Agent', type: 'agent', time: '00:04', text: 'Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?' },\n { speaker: 'Customer', type: 'customer', time: '00:12', text: 'Hi, Steve. This is Sandra with Botai Catering.' },\n { speaker: 'Agent', type: 'agent', time: '00:18', text: 'Hello. How are you?' },\n { speaker: 'Customer', type: 'customer', time: '00:20', text: \"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too.\" },\n { speaker: 'Agent', type: 'agent', time: '00:21', text: 'Oh, interesting. Okay. Can you swing by with it one of these days?' },\n];\n\nconst SPEED_OPTIONS = [1, 1.25, 1.5, 2];\n\nfunction parseTimeStr(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(':').map(Number);\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n}\n\n/* ── Component ── */\nconst UpdatedInteractionRecording = forwardRef(function UpdatedInteractionRecording({\n audioUrl,\n timelineSegments = [],\n durationSeconds = 0,\n // Parent-managed audio props (optional — if not provided, component manages its own audio)\n currentTimeSeconds: externalCurrentTime,\n timelinePlaying: externalPlaying,\n playbackRate: externalRate,\n onSeek: externalOnSeek,\n onTogglePlay: externalOnTogglePlay,\n onSeekBack: externalOnSeekBack,\n onSeekForward: externalOnSeekForward,\n onSetPlaybackRate: externalOnSetPlaybackRate,\n audioRef: externalAudioRef,\n // Speaker names\n agentName = 'Agent',\n customerName = 'Customer',\n // Transcript props\n transcript,\n highlightedTurns = new Set(),\n activeTurnIndex,\n activeDemoIndex = 1,\n turnObservations = {},\n setExpandedSignals,\n onTurnPlayPause,\n}, ref) {\n const scrollRef = useRef(null);\n const internalAudioRef = useRef(null);\n const animFrameRef = useRef(null);\n\n // Internal audio state (used when audioUrl is provided but parent doesn't manage playback)\n const [internalPlaying, setInternalPlaying] = useState(false);\n const [internalCurrentTime, setInternalCurrentTime] = useState(0);\n const [internalDuration, setInternalDuration] = useState(0);\n const [internalRate, setInternalRate] = useState(1);\n\n // Demo state (used when no audioUrl)\n const [demoSeekTime, setDemoSeekTime] = useState(null);\n const [demoRate, setDemoRate] = useState(1);\n const [demoPlaying, setDemoPlaying] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [activeDemoIdx, setActiveDemoIdx] = useState(activeDemoIndex);\n\n // Determine control mode\n const parentManaged = !!externalAudioRef;\n const isDemo = !audioUrl;\n const selfManaged = audioUrl && !parentManaged;\n\n // Unified state\n const activePlaying = isDemo ? demoPlaying : (parentManaged ? (externalPlaying ?? false) : internalPlaying);\n const activeCurrentTime = isDemo ? (demoSeekTime ?? 0) : (parentManaged ? (externalCurrentTime ?? 0) : internalCurrentTime);\n const activeRate = isDemo ? demoRate : (parentManaged ? (externalRate ?? 1) : internalRate);\n const activeDuration = isDemo ? (durationSeconds || 156) : (parentManaged ? durationSeconds : (internalDuration || durationSeconds || 0));\n const audioRefToUse = parentManaged ? externalAudioRef : internalAudioRef;\n\n /* ── Internal audio time tracking via requestAnimationFrame ── */\n const startTimeTracking = useCallback(() => {\n const tick = () => {\n const audio = internalAudioRef.current;\n if (audio) setInternalCurrentTime(audio.currentTime);\n animFrameRef.current = requestAnimationFrame(tick);\n };\n animFrameRef.current = requestAnimationFrame(tick);\n }, []);\n\n const stopTimeTracking = useCallback(() => {\n if (animFrameRef.current) {\n cancelAnimationFrame(animFrameRef.current);\n animFrameRef.current = null;\n }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => () => stopTimeTracking(), [stopTimeTracking]);\n\n // Wire up internal audio element events\n useEffect(() => {\n if (!selfManaged) return;\n const audio = internalAudioRef.current;\n if (!audio) return;\n const onLoaded = () => setInternalDuration(audio.duration || 0);\n const onEnded = () => { setInternalPlaying(false); stopTimeTracking(); };\n audio.addEventListener('loadedmetadata', onLoaded);\n audio.addEventListener('ended', onEnded);\n return () => {\n audio.removeEventListener('loadedmetadata', onLoaded);\n audio.removeEventListener('ended', onEnded);\n };\n }, [selfManaged, stopTimeTracking]);\n\n /* Compute which transcript card matches current playback time */\n const computeActiveIdx = (timeSec) => {\n for (let i = DEMO_TRANSCRIPT.length - 1; i >= 0; i--) {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[i].time);\n if (timeSec >= turnTime) return i;\n }\n return 0;\n };\n\n /* ── Unified handlers ── */\n const handleSeek = (timeSeconds) => {\n const dur = activeDuration || 156;\n const clamped = Math.max(0, Math.min(timeSeconds, dur));\n\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.currentTime = clamped;\n setInternalCurrentTime(clamped);\n } else if (parentManaged && externalOnSeek) {\n externalOnSeek(clamped);\n }\n\n // Always update demo state for UI\n setDemoSeekTime(clamped);\n setActiveDemoIdx(computeActiveIdx(clamped));\n };\n\n const handleTogglePlay = () => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (!audio) return;\n if (internalPlaying) {\n audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n } else {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else if (parentManaged && externalOnTogglePlay) {\n externalOnTogglePlay();\n } else {\n // Demo mode\n setDemoPlaying((prev) => !prev);\n }\n };\n\n const handleSeekBack = () => {\n if (parentManaged && externalOnSeekBack) externalOnSeekBack();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n handleSeek(Math.max(0, cur - 10));\n }\n };\n\n const handleSeekForward = () => {\n if (parentManaged && externalOnSeekForward) externalOnSeekForward();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n const dur = activeDuration || 156;\n handleSeek(Math.min(dur, cur + 10));\n }\n };\n\n const handleSetRate = (rate) => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.playbackRate = rate;\n setInternalRate(rate);\n } else if (parentManaged && externalOnSetPlaybackRate) {\n externalOnSetPlaybackRate(rate);\n }\n setDemoRate(rate);\n setShowSpeedMenu(false);\n };\n\n /* Expose seekTo for parent to call via ref (e.g. from Signals \"Show in transcript\") */\n useImperativeHandle(ref, () => ({\n seekTo: (timeSec) => {\n handleSeek(timeSec);\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else {\n setDemoPlaying(true);\n }\n const idx = computeActiveIdx(timeSec);\n setActiveDemoIdx(idx);\n setTimeout(() => {\n const cards = scrollRef.current?.children;\n if (cards?.[idx]) {\n cards[idx].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 50);\n },\n }));\n\n /* Handle transcript card play/pause */\n const handleDemoTurnPlayPause = (idx) => {\n if (activeDemoIdx === idx && activePlaying) {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n }\n setDemoPlaying(false);\n } else {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[idx]?.time);\n setActiveDemoIdx(idx);\n handleSeek(turnTime);\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.currentTime = turnTime;\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n }\n setDemoPlaying(true);\n }\n };\n\n /* transcript turn builder */\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const fmt = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n return `${fmt(startMs)}\\u2013${endMs != null ? fmt(endMs) : fmt(startMs)}`;\n };\n\n const turns = transcript?.messages?.length\n ? transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: activePlaying && activeTurnIndex === i\n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map((obs) => ({\n ...obs,\n onClick: () => {\n setExpandedSignals?.((prev) => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }))\n : null;\n\n // Computed display values\n const effectiveTime = isDemo ? (demoSeekTime ?? 0) : activeCurrentTime;\n const effectiveDuration = activeDuration || 156;\n const progress = effectiveDuration > 0 ? (effectiveTime / effectiveDuration) * 100 : 0;\n const displayTime = Math.round(effectiveTime);\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n }}>\n {/* ── \"Recording\" title with icon — outside the card, matches Signals style ── */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n width: '100%',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: 'var(--surface-hover, #F3F7F7)',\n flexShrink: 0,\n }}>\n <FileSignal size={20} color=\"#2E3236\" strokeWidth={1.5} />\n </div>\n <span style={{\n fontSize: 15,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n }}>\n Recording\n </span>\n </div>\n\n {/* ── Card with border ── */}\n <div style={{\n display: 'flex',\n padding: 24,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 24,\n borderRadius: 8,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n }}>\n\n {/* ════════════════════════════════════════\n RECORDING CONTROLS\n ════════════════════════════════════════ */}\n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 16 }}>\n\n {/* ── \"Agent / Customer\" + Controls — horizontal, space-between, center ── */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24 }}>\n <span style={{\n fontSize: 14, fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n {agentName} / {customerName}\n </span>\n\n {/* Controls — horizontal, gap: 12, center */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n {/* Skip back 10s */}\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n <button onClick={handleSeekBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCcw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n\n {/* Play / Pause — 32x32 dark circle */}\n <button onClick={handleTogglePlay} style={{\n background: 'var(--Grey-Strong, #2E3236)',\n border: 'none', cursor: 'pointer',\n width: 32, height: 32, borderRadius: 48,\n padding: 0,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {activePlaying\n ? <Pause size={14} color=\"#FFF\" fill=\"#FFF\" />\n : <Play size={14} color=\"#FFF\" fill=\"#FFF\" strokeWidth={1.5} style={{ marginLeft: 2 }} />\n }\n </button>\n\n {/* Skip forward 10s */}\n <button onClick={handleSeekForward} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n </div>\n\n {/* Speed pill with dropdown */}\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => setShowSpeedMenu((prev) => !prev)}\n style={{\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 20,\n padding: '0 5px 0 10px',\n height: 24,\n minWidth: 56,\n cursor: 'pointer',\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,\n }}\n >\n {activeRate}x\n <ChevronDown size={12} color=\"#808183\" />\n </button>\n\n {showSpeedMenu && (\n <div style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(0,0,0,0.1)',\n zIndex: 10,\n overflow: 'hidden',\n minWidth: 80,\n }}>\n {SPEED_OPTIONS.map((speed) => (\n <button\n key={speed}\n onClick={() => handleSetRate(speed)}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n border: 'none',\n background: activeRate === speed ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: activeRate === speed ? 600 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n textAlign: 'left',\n }}\n >\n {speed}x\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2: Progress bar ── */}\n {audioUrl && parentManaged ? (\n <>\n <Timeline\n segments={timelineSegments}\n durationSeconds={durationSeconds}\n currentTimeSeconds={externalCurrentTime}\n onSeek={externalOnSeek}\n showControls={false}\n hasRecording\n timelinePlaying={externalPlaying}\n playbackRate={externalRate}\n />\n <audio ref={externalAudioRef} preload=\"none\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n </>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Time label + scrubber bar */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{\n fontSize: 13, fontWeight: 600,\n color: progress > 0 ? 'var(--Green-Primary, #00925F)' : 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {fmtTime(displayTime)}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const pct = Math.max(0, Math.min(1, clickX / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 16,\n position: 'relative',\n display: 'flex', alignItems: 'center',\n cursor: 'pointer',\n }}\n >\n {/* Background track — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n pointerEvents: 'none',\n }} />\n {/* Played portion — Figma: #00925F, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, top: '50%',\n transform: 'translateY(-50%)',\n width: `${progress}%`,\n height: 4, borderRadius: 2,\n background: 'var(--Green-Primary, #00925F)',\n pointerEvents: 'none',\n }} />\n {/* Scrubber handle — Figma ellipse */}\n <svg\n width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: 'absolute',\n left: `${progress}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n }}\n >\n <path\n d=\"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z\"\n fill=\"#FFF\"\n stroke=\"#00925F\"\n strokeWidth=\"2\"\n />\n </svg>\n </div>\n </div>\n\n {/* ── Row 3: Speaker timeline bars + playback indicator ── */}\n <div style={{ position: 'relative', paddingBottom: 30, cursor: 'pointer' }}>\n {['Agent', 'Customer'].map((speaker, rowIdx) => (\n <div key={speaker} style={{\n display: 'flex', alignItems: 'center', gap: 8,\n height: 20,\n marginBottom: rowIdx === 0 ? 4 : 0,\n }}>\n <span style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {speaker}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 6,\n position: 'relative', borderRadius: 3,\n cursor: 'pointer',\n }}\n >\n {/* Thin baseline — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n top: '50%', transform: 'translateY(-50%)',\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n }} />\n {/* Speech segments */}\n {DEMO_SEGMENTS[speaker].map((seg, i) => (\n <div key={i} style={{\n position: 'absolute',\n left: `${seg.start * 100}%`,\n width: `${(seg.end - seg.start) * 100}%`,\n top: 0, bottom: 0, borderRadius: 3,\n background: speaker === 'Agent'\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n }} />\n ))}\n </div>\n </div>\n ))}\n\n {/* ── Playback position: dotted line + time tooltip ── */}\n <div style={{\n position: 'absolute',\n left: 68, /* 60 label + 8 gap */\n right: 0,\n top: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}>\n {/* Dotted vertical line */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n top: 0,\n height: 44, /* spans both rows */\n transform: 'translateX(-50%)',\n borderLeft: '1.5px dashed var(--Grey-Muted, #808183)',\n opacity: 0.5,\n }} />\n\n {/* Time tooltip — Figma: Frame 30, bg=#2E3236, pad 4 6, r=4, 14px/600/#FFF */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n bottom: 0,\n transform: 'translateX(-50%)',\n background: 'var(--Grey-Strong, #2E3236)',\n color: 'var(--Grey-White, #FFF)',\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n padding: '4px 6px',\n borderRadius: 4,\n whiteSpace: 'nowrap',\n }}>\n {fmtTime(displayTime)}\n </div>\n </div>\n </div>\n\n {/* Hidden audio element for self-managed mode */}\n {selfManaged && (\n <audio ref={internalAudioRef} preload=\"auto\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n )}\n </div>\n )}\n </div>\n\n {/* ════════════════════════════════════════\n TRANSCRIPT SECTION\n ════════════════════════════════════════ */}\n {/* Figma: Frame 49, vertical, gap: 16 */}\n <div style={{\n width: '100%',\n display: 'flex', flexDirection: 'column', gap: 16,\n }}>\n {/* ── Header: Transcript ── */}\n <div style={{\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n paddingBottom: 16,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n Transcript\n </span>\n </div>\n\n {/* ── Cards — V4 style for both real and demo data ── */}\n <div id=\"transcript-container\" ref={scrollRef} style={{\n display: 'flex', flexDirection: 'column',\n maxHeight: 600, overflowY: 'auto',\n }}>\n {(turns || DEMO_TRANSCRIPT.map((card) => ({\n actor: card.speaker,\n actorType: card.type,\n text: card.text,\n timeRange: card.time,\n }))).map((card, i) => {\n const isRealData = !!turns;\n const isActive = isRealData\n ? (activePlaying && activeTurnIndex === i)\n : (i === activeDemoIdx && activePlaying);\n const isCustomer = (card.actorType || card.type) === 'customer';\n\n return (\n <div key={i} style={{\n display: 'flex',\n padding: 16,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 16,\n alignSelf: 'stretch',\n borderTop: i > 0 ? '1px solid var(--Grey-absent, #D9D9D9)' : 'none',\n background: isActive ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n }}>\n {/* Speaker name + time */}\n <div style={{\n display: 'flex', alignItems: 'center',\n justifyContent: 'space-between', width: '100%',\n gap: 8,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n color: isCustomer ? 'var(--Grey-Strong, #2E3236)' : 'var(--Grey-Muted, #808183)',\n }}>\n {card.actor}\n </span>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {isActive && (\n <>\n <AudioLines size={12} color=\"#2E3236\" />\n <AudioLines size={12} color=\"#2E3236\" />\n </>\n )}\n <span style={{\n fontSize: 13, fontWeight: 400,\n lineHeight: 1.2,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n {card.timeRange}\n </span>\n </div>\n </div>\n\n {/* Play/Pause icon + text */}\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, width: '100%' }}>\n <button\n onClick={() => {\n if (isRealData && onTurnPlayPause) {\n onTurnPlayPause(card, i);\n } else {\n handleDemoTurnPlayPause(i);\n }\n }}\n style={{\n background: 'none', border: 'none',\n cursor: 'pointer', padding: 0,\n flexShrink: 0,\n display: 'flex',\n }}\n >\n {isActive ? (\n <PauseCircle size={17} color=\"#2E3236\" strokeWidth={1.5} />\n ) : (\n <PlayCircle size={17} color=\"#808183\" strokeWidth={1} />\n )}\n </button>\n <p style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n margin: 0,\n flex: 1,\n }}>\n {card.text}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>{/* end card */}\n </div>\n );\n});\n\nexport default UpdatedInteractionRecording;\n"],"names":["fmtTime","seconds","m","s","DEMO_SEGMENTS","DEMO_TRANSCRIPT","SPEED_OPTIONS","parseTimeStr","timeStr","parts","UpdatedInteractionRecording","forwardRef","audioUrl","timelineSegments","durationSeconds","externalCurrentTime","externalPlaying","externalRate","externalOnSeek","externalOnTogglePlay","externalOnSeekBack","externalOnSeekForward","externalOnSetPlaybackRate","externalAudioRef","agentName","customerName","transcript","highlightedTurns","activeTurnIndex","activeDemoIndex","turnObservations","setExpandedSignals","onTurnPlayPause","ref","scrollRef","useRef","internalAudioRef","animFrameRef","internalPlaying","setInternalPlaying","useState","internalCurrentTime","setInternalCurrentTime","internalDuration","setInternalDuration","internalRate","setInternalRate","demoSeekTime","setDemoSeekTime","demoRate","setDemoRate","demoPlaying","setDemoPlaying","showSpeedMenu","setShowSpeedMenu","activeDemoIdx","setActiveDemoIdx","parentManaged","isDemo","selfManaged","activePlaying","activeCurrentTime","activeRate","activeDuration","startTimeTracking","useCallback","tick","audio","stopTimeTracking","useEffect","onLoaded","onEnded","computeActiveIdx","timeSec","turnTime","handleSeek","timeSeconds","clamped","handleTogglePlay","prev","handleSeekBack","handleSeekForward","handleSetRate","rate","useImperativeHandle","idx","cards","_a","handleDemoTurnPlayPause","formatTimeRange","startMs","endMs","fmt","ms","minutes","turns","_b","obs","el","effectiveTime","effectiveDuration","progress","displayTime","jsxs","jsx","FileSignal","RotateCcw","Pause","Play","RotateCw","ChevronDown","speed","Fragment","Timeline","rect","clickX","pct","speaker","rowIdx","e","seg","i","card","isRealData","isActive","isCustomer","AudioLines","PauseCircle","PlayCircle"],"mappings":"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"}
|