Add components for Act management and integrate Electron setup
This commit is contained in:
190
components/ExportBook.tsx
Normal file
190
components/ExportBook.tsx
Normal file
@@ -0,0 +1,190 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user