'use client'; import React, { useState, useEffect, useCallback } from 'react'; import type { InterviewTemplate } from '@/lib/interview/types'; import { interviewTemplatesService } from '@/lib/interview/templates-service'; import { track } from '@/lib/telemetry'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { toast } from 'sonner'; import { Search, Plus, Edit, Copy, Trash2, Eye, ClipboardList, FileText } from 'lucide-react'; import { InterviewTemplateEditor } from './InterviewTemplateEditor'; interface InterviewTemplatesPanelProps { initialMode?: 'list' | 'create'; onChanged?: () => void; } type View = | 'list' | { mode: 'create' } | { mode: 'edit'; template: InterviewTemplate } | { mode: 'view'; template: InterviewTemplate }; export function InterviewTemplatesPanel({ initialMode = 'list', onChanged, }: InterviewTemplatesPanelProps) { const [templates, setTemplates] = useState([]); const [view, setView] = useState(initialMode === 'create' ? { mode: 'create' } : 'list'); const [searchQuery, setSearchQuery] = useState(''); const [showBuiltIn, setShowBuiltIn] = useState(true); const [showCustom, setShowCustom] = useState(true); const [templateToDelete, setTemplateToDelete] = useState(null); const reloadList = useCallback(async () => { try { const all = await interviewTemplatesService.getAllTemplates(); setTemplates(all); } catch { toast.error('Failed to load interview templates'); } }, []); useEffect(() => { reloadList(); }, [reloadList]); const handleDuplicate = async (src: InterviewTemplate) => { try { const id = await interviewTemplatesService.generateId(src.title + ' copy'); await interviewTemplatesService.createTemplate({ ...src, id, title: `${src.title} copy`, isBuiltIn: false, }); track('interview_template_created'); await reloadList(); onChanged?.(); const created = await interviewTemplatesService.getTemplate(id); if (created) { toast.success(`Duplicated: ${src.title}`); setView({ mode: 'edit', template: created }); } } catch (e) { const message = e instanceof Error ? e.message : 'Failed to duplicate template'; toast.error(message); } }; const confirmDelete = async () => { if (!templateToDelete) return; try { await interviewTemplatesService.deleteTemplate(templateToDelete.id); track('interview_template_deleted'); toast.success(`Deleted: ${templateToDelete.title}`); await reloadList(); onChanged?.(); } catch (e) { const message = e instanceof Error ? e.message : 'Failed to delete template'; toast.error(message); } finally { setTemplateToDelete(null); } }; const handleEditorSaved = async () => { await reloadList(); setView('list'); onChanged?.(); }; const filtered = templates.filter(t => { const q = searchQuery.toLowerCase(); const matchesSearch = t.title.toLowerCase().includes(q) || t.description.toLowerCase().includes(q); if (!matchesSearch) return false; if (t.isBuiltIn && !showBuiltIn) return false; if (!t.isBuiltIn && !showCustom) return false; return true; }).sort((a, b) => Number(!!a.isBuiltIn) - Number(!!b.isBuiltIn)); // custom first, then built-in const inEditor = view !== 'list'; const editorTemplate = inEditor && view.mode === 'create' ? null : inEditor ? view.template : null; return ( <>

Interview Templates

Manage the guided interviews available in interview mode.

setSearchQuery(e.target.value)} className="pl-9" />
Show:
{filtered.length === 0 ? (

No templates found

{!showBuiltIn && !showCustom ? 'Both Built-in and Custom are hidden. Enable at least one above.' : searchQuery ? 'Try a different search query' : 'Create your first interview template'}

{!searchQuery && ( )}
) : (
{filtered.map(t => (

{t.title}

{t.isBuiltIn ? 'Built-in' : 'Custom'}

{t.description}

{t.artifacts[0] && (

{t.artifacts[0].path}

)}
{t.isBuiltIn ? ( <> ) : ( <> )}
))}
)}
{/* Editor dialog (matches the Skills editor: a modal over the list) */} !o && setView('list')}> {editorTemplate ? `Edit ${editorTemplate.title}` : 'Create interview template'} {inEditor && ( setView('list')} /> )} {/* Delete confirmation */} !o && setTemplateToDelete(null)}> Delete Template {templateToDelete ? `Are you sure you want to delete "${templateToDelete.title}"? This action cannot be undone.` : ''} ); }