'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Switch } from '@/components/ui/switch'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { ArrowLeft, Brain, Plus, Pencil, Trash2, Loader2 } from 'lucide-react'; import { toast } from 'sonner'; import { AiPromptTemplate, PromptPurpose } from '@/lib/types/workflow'; const PURPOSES: { value: PromptPurpose; label: string }[] = [ { value: 'title_cleanup', label: 'Title Cleanup' }, { value: 'description_rewrite', label: 'Description Rewrite' }, { value: 'ambiguous_classification', label: 'Ambiguous Classification' }, { value: 'troubleshooting_steps', label: 'Troubleshooting Steps' }, { value: 'noc_format', label: 'NOC Format' }, { value: 'soc_analysis', label: 'SOC Analysis' }, ]; export default function TemplatesPage() { const [templates, setTemplates] = useState([]); const [isLoading, setIsLoading] = useState(true); const [editing, setEditing] = useState | null>(null); const [isSaving, setIsSaving] = useState(false); useEffect(() => { loadTemplates(); }, []); const loadTemplates = async () => { setIsLoading(true); try { const res = await fetch('/api/workflow/templates'); if (res.ok) setTemplates(await res.json()); } catch { toast.error('Failed to load templates'); } finally { setIsLoading(false); } }; const handleCreate = () => { setEditing({ name: '', purpose: 'title_cleanup', system_prompt: '', user_prompt_template: '', provider: 'openai', model: 'gpt-4o', temperature: 0.3, max_tokens: 4000, is_active: true, }); }; const handleSave = async () => { if (!editing) return; setIsSaving(true); try { const isUpdate = editing.id; const url = isUpdate ? `/api/workflow/templates/${editing.id}` : '/api/workflow/templates'; const res = await fetch(url, { method: isUpdate ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(editing), }); if (res.ok) { toast.success(isUpdate ? 'Template updated' : 'Template created'); setEditing(null); loadTemplates(); } } catch { toast.error('Failed to save template'); } finally { setIsSaving(false); } }; const handleDelete = async (id: number) => { if (!confirm('Delete this template?')) return; try { const res = await fetch(`/api/workflow/templates/${id}`, { method: 'DELETE' }); if (res.ok) { toast.success('Template deleted'); loadTemplates(); } } catch { toast.error('Failed to delete'); } }; return (

AI Prompt Templates

Configure prompts for AI-assisted triage

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

No templates configured. Default prompts will be used.

) : ( Name Purpose Provider Model Active Actions {templates.map((t) => ( {t.name} {t.purpose} {t.provider} {t.model} {t.is_active ? 'Yes' : 'No'}
))}
)}
{/* Edit Dialog */} !open && setEditing(null)}> {editing?.id ? 'Edit' : 'New'} AI Template Templates support {'{{field}}'} interpolation. Available variables: title, description, ticket_category, failed_fields, issueTypes, subIssueTypes, priorities. {editing && (
setEditing({ ...editing, name: e.target.value })} />
setEditing({ ...editing, model: e.target.value })} />
setEditing({ ...editing, temperature: parseFloat(e.target.value) })} />