2025-09-09 14:51:23 +02:00
|
|
|
import dynamic from "next/dynamic";
|
2025-08-28 18:27:07 +02:00
|
|
|
import { useEffect, useRef, useState } from "react";
|
|
|
|
|
import { LoadingPage } from "~/components/loading";
|
2025-08-04 17:45:44 +02:00
|
|
|
import { cn } from "~/lib/utils";
|
2025-10-24 16:10:59 +02:00
|
|
|
import type { FileMetadata } from "~/server/services/storage.service";
|
2025-08-04 17:45:44 +02:00
|
|
|
|
2025-09-09 14:51:23 +02:00
|
|
|
const PDFViewer = dynamic(
|
|
|
|
|
() => import("./pdf-viewer").then((mod) => mod.PDFViewer),
|
|
|
|
|
{
|
|
|
|
|
ssr: false,
|
|
|
|
|
loading: () => <LoadingPage />,
|
|
|
|
|
},
|
|
|
|
|
);
|
2025-08-04 17:45:44 +02:00
|
|
|
export const AllegatoIframe = ({
|
2025-08-28 18:27:07 +02:00
|
|
|
className,
|
|
|
|
|
allegato,
|
2025-08-04 17:45:44 +02:00
|
|
|
}: {
|
2025-08-28 18:27:07 +02:00
|
|
|
className?: string;
|
2025-10-24 16:10:59 +02:00
|
|
|
allegato: FileMetadata;
|
2025-08-04 17:45:44 +02:00
|
|
|
}) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
const if_ref = useRef<HTMLIFrameElement>(null);
|
2025-10-24 16:10:59 +02:00
|
|
|
|
2025-09-09 14:51:23 +02:00
|
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
|
const [isIOS, setIsIOS] = useState(false);
|
|
|
|
|
const [isPDF, setIsPDF] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// Detect mobile and iOS
|
|
|
|
|
const userAgent = navigator.userAgent.toLowerCase();
|
|
|
|
|
setIsMobile(
|
|
|
|
|
/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(
|
|
|
|
|
userAgent,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
setIsIOS(/iphone|ipad|ipod/i.test(userAgent));
|
|
|
|
|
|
|
|
|
|
// Try to detect if file is PDF from extension
|
2025-10-24 16:10:59 +02:00
|
|
|
setIsPDF(allegato.mimeType === "application/pdf");
|
2025-09-09 14:51:23 +02:00
|
|
|
}, [allegato]);
|
|
|
|
|
|
2025-08-28 18:27:07 +02:00
|
|
|
const handleIframeLoad = () => {
|
|
|
|
|
if (if_ref.current?.contentWindow) {
|
2025-09-09 14:51:23 +02:00
|
|
|
// For images
|
2025-08-28 18:27:07 +02:00
|
|
|
const img = if_ref.current.contentWindow.document.querySelector("img");
|
|
|
|
|
if (img) {
|
|
|
|
|
img.style.width = "100%";
|
|
|
|
|
img.style.height = "100%";
|
|
|
|
|
img.style.objectFit = "contain";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-09-09 14:51:23 +02:00
|
|
|
|
2025-10-24 16:10:59 +02:00
|
|
|
const requestUrl = `/storage-api/get/${allegato.id}?mode=inline`;
|
2025-09-09 14:51:23 +02:00
|
|
|
// For PDF on iOS, provide download link instead
|
|
|
|
|
if (isPDF && (isIOS || isMobile)) {
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"flex h-full w-full items-center justify-center object-contain",
|
|
|
|
|
className,
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<PDFViewer url={requestUrl} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
|
2025-08-28 18:27:07 +02:00
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"flex h-full w-full items-center justify-center object-contain",
|
|
|
|
|
className,
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
{/** biome-ignore lint/a11y/noNoninteractiveElementInteractions: <need interaction> */}
|
|
|
|
|
<iframe
|
2025-08-29 16:18:32 +02:00
|
|
|
allowFullScreen
|
2025-08-28 18:27:07 +02:00
|
|
|
className="h-full w-full"
|
|
|
|
|
onLoad={handleIframeLoad}
|
2025-08-29 16:18:32 +02:00
|
|
|
ref={if_ref}
|
|
|
|
|
src={requestUrl}
|
|
|
|
|
title="Allegato"
|
2025-08-28 18:27:07 +02:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|