Files
ERitors-Scribe-Desktop/components/ExportBook.tsx

190 lines
6.3 KiB
TypeScript

import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faDownload} from "@fortawesome/free-solid-svg-icons";
import React, {useContext, useRef, useState} from "react";
import {SessionContext} from "@/context/SessionContext";
import {AlertContext} from "@/context/AlertContext";
import {configs} from "@/lib/configs";
interface CreateEpubProps {
bookId: string;
bookTitle: string;
}
export default function ExportBook({bookId, bookTitle}: CreateEpubProps) {
const {session} = useContext(SessionContext);
const {successMessage, errorMessage} = useContext(AlertContext);
const [showMenu, setShowMenu] = useState(false);
const menuRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
function handleClickOutside(event: MouseEvent): void {
if (
menuRef.current &&
buttonRef.current &&
!menuRef.current.contains(event.target as Node) &&
!buttonRef.current.contains(event.target as Node)
) {
setShowMenu(false);
document.removeEventListener("mousedown", handleClickOutside);
}
}
function toggleMenu(): void {
if (!showMenu) {
setTimeout((): void => {
document.addEventListener("mousedown", handleClickOutside);
}, 0);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
setShowMenu(!showMenu);
}
async function handleDownloadEpub() {
try {
const response = await fetch(
`${configs.apiUrl}book/transform/epub?id=${bookId}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
}
);
if (!response.ok) {
errorMessage(`Échec du téléchargement du EPUB.`);
return;
}
const blob = await response.blob();
const virtualUrl = window.URL.createObjectURL(blob);
const aLink = document.createElement("a");
aLink.href = virtualUrl;
aLink.download = `${bookTitle}.epub`;
document.body.appendChild(aLink);
aLink.click();
aLink.remove();
window.URL.revokeObjectURL(virtualUrl);
setShowMenu(false);
successMessage(`Votre fichier EPUB a été téléchargé.`);
} catch (error) {
console.error(`Error downloading EPUB:`, error);
errorMessage(`Une erreur est survenue lors du téléchargement.`);
}
}
async function handleDownloadPdf() {
try {
const response = await fetch(
`${configs.apiUrl}book/transform/pdf?id=${bookId}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
}
);
if (!response.ok) {
errorMessage(`Échec du téléchargement du PDF.`);
return;
}
const blob = await response.blob();
const virtualUrl = window.URL.createObjectURL(blob);
const aLink = document.createElement("a");
aLink.href = virtualUrl;
aLink.download = `${bookTitle}.pdf`;
document.body.appendChild(aLink);
aLink.click();
aLink.remove();
window.URL.revokeObjectURL(virtualUrl);
setShowMenu(false);
successMessage(`Votre fichier PDF a été téléchargé.`);
} catch (error) {
console.error(`Error downloading PDF:`, error);
errorMessage(`Une erreur est survenue lors du téléchargement.`);
}
}
async function handleDownloadDocx() {
try {
const response = await fetch(
`${configs.apiUrl}book/transform/docx?id=${bookId}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
}
);
if (!response.ok) {
errorMessage(`Échec du téléchargement du DOCX.`);
return;
}
const blob = await response.blob();
const virtualUrl = window.URL.createObjectURL(blob);
const aLink = document.createElement("a");
aLink.href = virtualUrl;
aLink.download = `${bookTitle}.docx`;
document.body.appendChild(aLink);
aLink.click();
aLink.remove();
window.URL.revokeObjectURL(virtualUrl);
setShowMenu(false);
successMessage(`Votre fichier DOCX a été téléchargé.`);
} catch (error) {
console.error(`Error downloading DOCX:`, error);
errorMessage(`Une erreur est survenue lors du téléchargement.`);
}
}
return (
<div className="relative">
<button
ref={buttonRef}
onClick={toggleMenu}
className="text-muted hover:text-primary transition-all duration-200 p-1.5 rounded-lg hover:bg-secondary/50 hover:scale-110"
>
<FontAwesomeIcon icon={faDownload} className={'w-4 h-4'}/>
</button>
{showMenu && (
<div
ref={menuRef}
className="absolute z-50 bg-tertiary/90 backdrop-blur-sm shadow-2xl rounded-xl border border-secondary/50"
style={{
width: '110px',
right: '-30px',
top: '100%',
marginTop: '8px',
}}
>
<ul className="py-2">
<li
className="px-3 py-2 hover:bg-secondary cursor-pointer text-sm text-muted hover:text-text-primary transition-all duration-200 hover:scale-105 font-medium"
onClick={handleDownloadEpub}
>
EPUB
</li>
<li
className="px-3 py-2 hover:bg-secondary cursor-pointer text-sm text-muted hover:text-text-primary transition-all duration-200 hover:scale-105 font-medium"
onClick={handleDownloadPdf}
>
PDF
</li>
<li
className="px-3 py-2 hover:bg-secondary cursor-pointer text-sm text-muted hover:text-text-primary transition-all duration-200 hover:scale-105 font-medium"
onClick={handleDownloadDocx}
>
DOCX
</li>
</ul>
</div>
)}
</div>
);
}