upd: view file project
Deskripsi - install package pdf - layout modal file - ganti route api image No Issues
This commit is contained in:
84
src/module/_global/components/pdf_viewer.tsx
Normal file
84
src/module/_global/components/pdf_viewer.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist';
|
||||
import { Image, Skeleton, Stack } from '@mantine/core';
|
||||
|
||||
GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.6.82/pdf.worker.min.mjs';
|
||||
|
||||
const PdfToImage = ({ md }: { md: string }) => {
|
||||
const [images, setImages] = useState<string[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const renderPages = async () => {
|
||||
try {
|
||||
const loadingTask = getDocument(md); // Menggunakan md sebagai URL PDF
|
||||
const pdf = await loadingTask.promise;
|
||||
const numPages = pdf.numPages;
|
||||
const imagePromises: Promise<string>[] = [];
|
||||
|
||||
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
|
||||
const renderPage = async (pageNum: number): Promise<string> => {
|
||||
const page = await pdf.getPage(pageNum);
|
||||
const viewport = page.getViewport({ scale: 2.0 });
|
||||
|
||||
// Buat elemen canvas
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
if (context) {
|
||||
canvas.width = viewport.width;
|
||||
canvas.height = viewport.height;
|
||||
|
||||
// Render halaman PDF ke dalam canvas
|
||||
const renderContext = {
|
||||
canvasContext: context,
|
||||
viewport: viewport,
|
||||
};
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
// Konversi canvas ke gambar (data URL)
|
||||
return canvas.toDataURL('image/png');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
imagePromises.push(renderPage(pageNum));
|
||||
}
|
||||
|
||||
const imageSrcs = await Promise.all(imagePromises);
|
||||
setImages(imageSrcs);
|
||||
} catch (error) {
|
||||
console.error('Error rendering PDF to images:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
renderPages();
|
||||
}
|
||||
}, [md]);
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
{loading
|
||||
? <CustomLoading />
|
||||
: images.map((src, index) => (
|
||||
<Image key={index} src={src} alt={`Page ${index + 1}`} />
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
function CustomLoading() {
|
||||
return (
|
||||
<Stack p="md">
|
||||
{[...Array(3)].map((_, index) => (
|
||||
<Skeleton key={index} height={200} />
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
export default PdfToImage
|
||||
@@ -10,6 +10,7 @@ import LayoutDrawer from "./layout/layout_drawer";
|
||||
import LayoutIconBack from "./layout/layout_icon_back";
|
||||
import LoadingPage from "./layout/layout_loading_page";
|
||||
import LayoutLogin from "./layout/layout_login";
|
||||
import LayoutModalViewFile from "./layout/layout_modal_view_file";
|
||||
import LayoutNavbarHome from "./layout/layout_navbar_home";
|
||||
import LayoutNavbarNew from "./layout/layout_navbar_new";
|
||||
import ViewFilter from "./view/view_filter";
|
||||
@@ -29,3 +30,4 @@ export { SkeletonDetailDiscussionComment }
|
||||
export { SkeletonDetailDiscussionMember }
|
||||
export { SkeletonDetailProfile }
|
||||
export { SkeletonDetailListTugasTask }
|
||||
export { LayoutModalViewFile }
|
||||
|
||||
34
src/module/_global/layout/layout_modal_view_file.tsx
Normal file
34
src/module/_global/layout/layout_modal_view_file.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
'use client'
|
||||
import { Image, Modal } from '@mantine/core';
|
||||
import dynamic from 'next/dynamic';
|
||||
import React, { useState } from 'react';
|
||||
const PdfToImage = dynamic(() => import('./../components/pdf_viewer').then((mod) => mod.default), { ssr: false });
|
||||
|
||||
export default function LayoutModal({ opened, onClose, extension, fitur, file }: { opened: boolean, onClose: () => void, extension: string, fitur: string, file: string }) {
|
||||
const [isValModal, setValModal] = useState(opened)
|
||||
const filePdf = '/file/' + fitur + '/' + file
|
||||
return (
|
||||
<Modal styles={{
|
||||
body: {
|
||||
margin: 10,
|
||||
},
|
||||
content: {
|
||||
border: `2px solid ${'#828AFC'}`,
|
||||
borderRadius: 10
|
||||
}
|
||||
}} opened={opened} onClose={onClose} withCloseButton={true} centered closeOnClickOutside={false}>
|
||||
|
||||
{
|
||||
extension === 'pdf' ? <PdfToImage md={filePdf} /> :
|
||||
<Image
|
||||
radius="md"
|
||||
h={200}
|
||||
w="auto"
|
||||
fit="contain"
|
||||
src={`/api/file/img?cat=${fitur}&file=${file}&jenis=file`}
|
||||
/>
|
||||
}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user