'use client'; import { useState, useEffect } from 'react'; import { Pin, PinOff, Trash2, Plus, Save, Eye, EyeOff, Loader2, MessageCircle, Check, ExternalLink } from 'lucide-react'; const EMPTY = { title: '', content: '', author: 'Редактор', is_pinned: false }; export default function NotesPage() { const [notes, setNotes] = useState([]); const [loading, setLoading] = useState(true); const [editing, setEditing] = useState(null); // null | 'new' | note object const [form, setForm] = useState(EMPTY); const [saving, setSaving] = useState(false); const [err, setErr] = useState(''); async function load() { setLoading(true); try { const r = await fetch('/api/notes'); setNotes(await r.json()); } catch (e) { setErr(e.message); } finally { setLoading(false); } } useEffect(() => { load(); }, []); function startNew() { setForm(EMPTY); setEditing('new'); setErr(''); } function startEdit(note) { setForm({ title: note.title || '', content: note.content, author: note.author, is_pinned: note.is_pinned }); setEditing(note); setErr(''); } async function save() { if (!form.content.trim()) { setErr('Текст заметки обязателен'); return; } setSaving(true); setErr(''); try { const body = { ...form, title: form.title.trim() || null }; if (editing === 'new') { await fetch('/api/notes', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); } else { await fetch(`/api/notes/${editing.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); } setEditing(null); await load(); } catch (e) { setErr(e.message); } finally { setSaving(false); } } async function togglePublish(note) { await fetch(`/api/notes/${note.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ is_published: !note.is_published }) }); await load(); } async function togglePin(note) { await fetch(`/api/notes/${note.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ is_pinned: !note.is_pinned }) }); await load(); } async function del(note) { if (!confirm(`Удалить заметку «${note.title || note.content.slice(0, 40)}»?`)) return; await fetch(`/api/notes/${note.id}`, { method: 'DELETE' }); await load(); } const fmt = (d) => new Date(d).toLocaleDateString('ru-RU', { day: 'numeric', month: 'short', year: 'numeric' }); return (

Заметки редактора

{/* Форма создания/редактирования */} {editing && (
{editing === 'new' ? 'Новая заметка' : 'Редактировать'}
setForm(f => ({ ...f, title: e.target.value }))} />