✨(app-impress) print to pdf
Feature to print the pad to pdf. It display a button in the pad toolbar, when clicked it will convert the pad to markdown, send the markdown with a template to the backend to convert it to pdf and then download the pdf.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import { Pad } from '@/features/pads/pad';
|
||||
|
||||
import PrintToPDFButton from './PrintToPDFButton';
|
||||
|
||||
interface PadToolBoxProps {
|
||||
pad: Pad;
|
||||
}
|
||||
|
||||
export const PadToolBox = ({ pad }: PadToolBoxProps) => {
|
||||
return (
|
||||
<Box className="m-b" $align="flex-end">
|
||||
<PrintToPDFButton pad={pad} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
Button,
|
||||
VariantType,
|
||||
useToastProvider,
|
||||
} from '@openfun/cunningham-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Pad, usePadStore } from '@/features/pads/pad';
|
||||
|
||||
import { useCreatePdfFromMarkdown } from '../api/useCreatePdfFromMarkdown';
|
||||
import { downloadFile } from '../utils';
|
||||
|
||||
interface PrintToPDFButtonProps {
|
||||
pad: Pad;
|
||||
}
|
||||
|
||||
const PrintToPDFButton = ({ pad }: PrintToPDFButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [isFetching, setIsFetching] = useState(false);
|
||||
const { toast } = useToastProvider();
|
||||
const { padsStore } = usePadStore();
|
||||
const {
|
||||
mutate: createPdfFromMarkdown,
|
||||
data: pdf,
|
||||
isSuccess,
|
||||
isPending,
|
||||
error,
|
||||
} = useCreatePdfFromMarkdown();
|
||||
|
||||
useEffect(() => {
|
||||
setIsFetching(isPending);
|
||||
}, [isPending]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!error) {
|
||||
return;
|
||||
}
|
||||
|
||||
toast(error.message, VariantType.ERROR);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [error, t]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!pdf || !isSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
downloadFile(pdf, 'impress-document.pdf');
|
||||
setIsFetching(false);
|
||||
|
||||
toast(t('Your pdf was downloaded succesfully'), VariantType.SUCCESS);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pdf, isSuccess, t]);
|
||||
|
||||
async function onSubmit() {
|
||||
const editor = padsStore[pad.id].editor;
|
||||
|
||||
if (!editor) {
|
||||
toast(t('No editor found'), VariantType.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
const markdown = await editor.blocksToMarkdownLossy(editor.document);
|
||||
|
||||
createPdfFromMarkdown({
|
||||
templateId: '472d0633-20b8-4cb1-998a-1134ade092ba',
|
||||
markdown,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
onClick={() => void onSubmit()}
|
||||
style={{
|
||||
width: 'fit-content',
|
||||
}}
|
||||
disabled={isFetching}
|
||||
>
|
||||
{t('Print the pad')}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default PrintToPDFButton;
|
||||
@@ -0,0 +1 @@
|
||||
export * from './PadToolBox';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './components/';
|
||||
@@ -0,0 +1,11 @@
|
||||
export function downloadFile(blob: Blob, filename: string) {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
|
||||
import { Card, Text } from '@/components';
|
||||
|
||||
import { PadToolBox } from '../../pad-tools';
|
||||
import { Pad } from '../types';
|
||||
|
||||
import { BlockNoteEditor } from './BlockNoteEditor';
|
||||
@@ -12,9 +13,14 @@ interface PadEditorProps {
|
||||
|
||||
export const PadEditor = ({ pad }: PadEditorProps) => {
|
||||
return (
|
||||
<Card className="m-b p-b" $height="100%">
|
||||
<Text as="h2">{pad.name}</Text>
|
||||
<BlockNoteEditor pad={pad} />
|
||||
</Card>
|
||||
<>
|
||||
<PadToolBox pad={pad} />
|
||||
<Card className="m-b p-b" $css="margin-top:0;flex:1;" $overflow="auto">
|
||||
<Text as="h2" $align="center">
|
||||
{pad.name}
|
||||
</Text>
|
||||
<BlockNoteEditor pad={pad} />
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user