muryshev's picture
update
19eca0c
import React from 'react';
import Modal from 'react-modal';
import { GoX } from 'react-icons/go';
import { LlmPrompt } from '@/api/llmPrompts/types';
import { useQuery } from '@tanstack/react-query';
import { fetchLlmPromptById, fetchDefaultLlmPrompt } from '@/api/llmPrompts/llmPromptApi';
import './LlmPromptModal.scss';
interface LlmPromptModalProps {
isOpen: boolean;
onRequestClose: () => void;
prompt: LlmPrompt | null;
onSave: (prompt: LlmPrompt | Omit<LlmPrompt, 'id' | 'created_at'>) => Promise<void>;
isEditMode: boolean;
}
const customStyles = {
content: {
top: '40%',
left: '50%',
right: 'auto',
bottom: 'auto',
transform: 'translate(-50%, -50%)',
borderRadius: '15px',
maxWidth: '100%',
overflow: 'hidden',
},
};
const LlmPromptModal: React.FC<LlmPromptModalProps> = ({
isOpen,
onRequestClose,
prompt,
onSave,
isEditMode,
}) => {
const [formData, setFormData] = React.useState<LlmPrompt | Omit<LlmPrompt, 'id' | 'created_at'>>(() => ({
is_default: false,
name: 'Промпт ' + Date.now().toLocaleString(),
text: "",
type: 'system'
}));
// Запрос промпта для редактирования
const { data: serverPrompt, isLoading: isPromptLoading } = useQuery({
queryKey: ['llmPrompt', prompt?.id],
queryFn: () => fetchLlmPromptById(prompt!.id),
enabled: isOpen && isEditMode && !!prompt?.id,
});
// Запрос дефолтного промпта для создания
const { data: defaultPrompt, isLoading: isDefaultLoading } = useQuery({
queryKey: ['defaultLlmPrompt'],
queryFn: fetchDefaultLlmPrompt,
enabled: isOpen && !isEditMode, // Запрашиваем только при создании
});
React.useEffect(() => {
if (isOpen) {
if (isEditMode && serverPrompt) {
setFormData(serverPrompt); // Данные с сервера для редактирования
} else if (!isEditMode && defaultPrompt) {
setFormData(defaultPrompt); // Дефолтная запись с сервера для создания
} else if (!isEditMode && !defaultPrompt && !isDefaultLoading) {
setFormData({ // Если дефолтной записи нет и загрузка завершена
is_default: true,
name: 'Промпт ' + Date.now().toLocaleString(),
text: "",
type: 'system'
});
}
}
}, [isOpen, isEditMode, serverPrompt, defaultPrompt, isDefaultLoading]);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]:
name === 'is_default' ? (e.target as HTMLInputElement).checked :
name === 'text' || name === 'name' ? value :
parseFloat(value) || 0,
}));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
await onSave(formData);
onRequestClose();
} catch (err) {
console.error('Save failed:', err);
}
};
if (isPromptLoading && isEditMode) {
return <div>Loading prompt...</div>;
}
if (isDefaultLoading && !isEditMode) {
return <div>Loading default prompt...</div>;
}
return (
<Modal
isOpen={isOpen}
onRequestClose={onRequestClose}
style={customStyles}
overlayClassName="modal-overlay"
>
<div className="modal-content">
<div className="label">
<h3 className="name">{isEditMode ? 'Редактирование промпта' : 'Новый промпт'}</h3>
<button className="close-button" onClick={onRequestClose}>
<GoX style={{ height: '25px', width: '25px' }} />
</button>
</div>
<form onSubmit={handleSubmit}>
{isEditMode && 'id' in formData && (
<label>
<span className='title'>ID:</span>
<input type="text" value={formData.id} disabled />
</label>
)}
<label>
<span className='title'>Задать по-умолчанию:</span>
<input
type="checkbox"
name="is_default"
checked={formData.is_default}
onChange={handleChange}
/>
</label>
<label>
<span className='title'>Название:</span>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
/>
</label>
<label>
<span className='title'>Текст:</span>
<textarea
name="text"
value={formData.text || ''}
onChange={handleChange}
/>
</label>
<div className="button-group">
<button type="submit">{isEditMode ? 'Сохранить' : 'Создать'}</button>
</div>
</form>
</div>
</Modal>
);
};
export default LlmPromptModal;