(front) add standalone file preview

We were tired of using the raw default previewer of the browser, that
was also triggering downloads instead of preview sometimes.
This commit is contained in:
Nathan Vasse
2025-09-16 16:02:32 +02:00
parent d208033d49
commit d3ca608ef4
2 changed files with 76 additions and 0 deletions
@@ -274,6 +274,11 @@
"submit": "Edit"
}
},
"files": {
"not_found": {
"description": "The file you are looking for does not exist."
}
},
"workspaces": {
"mainWorkspace": "My workspace",
"form": {
@@ -647,6 +652,11 @@
"submit": "Mettre à jour"
}
},
"files": {
"not_found": {
"description": "Le fichier que vous recherchez n'existe pas."
}
},
"workspaces": {
"mainWorkspace": "Mon espace",
"form": {
@@ -0,0 +1,66 @@
import { APIError } from "@/features/api/APIError";
import { getDriver } from "@/features/config/Config";
import { Item } from "@/features/drivers/types";
import { itemToPreviewFile } from "@/features/explorer/utils/utils";
import { ItemInfo } from "@/features/items/components/ItemInfo";
import { useDownloadItem } from "@/features/items/hooks/useDownloadItem";
import { GenericDisclaimer } from "@/features/ui/components/generic-disclaimer/GenericDisclaimer";
import { SpinnerPage } from "@/features/ui/components/spinner/SpinnerPage";
import { FilePreview } from "@/features/ui/preview/files-preview/FilesPreview";
import { Icon } from "@gouvfr-lasuite/ui-kit";
import { Button } from "@openfun/cunningham-react";
import { useQuery } from "@tanstack/react-query";
import { useRouter } from "next/router";
import { useTranslation } from "react-i18next";
export default function FilePage() {
const { t } = useTranslation();
const router = useRouter();
const itemId = router.query.id as string;
const { handleDownloadItem } = useDownloadItem();
// On 403, 401, the user is automatically redirected to the 401/403 page.
const {
data: item,
isLoading,
error,
} = useQuery<Item, APIError>({
queryKey: ["items", itemId],
queryFn: async () => {
return getDriver().getItem(itemId);
},
});
// If the error is a 401 or 403, we want to show the spinner page because an auto redirect is happening.
if (isLoading || (error && [401, 403].includes(error.code))) {
return <SpinnerPage />;
}
// Can happen if the file is deleted.
if (!item) {
return (
<GenericDisclaimer
message={t("explorer.files.not_found.description")}
imageSrc="/assets/403-background.png"
>
<Button href="/" icon={<Icon name="home" />}>
{t("403.button")}
</Button>
</GenericDisclaimer>
);
}
return (
<div>
<FilePreview
isOpen={true}
hideCloseButton={true}
hideNav={true}
title={t("file_preview.title")}
files={[itemToPreviewFile(item)]}
onChangeFile={() => void 0}
handleDownloadFile={() => handleDownloadItem(item)}
openedFileId={item.id}
sidebarContent={item && <ItemInfo item={item} />}
/>
</div>
);
}