48 lines
1.7 KiB
TypeScript
48 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.
|
|
*/
|
|
|
|
import { useRouter } from "next/navigation";
|
|
import { Quote } from "lucide-react";
|
|
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="mt-1 block w-full rounded-lg border-l-2 border-primary bg-primary/5 px-3 py-2 text-left transition-colors hover:bg-primary/10 disabled:cursor-default disabled:hover:bg-primary/5"
|
|
>
|
|
<span className="flex items-start gap-2">
|
|
<Quote className="mt-0.5 size-3.5 shrink-0 text-primary" aria-hidden />
|
|
<span className="min-w-0 flex-1">
|
|
{/* The passage is the point, so it leads; the reference follows in
|
|
the quieter role a citation normally takes. */}
|
|
<span className="block text-sm italic leading-relaxed text-foreground">
|
|
{passage}
|
|
</span>
|
|
{attachment.title && (
|
|
<span className="mt-1 block truncate text-xs font-medium text-primary">
|
|
{attachment.title}
|
|
</span>
|
|
)}
|
|
</span>
|
|
</span>
|
|
</button>
|
|
);
|
|
}
|