Files
duocthu/apps/web/app/tra-cuu/page.tsx
T

91 lines
3.6 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { BookOpen, Bookmark, FileText, Sparkles } from "lucide-react";
import type { ChatMessage, Citation } from "@duoc-thu/shared-types";
import { ChatPanel } from "../_components/ChatPanel";
import { cn } from "@duoc-thu/ui";
export default function TraCuuPage() {
const [activePage, setActivePage] = useState<number | null>(null);
const [activeDrug, setActiveDrug] = useState<string | null>(null);
const [pdfSrc, setPdfSrc] = useState("/api/pdf");
const [sessionId, setSessionId] = useState("");
const [messages, setMessages] = useState<ChatMessage[]>([]);
useEffect(() => {
setSessionId(`lookup-${crypto.randomUUID()}`);
}, []);
function handleCitationClick(citation: Citation) {
if (citation.sourcePageRange && citation.sourcePageRange[0]) {
// Display the printed page (what's on the paper page, matches the
// clinician's physical copy), but navigate the PDF viewer by the
// physical page — they diverge by 1-3 pages depending on front-matter
// offset, confirmed against the real PDF (physical_page is PyMuPDF's
// 0-indexed page; the #page= fragment is 1-indexed).
setActivePage(citation.sourcePageRange[0]);
setActiveDrug(citation.drugName);
setPdfSrc(`/api/pdf#page=${citation.physicalPage + 1}`);
}
}
return (
<div className="flex flex-1 w-full h-[calc(100vh-6.5rem)] p-4 sm:p-6 overflow-hidden bg-app gap-4">
{/* PDF Document Reader Pane */}
<div className="flex flex-[1.3] flex-col overflow-hidden rounded-2xl border border-border-subtle bg-surface shadow-sm">
{/* Viewer Header */}
<div className="flex items-center justify-between border-b border-border-subtle bg-surface-elevated px-4 py-2.5">
<div className="flex items-center gap-2">
<BookOpen className="h-4 w-4 text-accent-primary" />
<span className="text-xs font-bold text-txt-primary">
Văn bản gốc: Dược thư quốc gia Việt Nam 2018 (PDF)
</span>
</div>
{activePage ? (
<div className="flex items-center gap-1.5 rounded-lg border border-border-accent bg-accent-soft px-2.5 py-1 text-xs font-bold text-accent-primary">
<Bookmark className="h-3.5 w-3.5" />
<span>
{activeDrug ? `${activeDrug}` : ""}Trang {activePage}
</span>
</div>
) : (
<div className="flex items-center gap-1 text-xs text-txt-muted">
<FileText className="h-3.5 w-3.5" />
<span>1.668 trang PDF</span>
</div>
)}
</div>
{/* Embedded PDF Viewer */}
<div className="relative flex-1 bg-surface-elevated">
<iframe
key={pdfSrc}
src={pdfSrc}
title="Dược thư quốc gia Việt Nam 2018"
className="h-full w-full border-none"
/>
</div>
</div>
{/* AI Assistant Chat Pane */}
<div className="flex flex-1 flex-col overflow-hidden">
<div className="mb-2 flex items-center gap-1.5 px-1 text-xs font-medium text-txt-muted">
<Sparkles className="h-3.5 w-3.5 text-accent-primary" />
<span>Bấm vào Trích Nguồn bên dưới đ nhảy trực tiếp tới trang PDF tương ng</span>
</div>
{sessionId && (
<ChatPanel
sessionId={sessionId}
messages={messages}
onMessagesChange={setMessages}
className="flex-1 h-full"
onCitationClick={handleCitationClick}
/>
)}
</div>
</div>
);
}