HEX
Server: nginx/1.18.0
System: Linux vcwordpress 5.15.0-174-generic #184-Ubuntu SMP Fri Mar 13 18:41:50 UTC 2026 x86_64
User: root (0)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/igsms.viitorcloud.co/igsmsportal/components/FloatingChatbot.tsx
import React, { useState } from 'react';
import { GoogleGenAI } from '@google/genai';
import { Grievance } from '../types';

interface FloatingChatbotProps {
  grievances: Grievance[];
}

const FloatingChatbot: React.FC<FloatingChatbotProps> = ({ grievances }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<{role: 'user' | 'bot', text: string}[]>([
    { role: 'bot', text: 'Namaste! I am your Gujarat IGSMS AI Assistant. How can I help you today?' }
  ]);
  const [input, setInput] = useState('');
  const [isTyping, setIsTyping] = useState(false);

  const handleSend = async () => {
    if (!input.trim()) return;
    
    const userMsg = input.trim();
    setMessages(prev => [...prev, { role: 'user', text: userMsg }]);
    setInput('');
    setIsTyping(true);

    try {
      const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
      const response = await ai.models.generateContent({
        model: 'gemini-3-flash-preview',
        contents: `You are a helpful government assistant for the Gujarat Integrated Grievance & Service Management System.
        Current system data context: There are ${grievances.length} tickets.
        User query: "${userMsg}"
        Be professional, concise, and helpful.`,
      });

      setMessages(prev => [...prev, { role: 'bot', text: response.text || 'I am sorry, I could not process that.' }]);
    } catch (err) {
      setMessages(prev => [...prev, { role: 'bot', text: 'System error. Please try again later.' }]);
    } finally {
      setIsTyping(false);
    }
  };

  return (
    <div className="fixed bottom-6 right-6 z-50">
      {isOpen ? (
        <div className="bg-white w-80 h-96 rounded-2xl shadow-2xl border border-gray-200 flex flex-col animate-scale-in">
          <div className="p-4 bg-orange-600 text-white rounded-t-2xl flex justify-between items-center">
            <span className="font-bold">IGSMS Assistant</span>
            <button onClick={() => setIsOpen(false)}>&times;</button>
          </div>
          <div className="flex-1 overflow-y-auto p-4 space-y-3 text-sm">
            {messages.map((m, i) => (
              <div key={i} className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`}>
                <div className={`max-w-[80%] p-2 rounded-lg ${m.role === 'user' ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-800'}`}>
                  {m.text}
                </div>
              </div>
            ))}
            {isTyping && <div className="text-xs text-gray-400 italic">Thinking...</div>}
          </div>
          <div className="p-3 border-t flex gap-2">
            <input 
              value={input} 
              onChange={e => setInput(e.target.value)}
              onKeyPress={e => e.key === 'Enter' && handleSend()}
              placeholder="Ask me anything..." 
              className="flex-1 text-sm border-none focus:ring-0 outline-none"
            />
            <button onClick={handleSend} className="text-orange-600 font-bold"><i className="fa-solid fa-paper-plane"></i></button>
          </div>
        </div>
      ) : (
        <button 
          onClick={() => setIsOpen(true)}
          className="bg-orange-600 text-white w-14 h-14 rounded-full shadow-lg hover:scale-110 transition-transform flex items-center justify-center text-xl"
        >
          <i className="fa-solid fa-robot"></i>
        </button>
      )}
    </div>
  );
};

export default FloatingChatbot;