import React, { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { Plus, Edit2, Trash2, FileText, Loader2, X, Sparkles, Sliders, Hash, Type, Brain } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; import { useLanguage } from '../../contexts/LanguageContext'; import { useToast } from '../../contexts/ToastContext'; import { useConfirm } from '../../contexts/ConfirmContext'; import { templateService } from '../../services/templateService'; import { knowledgeGroupService } from '../../services/knowledgeGroupService'; import { AssessmentTemplate, CreateTemplateData, UpdateTemplateData, KnowledgeGroup } from '../../types'; export const AssessmentTemplateManager: React.FC = () => { const { t } = useLanguage(); const { showSuccess, showError } = useToast(); const { confirm } = useConfirm(); const [templates, setTemplates] = useState([]); const [groups, setGroups] = useState([]); const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [showModal, setShowModal] = useState(false); const [editingTemplate, setEditingTemplate] = useState(null); // UI state uses strings for easy input const [formData, setFormData] = useState({ name: '', description: '', keywords: '', questionCount: 5, difficultyDistribution: 'Basic: 30%, Intermediate: 40%, Advanced: 30%', style: 'Professional', knowledgeGroupId: '', }); const fetchTemplates = async () => { setIsLoading(true); try { const data = await templateService.getAll(); setTemplates(data); } catch (error) { console.error('Failed to fetch templates:', error); showError(t('actionFailed')); } finally { setIsLoading(false); } }; const fetchGroups = async () => { try { const data = await knowledgeGroupService.getGroups(); setGroups(data); } catch (error) { console.error('Failed to fetch groups:', error); } }; useEffect(() => { fetchTemplates(); fetchGroups(); }, []); const handleOpenModal = (template?: AssessmentTemplate) => { if (template) { setEditingTemplate(template); setFormData({ name: template.name, description: template.description || '', keywords: Array.isArray(template.keywords) ? template.keywords.join(', ') : '', questionCount: template.questionCount, difficultyDistribution: typeof template.difficultyDistribution === 'object' ? JSON.stringify(template.difficultyDistribution) : (template.difficultyDistribution || ''), style: template.style || 'Professional', knowledgeGroupId: template.knowledgeGroupId || '', }); } else { setEditingTemplate(null); setFormData({ name: '', description: '', keywords: '', questionCount: 5, difficultyDistribution: '{"Basic": 3, "Intermediate": 4, "Advanced": 3}', style: 'Professional', knowledgeGroupId: '', }); } setShowModal(true); }; const handleSave = async (e: React.FormEvent) => { e.preventDefault(); setIsSaving(true); try { // Convert UI strings back to required types const keywordsArray = formData.keywords.split(',').map(k => k.trim()).filter(k => k !== ''); let diffDist: any = formData.difficultyDistribution; try { if (formData.difficultyDistribution.startsWith('{')) { diffDist = JSON.parse(formData.difficultyDistribution); } } catch (e) { // Keep as string if parsing fails } const payload: CreateTemplateData = { name: formData.name, description: formData.description, keywords: keywordsArray, questionCount: formData.questionCount, difficultyDistribution: diffDist, style: formData.style, knowledgeGroupId: formData.knowledgeGroupId || undefined, }; if (editingTemplate) { await templateService.update(editingTemplate.id, payload as UpdateTemplateData); showSuccess(t('featureUpdated')); } else { await templateService.create(payload); showSuccess(t('confirm')); } setShowModal(false); fetchTemplates(); } catch (error) { console.error('Save failed:', error); showError(t('actionFailed')); } finally { setIsSaving(false); } }; const handleDelete = async (id: string) => { if (!(await confirm(t('confirmTitle')))) return; try { await templateService.delete(id); showSuccess(t('confirm')); fetchTemplates(); } catch (error) { showError(t('actionFailed')); } }; const renderDifficulty = (dist: any) => { if (typeof dist === 'string') return dist; if (typeof dist === 'object' && dist !== null) { return Object.entries(dist).map(([k, v]) => `${k}: ${v}`).join(', '); } return ''; }; return (

{t('assessmentTemplates')}

{t('assessmentTemplatesSubtitle')}

{isLoading ? (
) : templates.length === 0 ? (

{t('mmEmpty')}

) : (
{templates.map((template) => (

{template.name}

{template.description || t('noDescription')}

{t('questionCount')} {template.questionCount}
{t('difficultyDistribution')} {renderDifficulty(template.difficultyDistribution)}
{template.knowledgeGroup?.name || t('selectKnowledgeGroup')}
{Array.isArray(template.keywords) && template.keywords.map((kw, i) => ( {kw} ))} {(!template.keywords || template.keywords.length === 0) && No keywords}
))}
)} {createPortal( {showModal && (
setShowModal(false)} className="absolute inset-0 bg-slate-900/40 backdrop-blur-sm" />
{editingTemplate ? : }

{editingTemplate ? t('editTemplate') : t('createTemplate')}

setFormData({ ...formData, name: e.target.value })} placeholder="e.g. Senior Frontend Engineer Technical Interview" />
setFormData({ ...formData, keywords: e.target.value })} placeholder={t('keywordsHint')} />
setFormData({ ...formData, questionCount: parseInt(e.target.value) })} />
setFormData({ ...formData, difficultyDistribution: e.target.value })} placeholder='{"Basic": 3, "Inter": 4, "Adv": 3}' />
setFormData({ ...formData, style: e.target.value })} />
)}
, document.body )}
); };