feat: frontend pages — recordings, protocols, templates, settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { useState } from 'react'
|
||||
import { useTemplates } from '../hooks/useTemplates'
|
||||
|
||||
export default function TemplatesPage() {
|
||||
const { templates, isLoading, createTemplate, deleteTemplate } = useTemplates()
|
||||
const [showForm, setShowForm] = useState(false)
|
||||
const [form, setForm] = useState({ name: '', description: '', system_prompt: '', user_prompt: '', type: 'custom' as const })
|
||||
|
||||
const handleCreate = async () => {
|
||||
await createTemplate(form)
|
||||
setShowForm(false)
|
||||
setForm({ name: '', description: '', system_prompt: '', user_prompt: '', type: 'custom' })
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-2xl font-bold">Шаблоны протоколов</h1>
|
||||
<button
|
||||
onClick={() => setShowForm(!showForm)}
|
||||
className="bg-blue-600 text-white px-4 py-2 rounded text-sm hover:bg-blue-700"
|
||||
>
|
||||
+ Новый шаблон
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{showForm && (
|
||||
<div className="bg-white p-4 rounded-lg shadow-sm mb-6 space-y-3">
|
||||
<input
|
||||
placeholder="Название"
|
||||
value={form.name}
|
||||
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||||
className="w-full border rounded px-3 py-2 text-sm"
|
||||
/>
|
||||
<input
|
||||
placeholder="Описание"
|
||||
value={form.description}
|
||||
onChange={(e) => setForm({ ...form, description: e.target.value })}
|
||||
className="w-full border rounded px-3 py-2 text-sm"
|
||||
/>
|
||||
<textarea
|
||||
placeholder="System prompt"
|
||||
value={form.system_prompt}
|
||||
onChange={(e) => setForm({ ...form, system_prompt: e.target.value })}
|
||||
className="w-full border rounded px-3 py-2 text-sm h-24"
|
||||
/>
|
||||
<textarea
|
||||
placeholder="User prompt (используйте {transcription} для вставки текста)"
|
||||
value={form.user_prompt}
|
||||
onChange={(e) => setForm({ ...form, user_prompt: e.target.value })}
|
||||
className="w-full border rounded px-3 py-2 text-sm h-24"
|
||||
/>
|
||||
<button onClick={handleCreate} className="bg-green-600 text-white px-4 py-2 rounded text-sm">
|
||||
Создать
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoading ? (
|
||||
<p>Загрузка...</p>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{templates.map((tpl) => (
|
||||
<div key={tpl.id} className="bg-white p-4 rounded-lg shadow-sm">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div>
|
||||
<h3 className="font-semibold">{tpl.name}</h3>
|
||||
<p className="text-sm text-gray-500">{tpl.description}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs bg-gray-100 px-2 py-1 rounded">{tpl.type}</span>
|
||||
{tpl.is_default && <span className="text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded">По умолчанию</span>}
|
||||
{tpl.type === 'custom' && (
|
||||
<button
|
||||
onClick={() => deleteTemplate(tpl.id)}
|
||||
className="text-red-500 text-xs hover:text-red-700"
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user