Replace plain textarea with shared tiptap editor and sanitized html rendering. Adds interactive checklists on read surfaces and mobile overflow fixes.
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { FileText, Pin } from "lucide-react";
|
|
import { RichTextContent } from "@/components/rich-text";
|
|
import { ShareEyebrow } from "@/components/share/share-eyebrow";
|
|
import type { NoteShareData } from "../server/share-queries";
|
|
import { toggleShareNoteChecklistItem } from "../server/checklist-actions";
|
|
|
|
type Props = {
|
|
data: NoteShareData;
|
|
canWrite?: boolean;
|
|
token?: string;
|
|
};
|
|
|
|
export function NoteSharedView({ data, canWrite = false, token }: Props) {
|
|
const updated = new Date(data.updatedAt).toLocaleDateString(undefined, {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<ShareEyebrow>
|
|
<FileText className="size-3" />
|
|
Note
|
|
</ShareEyebrow>
|
|
<h1
|
|
className="serif"
|
|
style={{
|
|
fontSize: "clamp(28px, 6vw, 38px)",
|
|
lineHeight: 1.15,
|
|
letterSpacing: "-0.02em",
|
|
color: "var(--ink)",
|
|
margin: "0 0 8px",
|
|
textWrap: "pretty",
|
|
}}
|
|
>
|
|
{data.title}
|
|
</h1>
|
|
<p className="muted text-[13px] mb-6 inline-flex items-center gap-2">
|
|
{data.pinned && (
|
|
<span className="inline-flex items-center gap-1">
|
|
<Pin className="size-3 text-[var(--accent)]" />
|
|
Pinned
|
|
</span>
|
|
)}
|
|
{data.pinned && <span>·</span>}
|
|
<span>Updated {updated}</span>
|
|
</p>
|
|
|
|
{data.body ? (
|
|
<RichTextContent
|
|
html={data.body}
|
|
interactiveChecklists={canWrite && !!token}
|
|
onToggleChecklist={
|
|
canWrite && token
|
|
? async (taskIndex, checked) => {
|
|
await toggleShareNoteChecklistItem(token, data.id, taskIndex, checked);
|
|
}
|
|
: undefined
|
|
}
|
|
/>
|
|
) : null}
|
|
</>
|
|
);
|
|
}
|