From 3e6202f6d3087669384bb8daee14c87852e5a856 Mon Sep 17 00:00:00 2001 From: Harith_dml Date: Fri, 27 Jun 2025 16:30:03 +0530 Subject: [PATCH] new changes --- src/App.tsx | 24 +++++-- src/components/ChatInterface.tsx | 106 +++++++++++++++++++++++++++---- src/components/TicketForm.tsx | 15 ++--- 3 files changed, 115 insertions(+), 30 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 450f4ee..6bef1f3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,6 +6,8 @@ import { ChatInterface } from './components/ChatInterface'; import { TicketConfirmation } from './components/TicketConfirmation'; import { apiService } from './services/apiService'; import { Ticket } from './types'; +import { FilePlus } from 'lucide-react'; // Add this import at the top + function App() { const [activeTab, setActiveTab] = useState<'new' | 'history' | 'chat'>('new'); @@ -114,15 +116,25 @@ function App() { {/* Main Content */}
- {activeTab === 'new' && ( -
-
-

Submit New Ticket

-

Use voice or text to describe your IT issue

+ {activeTab === 'new' && ( +
+
+ + {/* Header with icon */} +
+
+ +
+

Submit a New Ticket

+

Describe your IT issue using voice or text — we’ll take it from here!

+ + {/* Ticket form */}
- )} +
+ )} + {activeTab === 'history' && (
diff --git a/src/components/ChatInterface.tsx b/src/components/ChatInterface.tsx index 74168fc..9220054 100644 --- a/src/components/ChatInterface.tsx +++ b/src/components/ChatInterface.tsx @@ -2,6 +2,7 @@ import React, { useState, useRef, useEffect } from 'react'; import { Send, Bot, User, Loader, MessageSquare, UserPlus } from 'lucide-react'; import { ChatMessage } from '../types'; import { ChatService } from '../services/chatService'; +import { Mic, MicOff } from 'lucide-react'; interface ChatInterfaceProps { onCreateTicket?: (conversation: string) => void; @@ -23,22 +24,61 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) const [isCreatingTicket, setIsCreatingTicket] = useState(false); const messagesEndRef = useRef(null); const [chatService] = useState(() => new ChatService()); + const [isListening, setIsListening] = useState(false); + const recognitionRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; useEffect(() => { - scrollToBottom(); - }, [messages]); + const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition; - const handleSend = async () => { - if (!input.trim() || isLoading) return; + if (SpeechRecognition) { + const recognition = new SpeechRecognition(); + recognition.lang = 'en-US'; + recognition.interimResults = false; + recognition.maxAlternatives = 1; + + recognition.onstart = () => setIsListening(true); + recognition.onend = () => setIsListening(false); + recognition.onerror = (e: any) => { + console.error('Speech recognition error', e); + setIsListening(false); + }; + recognition.onresult = (event: SpeechRecognitionEvent) => { + const transcript = event.results[0][0].transcript; + setInput(transcript); + handleSend(transcript); + }; + + recognitionRef.current = recognition; + } else { + console.warn('SpeechRecognition is not supported in this browser.'); + } + }, []); + + const speak = (text: string) => { + if ('speechSynthesis' in window) { + const utterance = new SpeechSynthesisUtterance(text); + utterance.lang = 'en-US'; + utterance.pitch = 1; + utterance.rate = 1; + utterance.volume = 1; + window.speechSynthesis.speak(utterance); + } else { + console.warn('Speech synthesis not supported in this browser.'); + } +}; + + const handleSend = async (messageOverride?: string) => { + const messageToSend = messageOverride ?? input; + if (!messageToSend.trim() || isLoading) return; const userMessage: ChatMessage = { id: Date.now().toString(), role: 'user', - content: input, + content: messageToSend, timestamp: new Date().toLocaleString() }; @@ -48,7 +88,7 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) try { const response = await chatService.sendMessage([...messages, userMessage]); - + const assistantMessage: ChatMessage = { id: (Date.now() + 1).toString(), role: 'assistant', @@ -57,12 +97,13 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) }; setMessages(prev => [...prev, assistantMessage]); + speak(response); } catch (error) { console.error('Chat error:', error); const errorMessage: ChatMessage = { id: (Date.now() + 1).toString(), role: 'assistant', - content: "I apologize, but I'm experiencing some technical difficulties. Please try again or create a support ticket if the issue persists.", + content: "I apologize, but I'm experiencing some technical difficulties.", timestamp: new Date().toLocaleString() }; setMessages(prev => [...prev, errorMessage]); @@ -71,6 +112,7 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) } }; + const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); @@ -78,6 +120,17 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) } }; + const handleMicClick = () => { + if (recognitionRef.current) { + if (isListening) { + recognitionRef.current.stop(); + } else { + recognitionRef.current.start(); + } + } +}; + + const handleCreateTicketFromChat = async () => { if (!ticketFormData.requester.trim() || !ticketFormData.email.trim()) { return; @@ -260,13 +313,38 @@ export const ChatInterface: React.FC = ({ onCreateTicket }) rows={1} disabled={isLoading} /> - +
+ + + + + + +
+
diff --git a/src/components/TicketForm.tsx b/src/components/TicketForm.tsx index 224c2dc..551217e 100644 --- a/src/components/TicketForm.tsx +++ b/src/components/TicketForm.tsx @@ -68,13 +68,7 @@ export const TicketForm: React.FC = ({ onTicketSubmit }) => {
-
- -
-
-

Create New Ticket

-

Submit your IT support request

-
+
{error && ( @@ -86,7 +80,7 @@ export const TicketForm: React.FC = ({ onTicketSubmit }) => {
-
-