Nagesh Muralidhar
Initial commit of PodCraft application
fd52f31
import React, { useRef, useEffect, useState } from 'react';
import { FaRobot, FaUser, FaCopy, FaSearch, FaEdit, FaSave, FaTimes } from 'react-icons/fa';
import './ChatDetailModal.css';
/**
* Modal component for displaying and editing agent chat messages in detail
* @param {Object} props
* @param {boolean} props.isOpen - Whether the modal is open
* @param {function} props.onClose - Function to call when the modal is closed
* @param {string} props.agentName - The name of the agent
* @param {string} props.agentId - The ID of the agent
* @param {number} props.turn - The turn number
* @param {string} props.content - The chat message content
* @param {function} props.onSave - Function to call when the content is saved
*/
const ChatDetailModal = ({ isOpen, onClose, agentName, agentId, turn, content, onSave }) => {
const modalRef = useRef(null);
const [isEditing, setIsEditing] = useState(false);
const [editedContent, setEditedContent] = useState('');
const textareaRef = useRef(null);
// Initialize the editor with the current content when editing starts
useEffect(() => {
if (isEditing && content) {
// Remove any HTML tags to get plain text for editing
const plainText = content.replace(/<[^>]*>/g, '');
setEditedContent(plainText);
// Focus the textarea when editing starts
setTimeout(() => {
if (textareaRef.current) {
textareaRef.current.focus();
}
}, 100);
}
}, [isEditing, content]);
// Reset edited content when content changes (even if modal is already open)
useEffect(() => {
if (content && isOpen) {
// If we're currently editing, update the edited content
if (isEditing) {
const plainText = content.replace(/<[^>]*>/g, '');
setEditedContent(plainText);
}
}
}, [content, isOpen]);
// Handle clicks outside the modal to close it
useEffect(() => {
const handleClickOutside = (event) => {
if (modalRef.current && !modalRef.current.contains(event.target)) {
onClose();
}
};
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isOpen, onClose]);
// Copy content to clipboard
const handleCopyContent = () => {
const plainText = content.replace(/<[^>]*>/g, '');
navigator.clipboard.writeText(plainText);
// Show a mini toast or feedback
const copyButton = document.querySelector('.copy-button');
if (copyButton) {
copyButton.classList.add('copied');
setTimeout(() => {
copyButton.classList.remove('copied');
}, 2000);
}
};
// Start editing the content
const handleStartEditing = () => {
setIsEditing(true);
};
// Cancel editing and reset
const handleCancelEdit = () => {
setIsEditing(false);
setEditedContent('');
};
// Save the edited content
const handleSaveEdit = () => {
if (onSave) {
onSave(agentId, turn, editedContent);
}
setIsEditing(false);
};
// Don't render anything if the modal is not open
if (!isOpen) return null;
// Get agent icon based on agent ID or name
const getAgentIcon = () => {
if (agentId === 'researcher') {
return <FaSearch />;
}
return <FaRobot />;
};
return (
<div className="chat-modal-overlay">
<div className="chat-modal-content" ref={modalRef}>
<div className="chat-modal-header">
<div className="agent-info">
<div className="agent-avatar">
{getAgentIcon()}
</div>
<div className="agent-details">
<h3>{agentName}</h3>
<span className="turn-badge">Turn {turn}</span>
</div>
</div>
<div className="modal-actions">
{!isEditing ? (
<>
<button
className="edit-button"
onClick={handleStartEditing}
title="Edit content"
>
<FaEdit />
</button>
<button
className="copy-button"
onClick={handleCopyContent}
title="Copy to clipboard"
>
<FaCopy />
</button>
</>
) : (
<>
<button
className="save-button"
onClick={handleSaveEdit}
title="Save changes"
>
<FaSave />
</button>
<button
className="cancel-button"
onClick={handleCancelEdit}
title="Cancel editing"
>
<FaTimes />
</button>
</>
)}
<button className="close-button" onClick={onClose}>×</button>
</div>
</div>
<div className="chat-modal-body">
{!isEditing ? (
<div className="content-box" dangerouslySetInnerHTML={{ __html: content }} />
) : (
<textarea
ref={textareaRef}
className="content-editor"
value={editedContent}
onChange={(e) => setEditedContent(e.target.value)}
placeholder="Edit the content..."
/>
)}
</div>
<div className="chat-modal-footer">
{!isEditing ? (
<button className="modal-button close-btn" onClick={onClose}>Close</button>
) : (
<>
<button className="modal-button cancel-btn" onClick={handleCancelEdit}>Cancel</button>
<button className="modal-button save-btn" onClick={handleSaveEdit}>Save Changes</button>
</>
)}
</div>
</div>
</div>
);
};
export default ChatDetailModal;