/** * HelpChat Component * Persistent side-panel chat with LLM-powered help * Context-aware and maintains conversation history */ import React, { useState, useEffect, useRef } from 'react'; const HelpChat = ({ isOpen = false, onClose, currentPage = 'dashboard', context = {} }) => { const [messages, setMessages] = useState([]); const [inputText, setInputText] = useState(''); const [isLoading, setIsLoading] = useState(false); const [sessionId] = useState(() => `session-${Date.now()}`); const messagesEndRef = useRef(null); const inputRef = useRef(null); useEffect(() => { if (isOpen && messages.length === 0) { // Add welcome message setMessages([{ role: 'assistant', content: `👋 Hi! I'm your AI assistant for StrikePackageGPT. I can help you with: • Understanding security tools and commands • Interpreting scan results • Writing nmap, nikto, and other tool commands • Navigating the platform • Security best practices What would you like help with?`, timestamp: new Date() }]); } }, [isOpen]); useEffect(() => { scrollToBottom(); }, [messages]); useEffect(() => { if (isOpen && inputRef.current) { inputRef.current.focus(); } }, [isOpen]); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; const handleSendMessage = async () => { if (!inputText.trim() || isLoading) return; const userMessage = { role: 'user', content: inputText, timestamp: new Date() }; setMessages(prev => [...prev, userMessage]); setInputText(''); setIsLoading(true); try { // Build context string const contextString = `User is on ${currentPage} page. ${JSON.stringify(context)}`; const response = await fetch('/api/llm/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: inputText, session_id: sessionId, context: contextString }) }); if (!response.ok) { throw new Error('Failed to get response'); } const data = await response.json(); const assistantMessage = { role: 'assistant', content: data.message || data.content || 'I apologize, I had trouble processing that request.', timestamp: new Date() }; setMessages(prev => [...prev, assistantMessage]); } catch (error) { console.error('Error sending message:', error); setMessages(prev => [...prev, { role: 'assistant', content: '❌ Sorry, I encountered an error. Please try again.', timestamp: new Date(), isError: true }]); } finally { setIsLoading(false); } }; const handleKeyPress = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSendMessage(); } }; const copyToClipboard = (text) => { navigator.clipboard.writeText(text).then(() => { // Could show a toast notification here console.log('Copied to clipboard'); }); }; const clearChat = () => { if (window.confirm('Clear all chat history?')) { setMessages([{ role: 'assistant', content: 'Chat history cleared. How can I help you?', timestamp: new Date() }]); } }; const renderMessage = (message, index) => { const isUser = message.role === 'user'; const isError = message.isError; // Check if message contains code blocks const hasCode = message.content.includes('```'); let renderedContent; if (hasCode) { // Simple code block rendering const parts = message.content.split(/(```[\s\S]*?```)/g); renderedContent = parts.map((part, i) => { if (part.startsWith('```')) { const code = part.slice(3, -3).trim(); const [lang, ...codeLines] = code.split('\n'); const codeText = codeLines.join('\n'); return (
{lang || 'code'}
                {codeText}
              
); } return
{part}
; }); } else { renderedContent =
{message.content}
; } return (
{renderedContent}
{message.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
); }; const quickActions = [ { label: '📝 Write nmap command', prompt: 'How do I write an nmap command to scan a network?' }, { label: '🔍 Interpret results', prompt: 'Help me understand these scan results' }, { label: '🛠️ Use sqlmap', prompt: 'How do I use sqlmap to test for SQL injection?' }, { label: '📊 Generate report', prompt: 'How do I generate a security assessment report?' } ]; if (!isOpen) return null; return (
{/* Header */}

💬 AI Assistant

Ask me anything about security testing
{/* Messages area */}
{messages.map((message, index) => renderMessage(message, index))} {isLoading && (
Thinking...
)}
{/* Quick actions */} {messages.length <= 1 && (
Quick actions:
{quickActions.map((action, i) => ( ))}
)} {/* Input area */}