feat: editor enriquecido en notas de Seguimiento
Barra tipo Docs (negrita, color, resaltado, listas, enlaces, tamaño) al crear notas. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
Send,
|
||||
} from 'lucide-react';
|
||||
import { PageHeader } from '@/components/ui';
|
||||
import NoteRichEditor, { richTextHasContent } from '@/components/NoteRichEditor';
|
||||
|
||||
type Entry = {
|
||||
id: string;
|
||||
@@ -49,7 +50,9 @@ function typeTone(t: string) {
|
||||
}
|
||||
|
||||
function looksLikeHtml(s: string) {
|
||||
return /<\/?(?:ul|ol|li|p|a|strong|br)\b/i.test(s);
|
||||
return /<\/?(?:ul|ol|li|p|a|strong|b|em|i|u|br|span|font|div|h[1-6])\b/i.test(
|
||||
s
|
||||
);
|
||||
}
|
||||
|
||||
function escapeHtml(s: string) {
|
||||
@@ -104,7 +107,7 @@ export default function SeguimientoBoard() {
|
||||
}, [data, query]);
|
||||
|
||||
async function saveNote() {
|
||||
if (!noteBody.trim()) return;
|
||||
if (!richTextHasContent(noteBody)) return;
|
||||
setNoteBusy(true);
|
||||
setNoteMsg(null);
|
||||
try {
|
||||
@@ -113,7 +116,7 @@ export default function SeguimientoBoard() {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
title: noteTitle.trim() || 'Nota de seguimiento',
|
||||
body: noteBody.trim(),
|
||||
body: noteBody,
|
||||
occurredAt: new Date().toISOString(),
|
||||
}),
|
||||
});
|
||||
@@ -209,8 +212,8 @@ export default function SeguimientoBoard() {
|
||||
Nueva nota
|
||||
</div>
|
||||
<p className="text-xs text-gray-500">
|
||||
Se guarda con fecha. El histórico también incluye entradas
|
||||
sincronizadas desde Superhuman Docs (docs de seguimiento).
|
||||
Formato enriquecido (negrita, color, resaltado, listas, enlaces). El
|
||||
histórico también incluye entradas de Superhuman / Google Doc.
|
||||
</p>
|
||||
<input
|
||||
value={noteTitle}
|
||||
@@ -218,16 +221,16 @@ export default function SeguimientoBoard() {
|
||||
placeholder="Título (opcional)"
|
||||
className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm text-gray-900"
|
||||
/>
|
||||
<textarea
|
||||
<NoteRichEditor
|
||||
value={noteBody}
|
||||
onChange={(e) => setNoteBody(e.target.value)}
|
||||
onChange={setNoteBody}
|
||||
placeholder="Comentarios, hipótesis, bloqueos, siguientes pasos…"
|
||||
className="w-full min-h-[120px] rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm text-gray-900"
|
||||
minHeight="160px"
|
||||
/>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<button
|
||||
type="button"
|
||||
disabled={noteBusy || !noteBody.trim()}
|
||||
disabled={noteBusy || !richTextHasContent(noteBody)}
|
||||
onClick={() => void saveNote()}
|
||||
className="inline-flex items-center gap-2 rounded-xl bg-brand-500 text-white px-4 py-2 text-sm font-semibold disabled:opacity-50"
|
||||
>
|
||||
@@ -332,7 +335,7 @@ export default function SeguimientoBoard() {
|
||||
</div>
|
||||
{open && e.body_md && (
|
||||
<div
|
||||
className="mt-3 text-sm text-gray-800 bg-gray-50 border border-gray-100 rounded-lg p-4 max-h-[36rem] overflow-y-auto [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:my-1.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:my-0.5 [&_a]:text-brand-600 [&_a]:underline [&_strong]:font-semibold [&_p]:my-1.5"
|
||||
className="mt-3 text-sm text-gray-800 bg-gray-50 border border-gray-100 rounded-lg p-4 max-h-[36rem] overflow-y-auto [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:my-1.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:my-0.5 [&_a]:text-brand-600 [&_a]:underline [&_strong]:font-semibold [&_b]:font-semibold [&_em]:italic [&_i]:italic [&_u]:underline [&_p]:my-1.5"
|
||||
onClick={(ev) => {
|
||||
const t = ev.target as HTMLElement;
|
||||
if (t.closest('a')) ev.stopPropagation();
|
||||
|
||||
Reference in New Issue
Block a user