47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* A passage shared from the library, rendered as a quotation.
|
|
*
|
|
* Tapping it returns the reader to the exact phrase: the stored path carries
|
|
* the `?hl=` fragment that TextHighlighter resolves on arrival, scrolling to
|
|
* the passage and flashing it.
|
|
*
|
|
* The path is always app-relative — the BFF rejects anything else — so this
|
|
* can navigate with the router rather than leaving the app.
|
|
*
|
|
* Styling is deliberately bare. This sits INSIDE a chat bubble, which already
|
|
* supplies the padding, the background and the rounding; giving the quote its
|
|
* own would draw a second bubble within the first. A left rule and italics are
|
|
* enough to say "quotation", and every colour is inherited so the same markup
|
|
* reads correctly on your own primary-coloured bubble and on the muted one
|
|
* opposite.
|
|
*/
|
|
|
|
import { useRouter } from "next/navigation";
|
|
import type { Attachment } from "@/lib/chat";
|
|
|
|
export function QuoteCard({ attachment }: { attachment: Attachment }) {
|
|
const router = useRouter();
|
|
const path = attachment.url ?? "";
|
|
const passage = attachment.description ?? "";
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={() => path && router.push(path)}
|
|
disabled={!path}
|
|
className="block w-full border-l-2 border-current/30 pl-2.5 text-left transition-opacity hover:opacity-80 disabled:cursor-default disabled:hover:opacity-100"
|
|
>
|
|
{/* The passage leads; the citation follows in the quieter role a
|
|
reference normally takes. */}
|
|
<span className="block text-sm italic leading-snug">{passage}</span>
|
|
{attachment.title && (
|
|
<span className="mt-0.5 block truncate text-xs opacity-70">
|
|
{attachment.title}
|
|
</span>
|
|
)}
|
|
</button>
|
|
);
|
|
}
|