summaryrefslogtreecommitdiff
path: root/makima/frontend/src/routes
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-15 00:05:20 +0000
committersoryu <soryu@soryu.co>2026-01-15 01:30:02 +0000
commitb8035a7bc86dfb40af66f80e0564a41b8c6f7ba8 (patch)
tree59223bc7b3ec88c5ced42ed77f419e9fc4501941 /makima/frontend/src/routes
parenteae8e698e89d7e5c8dc5bcdb2dcef61f25295515 (diff)
downloadsoryu-b8035a7bc86dfb40af66f80e0564a41b8c6f7ba8.tar.gz
soryu-b8035a7bc86dfb40af66f80e0564a41b8c6f7ba8.zip
feat(listen): add transcript analysis UI panel
Add UI integration for the transcript analysis feature: - Add TranscriptSaved WebSocket message type to notify client when transcript is saved - Create TranscriptAnalysisPanel component to display analysis results - Shows requirements grouped by category, decisions, action items with priorities - Displays speaker statistics and suggested contract name/description - Provides buttons to create new contract or add to existing contract - Update Listen page to show analysis panel as modal overlay after recording stops - Update useWebSocket hook to handle transcriptSaved message Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima/frontend/src/routes')
-rw-r--r--makima/frontend/src/routes/listen.tsx41
1 files changed, 41 insertions, 0 deletions
diff --git a/makima/frontend/src/routes/listen.tsx b/makima/frontend/src/routes/listen.tsx
index 36c468b..55cf7e6 100644
--- a/makima/frontend/src/routes/listen.tsx
+++ b/makima/frontend/src/routes/listen.tsx
@@ -3,6 +3,7 @@ import { Masthead } from "../components/Masthead";
import { SpeakerPanel } from "../components/listen/SpeakerPanel";
import { TranscriptPanel } from "../components/listen/TranscriptPanel";
import { ControlPanel, type ContractOption } from "../components/listen/ControlPanel";
+import { TranscriptAnalysisPanel } from "../components/listen/TranscriptAnalysisPanel";
import { useMicrophone } from "../hooks/useMicrophone";
import { useWebSocket } from "../hooks/useWebSocket";
import { listContracts } from "../lib/api";
@@ -20,6 +21,12 @@ export default function ListenPage() {
const [contractsLoading, setContractsLoading] = useState(true);
const { session, isAuthenticated } = useAuth();
+ // Saved transcript state for analysis
+ const [savedTranscript, setSavedTranscript] = useState<{
+ fileId: string;
+ contractId: string;
+ } | null>(null);
+
// Fetch contracts on mount
useEffect(() => {
if (!isAuthenticated) {
@@ -61,6 +68,10 @@ export default function ListenPage() {
setIsListening(false);
setActiveSpeaker(null);
},
+ onTranscriptSaved: (fileId, contractId) => {
+ // Store the saved transcript info for analysis
+ setSavedTranscript({ fileId, contractId });
+ },
});
const wsRef = useRef(ws);
@@ -157,8 +168,13 @@ export default function ListenPage() {
ws.disconnect();
setIsListening(false);
setActiveSpeaker(null);
+ setSavedTranscript(null);
}, [mic, ws]);
+ const handleCloseAnalysis = useCallback(() => {
+ setSavedTranscript(null);
+ }, []);
+
const error = ws.error || mic.error;
return (
@@ -194,6 +210,31 @@ export default function ListenPage() {
/>
</div>
</main>
+
+ {/* Transcript Analysis Panel - shown after recording stops and transcript is saved */}
+ {savedTranscript && !isListening && (
+ <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60">
+ <div className="w-full max-w-2xl mx-4 max-h-[90vh] overflow-hidden">
+ <TranscriptAnalysisPanel
+ fileId={savedTranscript.fileId}
+ contractId={savedTranscript.contractId}
+ selectedContractId={selectedContractId}
+ onContractCreated={(response) => {
+ // Refresh contracts list and select the new contract
+ setContracts((prev) => [
+ { id: response.contractId, name: response.contractName },
+ ...prev,
+ ]);
+ setSelectedContractId(response.contractId);
+ }}
+ onContractUpdated={() => {
+ // Keep the current selection
+ }}
+ onClose={handleCloseAnalysis}
+ />
+ </div>
+ </div>
+ )}
</div>
);
}