From 20009aed53d8864c9204d43a17895168a777d2cc Mon Sep 17 00:00:00 2001
From: Ilan Bigio <ilan@openai.com>
Date: Mon, 16 Dec 2024 13:06:08 -0800
Subject: Initial commit

---
 webapp/components/transcript.tsx | 104 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 webapp/components/transcript.tsx

(limited to 'webapp/components/transcript.tsx')

diff --git a/webapp/components/transcript.tsx b/webapp/components/transcript.tsx
new file mode 100644
index 0000000..bc2ecbd
--- /dev/null
+++ b/webapp/components/transcript.tsx
@@ -0,0 +1,104 @@
+import React, { useEffect, useRef } from "react";
+import { Card, CardContent } from "@/components/ui/card";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { Bot, Phone, MessageSquare, Wrench } from "lucide-react";
+import { Item } from "@/components/types";
+
+type TranscriptProps = {
+  items: Item[];
+};
+
+const Transcript: React.FC<TranscriptProps> = ({ items }) => {
+  const scrollRef = useRef<HTMLDivElement>(null);
+
+  useEffect(() => {
+    scrollRef.current?.scrollIntoView({ behavior: "smooth" });
+  }, [items]);
+
+  // Show messages, function calls, and function call outputs in the transcript
+  const transcriptItems = items.filter(
+    (it) =>
+      it.type === "message" ||
+      it.type === "function_call" ||
+      it.type === "function_call_output"
+  );
+
+  return (
+    <Card className="h-full flex flex-col overflow-hidden">
+      <CardContent className="flex-1 h-full min-h-0 overflow-hidden flex flex-col p-0">
+        {transcriptItems.length === 0 && (
+          <div className="flex flex-1 h-full items-center justify-center mt-36">
+            <div className="flex flex-col items-center gap-3 justify-center h-full">
+              <div className="h-[140px] w-[140px] rounded-full bg-secondary/20 flex items-center justify-center">
+                <MessageSquare className="h-16 w-16 text-foreground/10 bg-transparent" />
+              </div>
+              <div className="text-center space-y-1">
+                <p className="text-sm font-medium text-foreground/60">
+                  No messages yet
+                </p>
+                <p className="text-sm text-muted-foreground">
+                  Start a call to see the transcript
+                </p>
+              </div>
+            </div>
+          </div>
+        )}
+        <ScrollArea className="h-full">
+          <div className="flex flex-col gap-6 p-6">
+            {transcriptItems.map((msg, i) => {
+              const isUser = msg.role === "user";
+              const isTool = msg.role === "tool";
+              // Default to assistant if not user or tool
+              const Icon = isUser ? Phone : isTool ? Wrench : Bot;
+
+              // Combine all text parts into a single string for display
+              const displayText = msg.content
+                ? msg.content.map((c) => c.text).join("")
+                : "";
+
+              return (
+                <div key={i} className="flex items-start gap-3">
+                  <div
+                    className={`shrink-0 w-8 h-8 rounded-full flex items-center justify-center border ${
+                      isUser
+                        ? "bg-background border-border"
+                        : isTool
+                        ? "bg-secondary border-secondary"
+                        : "bg-secondary border-secondary"
+                    }`}
+                  >
+                    <Icon className="h-4 w-4" />
+                  </div>
+                  <div className="flex-1 min-w-0">
+                    <div className="flex items-center gap-2 mb-1.5">
+                      <span
+                        className={`text-sm font-medium ${
+                          isUser ? "text-muted-foreground" : "text-foreground"
+                        }`}
+                      >
+                        {isUser
+                          ? "Caller"
+                          : isTool
+                          ? "Tool Response"
+                          : "Assistant"}
+                      </span>
+                      <span className="text-xs text-muted-foreground">
+                        {msg.timestamp}
+                      </span>
+                    </div>
+                    <p className="text-sm text-muted-foreground leading-relaxed break-words">
+                      {displayText}
+                    </p>
+                  </div>
+                </div>
+              );
+            })}
+            <div ref={scrollRef} />
+          </div>
+        </ScrollArea>
+      </CardContent>
+    </Card>
+  );
+};
+
+export default Transcript;
-- 
cgit v1.2.3

