Spaces:
Paused
Paused
File size: 3,197 Bytes
ec17af3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | "use client";
import { useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { SessionDocument } from "@/lib/documentReader";
import { cn } from "@/lib/utils";
type DocumentReaderPanelProps = {
title?: string;
document: SessionDocument | null;
activeBlockIndex?: number;
error?: string | null;
helperText?: string;
readOnly?: boolean;
onPickFile?: (file: File | null) => void;
onClear?: () => void;
};
export function DocumentReaderPanel({
title = "Reading Document",
document,
activeBlockIndex = -1,
error,
helperText,
readOnly = false,
onPickFile,
onClear,
}: DocumentReaderPanelProps) {
const blockRefs = useRef<(HTMLParagraphElement | null)[]>([]);
useEffect(() => {
if (activeBlockIndex < 0) return;
blockRefs.current[activeBlockIndex]?.scrollIntoView({
block: "nearest",
behavior: "smooth",
});
}, [activeBlockIndex]);
return (
<div className="rounded-3xl bg-white/80 p-5">
<div className="flex flex-wrap items-center justify-between gap-3">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.3em] text-ink/60">{title}</p>
<p className="mt-1 text-sm text-ink/60">
{document ? `${document.name} · ${document.blocks.length} blocks` : "Upload a PDF or TXT to read while recording."}
</p>
</div>
{!readOnly && (
<div className="flex flex-wrap items-center gap-2">
<Input
type="file"
accept=".pdf,.txt,application/pdf,text/plain"
onChange={(event) => onPickFile?.(event.target.files?.[0] || null)}
className="h-10 w-[220px]"
/>
{document && onClear && (
<Button type="button" variant="outline" size="sm" onClick={onClear}>
Clear
</Button>
)}
</div>
)}
</div>
{helperText && <p className="mt-3 text-xs text-ink/60">{helperText}</p>}
{error && <p className="mt-3 text-xs text-red-600">{error}</p>}
<div className="mt-4 max-h-80 overflow-y-auto rounded-3xl border border-ink/10 bg-white/75 p-4">
{!document && (
<div className="flex min-h-[180px] items-center justify-center text-center text-sm text-ink/55">
No reading document loaded yet.
</div>
)}
{document && (
<div className="space-y-3">
{document.blocks.map((block) => {
const isActive = block.index === activeBlockIndex;
return (
<p
key={block.index}
ref={(node) => {
blockRefs.current[block.index] = node;
}}
className={cn(
"rounded-2xl px-3 py-2 text-sm leading-7 text-ink/80 transition",
isActive ? "bg-amber-100 text-ink shadow-sm" : "bg-transparent"
)}
>
{block.text}
</p>
);
})}
</div>
)}
</div>
</div>
);
}
|