Files
Estacion-de-Documentos/frontend/app/documents/[documentId]/page.tsx
T
2026-05-17 10:14:14 -06:00

66 lines
2.7 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { api, DocumentItem } from "@/lib/api";
import { Shell } from "@/components/Shell";
import { Button, Card } from "@/components/ui";
export default function DocumentPage({ params }: { params: { documentId: string } }) {
const documentId = Number(params.documentId);
const [document, setDocument] = useState<DocumentItem | null>(null);
const [content, setContent] = useState("");
const [savedContent, setSavedContent] = useState("");
const [status, setStatus] = useState("");
const dirty = content !== savedContent;
useEffect(() => {
Promise.all([api.document(documentId), api.markdown(documentId)]).then(([doc, markdown]) => {
setDocument(doc); setContent(markdown); setSavedContent(markdown);
}).catch((err) => setStatus(err.message));
}, [documentId]);
async function save() {
setStatus("Guardando...");
await api.saveMarkdown(documentId, content);
setSavedContent(content);
setStatus("Guardado");
}
async function copy() {
await navigator.clipboard.writeText(content);
setStatus("Copiado al portapapeles");
}
return (
<Shell>
<Link href="/" className="text-sm text-blue-300">Volver al dashboard</Link>
<div className="mt-4 flex flex-wrap items-center justify-between gap-4">
<div>
<h1 className="text-3xl font-bold">{document?.title || "Documento"}</h1>
<p className="mt-1 text-sm text-slate-400">{dirty ? "Cambios sin guardar" : "Sin cambios pendientes"} {status && `- ${status}`}</p>
</div>
<div className="flex flex-wrap gap-2">
<Button onClick={save} disabled={!dirty}>Guardar</Button>
<Button className="bg-slate-700 hover:bg-slate-600" onClick={copy}>Copiar</Button>
<a className="rounded-xl border border-white/10 px-4 py-2 hover:bg-white/10" href={api.downloadDocumentUrl(documentId)}>Descargar .md</a>
</div>
</div>
<div className="mt-6 grid gap-6 xl:grid-cols-2">
<Card className="p-0">
<div className="border-b border-white/10 px-4 py-3 font-medium">Editor Markdown</div>
<textarea value={content} onChange={(event) => setContent(event.target.value)} className="h-[72vh] w-full resize-none rounded-b-2xl bg-slate-950 p-4 font-mono text-sm leading-6 outline-none" />
</Card>
<Card className="overflow-auto">
<div className="mb-4 font-medium">Vista previa</div>
<article className="prose prose-invert prose-slate">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
</article>
</Card>
</div>
</Shell>
);
}