Files
John Remillard a7a8c661b7 feat: Add user settings for voice and persona
Introduces a new `UserSettings` interface and default settings. This allows users to customize voice preferences (name, style, gender) and persona characteristics within the application. This enhances personalization and user experience by tailoring interactions to individual needs and preferences.
2025-12-17 12:14:29 -05:00

85 lines
3.6 KiB
TypeScript

import React, { useEffect, useRef } from 'react';
import { MessageSquare, X, User, Bot } from 'lucide-react';
interface TranscriptPanelProps {
messages: { role: 'user' | 'model'; text: string; id: string }[];
onClose: () => void;
}
const TranscriptPanel: React.FC<TranscriptPanelProps> = ({ messages, onClose }) => {
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [messages]);
return (
<div className="absolute top-0 right-0 w-full sm:w-80 h-full bg-slate-900/95 backdrop-blur-2xl border-l border-white/10 z-50 flex flex-col shadow-2xl animate-in slide-in-from-right duration-500">
<div className="p-5 border-b border-white/10 flex justify-between items-center bg-black/20">
<div className="flex items-center gap-2 text-teal-400">
<MessageSquare size={16} />
<h3 className="text-[10px] font-black uppercase tracking-widest text-white">Live Conversation</h3>
</div>
<button onClick={onClose} className="text-white/40 hover:text-white transition-colors p-1 hover:bg-white/5 rounded-lg">
<X size={18} />
</button>
</div>
<div
ref={scrollRef}
className="flex-grow overflow-y-auto p-6 space-y-5 scrollbar-hide"
>
{messages.length === 0 ? (
<div className="h-full flex flex-col items-center justify-center text-center opacity-20 px-8">
<div className="w-12 h-12 rounded-full border border-white/20 flex items-center justify-center mb-4">
<MessageSquare size={24} className="text-white" />
</div>
<p className="text-[9px] text-white uppercase font-bold tracking-widest leading-loose">
Listening for conversation...<br/>Transcript will appear here
</p>
</div>
) : (
messages.map((m) => (
<div key={m.id} className={`flex flex-col gap-1.5 ${m.role === 'user' ? 'items-end' : 'items-start'} animate-in fade-in slide-in-from-bottom-2 duration-300`}>
<div className="flex items-center gap-1.5 opacity-40 mb-0.5 px-1">
{m.role === 'user' ? (
<>
<span className="text-[8px] font-black text-white uppercase tracking-tighter">You</span>
<User size={8} className="text-teal-400" />
</>
) : (
<>
<Bot size={8} className="text-blue-400" />
<span className="text-[8px] font-black text-white uppercase tracking-tighter">AI Partner</span>
</>
)}
</div>
<div className={`px-4 py-3 rounded-2xl text-[11px] leading-relaxed max-w-[95%] shadow-lg ${
m.role === 'user'
? 'bg-teal-600 text-white rounded-tr-none shadow-teal-900/20'
: 'bg-white/10 text-slate-100 rounded-tl-none border border-white/5 shadow-black/20'
}`}>
{m.text}
</div>
</div>
))
)}
</div>
<div className="p-4 bg-black/40 text-center border-t border-white/5">
<div className="flex items-center justify-center gap-2">
<div className="w-1 h-1 bg-teal-400 rounded-full animate-pulse"></div>
<p className="text-[8px] text-white/30 uppercase font-black tracking-[0.3em]">
Real-time Analysis
</p>
</div>
</div>
</div>
);
};
export default React.memo(TranscriptPanel);