118 lines
3.7 KiB
TypeScript
118 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { Download, Eye, FileText } from "lucide-react";
|
|
|
|
type DocumentItem = {
|
|
id: number;
|
|
title: string;
|
|
file?: string;
|
|
mode: "preview" | "download" | "disabled";
|
|
};
|
|
|
|
type Props = {
|
|
items: DocumentItem[];
|
|
};
|
|
|
|
function getPreviewUrl(origin: string, file: string) {
|
|
const absoluteUrl = `${origin}/documents/${file}`;
|
|
const extension = file.split(".").pop()?.toLowerCase();
|
|
|
|
if (extension === "pdf") {
|
|
return `${absoluteUrl}#toolbar=0&navpanes=0&scrollbar=1`;
|
|
}
|
|
|
|
return `https://docs.google.com/gview?embedded=1&url=${encodeURIComponent(absoluteUrl)}`;
|
|
}
|
|
|
|
export function DocumentsViewer({ items }: Props) {
|
|
const firstPreviewable = items.find((item) => item.mode === "preview" && item.file) ?? null;
|
|
const [selectedId, setSelectedId] = useState<number>(firstPreviewable?.id ?? 0);
|
|
const [origin, setOrigin] = useState("");
|
|
|
|
useEffect(() => {
|
|
setOrigin(window.location.origin);
|
|
}, []);
|
|
|
|
const selectedItem =
|
|
items.find((item) => item.id === selectedId && item.mode === "preview" && item.file) ??
|
|
firstPreviewable;
|
|
|
|
return (
|
|
<div className="documents-layout">
|
|
<aside className="documents-sidebar">
|
|
<div className="documents-sidebar__panel">
|
|
{items.map((item) => {
|
|
if (item.mode === "download" && item.file) {
|
|
return (
|
|
<a
|
|
key={item.id}
|
|
href={`/documents/${item.file}`}
|
|
download
|
|
className="documents-link documents-link--download"
|
|
>
|
|
<Download size={16} />
|
|
<span>{item.title}</span>
|
|
</a>
|
|
);
|
|
}
|
|
|
|
if (item.mode === "disabled") {
|
|
return (
|
|
<div key={item.id} className="documents-link documents-link--disabled">
|
|
<FileText size={16} />
|
|
<span>{item.title}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<button
|
|
key={item.id}
|
|
type="button"
|
|
onClick={() => setSelectedId(item.id)}
|
|
className={`documents-link documents-link--button${
|
|
selectedItem?.id === item.id ? " documents-link--active" : ""
|
|
}`}
|
|
>
|
|
<Eye size={16} />
|
|
<span>{item.title}</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</aside>
|
|
|
|
<div className="documents-content">
|
|
<article className="page-panel documents-preview">
|
|
<div className="documents-preview__header">
|
|
<div>
|
|
<span className="eyebrow">Просмотр документа</span>
|
|
<h2>{selectedItem?.title ?? "Документ не выбран"}</h2>
|
|
</div>
|
|
<div className="documents-preview__note">
|
|
<FileText size={18} />
|
|
<span>Для просмотра используйте список слева</span>
|
|
</div>
|
|
</div>
|
|
|
|
{selectedItem?.file && origin ? (
|
|
<div className="documents-preview__frame">
|
|
<iframe
|
|
key={`${origin}-${selectedItem.file}`}
|
|
src={getPreviewUrl(origin, selectedItem.file)}
|
|
title={selectedItem.title}
|
|
className="documents-preview__iframe"
|
|
/>
|
|
</div>
|
|
) : (
|
|
<div className="documents-preview__empty">
|
|
Документ загрузится после открытия страницы в браузере.
|
|
</div>
|
|
)}
|
|
</article>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|