import React, { useState, useEffect, useRef } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import { Mic, MicOff, Send, X, Volume2, TrendingUp, DollarSign, PieChart, Calendar, Wallet, Target, CreditCard, Heart } from 'lucide-react'; interface VoiceQuery { id: string; query: string; response: string; type: 'portfolio' | 'budget' | 'credit' | 'goals' | 'general'; data?: any; } const FloatingVoiceBot: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const [isAnimating, setIsAnimating] = useState(false); const [isListening, setIsListening] = useState(false); const [isProcessing, setIsProcessing] = useState(false); const [textInput, setTextInput] = useState(''); const [conversation, setConversation] = useState>([]); const messagesEndRef = useRef(null); const conversationRef = useRef(null); // Demo financial data const demoData = { portfolio: { totalValue: 1245000, todayChange: 15750, todayChangePercent: 1.28, topPerformer: 'HDFC Bank', topPerformerGain: 8.5, allocation: { equity: 65, debt: 25, gold: 10 }, holdings: [ { name: 'HDFC Bank', value: 285000, change: 8.5 }, { name: 'Reliance Industries', value: 220000, change: -2.1 }, { name: 'ICICI Bank', value: 185000, change: 4.2 }, { name: 'SBI ETF Gold', value: 125000, change: 0.8 } ] }, budget: { monthlyIncome: 125000, monthlyExpenses: 67500, savingsRate: 46, topExpenseCategory: 'Food & Dining', topExpenseAmount: 18500 }, credit: { creditScore: 768, totalLimit: 350000, utilization: 28, nextDueDate: '15 May 2024' }, goals: { totalGoals: 5, onTrack: 4, emergencyFund: 450000, emergencyFundTarget: 600000 } }; // Voice queries with responses const voiceQueries: VoiceQuery[] = [ { id: '1', query: 'what is my current portfolio standing', response: `Your portfolio is currently valued at ₹12.45 lakhs, up by ₹15,750 today (1.28%). Your top performer is HDFC Bank with 8.5% gains. Your allocation is 65% equity, 25% debt, and 10% gold.`, type: 'portfolio', data: demoData.portfolio }, { id: '2', query: 'how is my portfolio performing', response: `Your portfolio is performing well today with a gain of ₹15,750 (1.28%). HDFC Bank is your top performer with 8.5% gains, while Reliance is down 2.1%. Overall, you're maintaining a balanced allocation.`, type: 'portfolio', data: demoData.portfolio }, { id: '3', query: 'what are my top holdings', response: `Your top holdings are: HDFC Bank (₹2.85L, +8.5%), Reliance Industries (₹2.20L, -2.1%), ICICI Bank (₹1.85L, +4.2%), and SBI ETF Gold (₹1.25L, +0.8%).`, type: 'portfolio', data: demoData.portfolio }, { id: '4', query: 'show me my budget summary', response: `Your monthly income is ₹1.25 lakhs with expenses of ₹67,500, giving you a healthy 46% savings rate. Your top expense category is Food & Dining at ₹18,500.`, type: 'budget', data: demoData.budget }, { id: '5', query: 'what is my credit score', response: `Your credit score is 768, which is excellent. Your total credit limit is ₹3.5 lakhs with 28% utilization. Your next payment is due on 15th May 2024.`, type: 'credit', data: demoData.credit }, { id: '6', query: 'how are my financial goals', response: `You have 5 active financial goals with 4 on track. Your emergency fund is at ₹4.5 lakhs, which is 75% of your ₹6 lakh target.`, type: 'goals', data: demoData.goals } ]; const processVoiceQuery = (query: string): VoiceQuery | null => { const normalizedQuery = query.toLowerCase().trim(); return voiceQueries.find(vq => normalizedQuery.includes('portfolio') || normalizedQuery.includes('holdings') || normalizedQuery.includes('budget') || normalizedQuery.includes('credit score') || normalizedQuery.includes('goals') || normalizedQuery.includes('performing') ) || null; }; const handleVoiceInput = async () => { if (isListening) { setIsListening(false); setIsProcessing(true); // Simulate processing delay setTimeout(() => { const demoQuery = voiceQueries[0]; // Default to portfolio query setConversation(prev => [ ...prev, { type: 'user', message: demoQuery.query, timestamp: new Date() }, { type: 'bot', message: demoQuery.response, data: demoQuery.data, timestamp: new Date() } ]); setIsProcessing(false); }, 2000); } else { setIsListening(true); // Auto-stop listening after 3 seconds for demo setTimeout(() => { if (isListening) { handleVoiceInput(); } }, 3000); } }; const handleTextSubmit = () => { if (!textInput.trim()) return; const matchedQuery = processVoiceQuery(textInput); setConversation(prev => [ ...prev, { type: 'user', message: textInput, timestamp: new Date() } ]); if (matchedQuery) { setTimeout(() => { setConversation(prev => [ ...prev, { type: 'bot', message: matchedQuery.response, data: matchedQuery.data, timestamp: new Date() } ]); }, 1000); } else { setTimeout(() => { setConversation(prev => [ ...prev, { type: 'bot', message: "I can help you with portfolio status, budget summary, credit score, and financial goals. Try asking 'What is my current portfolio standing?' or 'Show me my budget summary'.", timestamp: new Date() } ]); }, 1000); } setTextInput(''); }; const renderDataVisualization = (data: any, type: string) => { switch (type) { case 'portfolio': return (
Total Value:

₹{(data.totalValue / 100000).toFixed(2)}L

Today's Change:

+₹{(data.todayChange / 1000).toFixed(1)}K

); case 'budget': return (
Savings Rate:

{data.savingsRate}%

Monthly Save:

₹{((data.monthlyIncome - data.monthlyExpenses) / 1000).toFixed(0)}K

); case 'credit': return (
Credit Score:

{data.creditScore}

Utilization:

{data.utilization}%

); default: return null; } }; const handleOpen = () => { setIsOpen(true); // Small delay to ensure DOM is ready, then trigger animation setTimeout(() => setIsAnimating(true), 10); }; const handleClose = () => { setIsAnimating(false); // Delay the actual close to allow animation to complete setTimeout(() => setIsOpen(false), 300); }; const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; useEffect(() => { scrollToBottom(); }, [conversation, isProcessing]); return ( <> {/* Floating Button */}
{/* Voice Bot Modal */} {isOpen && (
e.stopPropagation()} >
Voice Assistant Ask about your finances
{/* Conversation Area */}
{conversation.length === 0 && (

Try asking:

"What is my portfolio standing?"

"Show me my budget summary"

"What is my credit score?"

)} {conversation.map((msg, index) => (

{msg.message}

{msg.data && renderDataVisualization(msg.data, conversation[index-1]?.message.includes('portfolio') ? 'portfolio' : conversation[index-1]?.message.includes('budget') ? 'budget' : conversation[index-1]?.message.includes('credit') ? 'credit' : 'general')}
))} {isProcessing && (
)} {/* Invisible element to scroll to */}
{/* Voice Input Area */}
setTextInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleTextSubmit()} className="flex-1 text-sm transition-all duration-200 focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 hover:border-gray-300" />
{isListening && (

Listening...

)}
)} ); }; export default FloatingVoiceBot;