diff --git a/frontend/src/components/common/DownloadMenu.tsx b/frontend/src/components/common/DownloadMenu.tsx
index bb9e92a1..1b911a57 100644
--- a/frontend/src/components/common/DownloadMenu.tsx
+++ b/frontend/src/components/common/DownloadMenu.tsx
@@ -1,6 +1,6 @@
import { SaveAlt as SaveAltIcon } from "@mui/icons-material";
import { IconButton, Menu, MenuItem, Paper } from "@mui/material";
-import { MouseEvent, useCallback, useState } from "react";
+import { MouseEvent, useState } from "react";
import { useFileExport } from "../../hooks/useFileExport";
const DownloadMenu = () => {
@@ -14,22 +14,7 @@ const DownloadMenu = () => {
setAnchorEl(null);
};
- const { exportToPDF, exportToTXT, exportToDOCX } = useFileExport();
-
- const handleExportToPDF = useCallback(() => {
- exportToPDF();
- handleClose();
- }, [exportToPDF]);
-
- const handleExportToTXT = useCallback(() => {
- exportToTXT();
- handleClose();
- }, [exportToTXT]);
-
- const handleExportToDOCX = useCallback(() => {
- exportToDOCX();
- handleClose();
- }, [exportToDOCX]);
+ const { handleExportToPDF, handleExportToHTML, handleExportToMarkdown } = useFileExport();
return (
@@ -44,8 +29,8 @@ const DownloadMenu = () => {
onClose={handleClose}
>
-
-
+
+
);
diff --git a/frontend/src/hooks/useFileExport.ts b/frontend/src/hooks/useFileExport.ts
index 3f9c52e4..1b87616b 100644
--- a/frontend/src/hooks/useFileExport.ts
+++ b/frontend/src/hooks/useFileExport.ts
@@ -1,77 +1,75 @@
-import { Document, Packer, Paragraph, TextRun } from "docx";
-import { saveAs } from "file-saver";
-import jspdfHtml2canvas from "jspdf-html2canvas";
+import axios from "axios";
import { useSnackbar } from "notistack";
-import { useCallback, useContext } from "react";
+import { useCallback } from "react";
import { useSelector } from "react-redux";
-import { PreviewRefContext } from "../contexts/PreviewRefContext";
+import { selectDocument } from "../store/documentSlice";
import { selectEditor } from "../store/editorSlice";
-import { documentNameStorage } from "../utils/localStorage";
-interface useFileExportReturn {
- exportToPDF: () => Promise;
- exportToTXT: () => void;
- exportToDOCX: () => void;
+export const enum FileExtension {
+ Markdown = "markdown",
+ HTML = "html",
+ PDF = "pdf",
}
-export const useFileExport = (): useFileExportReturn => {
- const editorStore = useSelector(selectEditor);
- const markdown = editorStore.doc?.getRoot().content?.toString() || "";
-
- const { previewRef } = useContext(PreviewRefContext);
+interface UseFileExportReturn {
+ handleExportToPDF: () => void;
+ handleExportToHTML: () => void;
+ handleExportToMarkdown: () => void;
+}
+export const useFileExport = (): UseFileExportReturn => {
const { enqueueSnackbar } = useSnackbar();
+ const editorStore = useSelector(selectEditor);
+ const documentStore = useSelector(selectDocument);
- const documentName = documentNameStorage.getDocumentName() || 'codepair_document';
+ const markdown = editorStore.doc?.getRoot().content?.toString() || "";
+ const documentName = documentStore.data?.title || "codepair_document";
- const exportToPDF = useCallback(async () => {
- if (previewRef.current?.mdp && previewRef.current.mdp.current instanceof HTMLDivElement) {
+ const handleExportFile = useCallback(
+ async (exportType: string) => {
try {
- await jspdfHtml2canvas(previewRef.current.mdp.current, {
- output: `${documentName}`,
- jsPDF: {
- format: "a4",
- orientation: "portrait",
- },
- html2canvas: {
- scale: 3,
+ enqueueSnackbar(`${exportType.toUpperCase()} 파일 내보내기 시작...`, {
+ variant: "info",
+ });
+
+ const response = await axios.post(
+ "/files/export-markdown",
+ {
+ exportType,
+ content: markdown,
+ fileName: documentName,
},
+ {
+ responseType: "blob",
+ }
+ );
+
+ const blob = new Blob([response.data], { type: `application/${exportType}` });
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement("a");
+ link.href = url;
+ link.setAttribute("download", `${encodeURIComponent(documentName)}.${exportType}`);
+ document.body.appendChild(link);
+ link.click();
+ if (link.parentNode) link.parentNode.removeChild(link);
+ window.URL.revokeObjectURL(url);
+
+ enqueueSnackbar(`${exportType.toUpperCase()} 파일이 성공적으로 내보내졌습니다.`, {
+ variant: "success",
});
} catch (error) {
- if(previewRef.current.mdp.current) {
- enqueueSnackbar("Content is empty", { variant: "error" });
- } else {
- enqueueSnackbar("Failed to export PDF", { variant: "error" });
- }
+ console.error("오류:", error);
+ enqueueSnackbar(`${exportType.toUpperCase()} 파일 내보내기에 실패했습니다.`, {
+ variant: "error",
+ });
}
- } else {
- enqueueSnackbar("Please try again", { variant: "error" });
- }
- }, [previewRef, enqueueSnackbar, documentName]);
-
- const exportToTXT = useCallback(() => {
- const blob = new Blob([markdown], { type: "text/plain;charset=utf-8" });
- saveAs(blob, documentName);
- }, [documentName, markdown]);
-
- const exportToDOCX = useCallback(() => {
- const doc = new Document({
- sections: [
- {
- properties: {},
- children: [
- new Paragraph({
- children: [new TextRun(markdown)],
- }),
- ],
- },
- ],
- });
+ },
+ [markdown, documentName, enqueueSnackbar]
+ );
- Packer.toBlob(doc).then((blob) => {
- saveAs(blob, documentName);
- });
- }, [markdown, documentName]);
+ const handleExportToPDF = () => handleExportFile(FileExtension.PDF);
+ const handleExportToHTML = () => handleExportFile(FileExtension.HTML);
+ const handleExportToMarkdown = () => handleExportFile(FileExtension.Markdown);
- return { exportToPDF, exportToTXT, exportToDOCX };
+ return { handleExportToPDF, handleExportToHTML, handleExportToMarkdown };
};