diff --git a/zubhub_frontend/zubhub/package.json b/zubhub_frontend/zubhub/package.json index a62f22e7e..70d5c4665 100644 --- a/zubhub_frontend/zubhub/package.json +++ b/zubhub_frontend/zubhub/package.json @@ -28,6 +28,7 @@ "lodash": "^4.17.21", "nanoid": "^3.3.1", "pdfmake": "^0.2.7", + "qrcode.react": "^3.1.0", "quill": "^1.3.7", "react": "^17.0.1", "react-confetti": "^6.1.0", diff --git a/zubhub_frontend/zubhub/public/locales/en/translation.json b/zubhub_frontend/zubhub/public/locales/en/translation.json index da061c5b4..8e79ed430 100644 --- a/zubhub_frontend/zubhub/public/locales/en/translation.json +++ b/zubhub_frontend/zubhub/public/locales/en/translation.json @@ -1132,6 +1132,14 @@ "label": "save button", "save": "save", "unsave": "unsave" + }, + "pdfDetails":{ + "introduction": "Introduction", + "category": "Category", + "classHeading": "Class Grade", + "materials": "Materials Used", + "shareActivity": "SHARE THIS ACTIVITY", + "qrHeading": "Scan code to view activity" } }, "breadCrumb":{ diff --git a/zubhub_frontend/zubhub/public/locales/hi/translation.json b/zubhub_frontend/zubhub/public/locales/hi/translation.json index 84c7826c5..8f233c378 100644 --- a/zubhub_frontend/zubhub/public/locales/hi/translation.json +++ b/zubhub_frontend/zubhub/public/locales/hi/translation.json @@ -1034,7 +1034,16 @@ "save": "सहेजें", "unsave": "बिना सोचे समझे" } + }, + "pdfDetails": { + "introduction": "परिचय", + "category": "श्रेणी", + "classHeading": "कक्षा ग्रेड", + "materials": "उपयोग किए गए सामग्री", + "shareActivity": "इस गतिविधि को साझा करें", + "qrHeading": "कोड स्कैन करें ताकि गतिविधि देख सकें" } + }, "breadCrumb": { "link": { diff --git a/zubhub_frontend/zubhub/src/assets/images/index.js b/zubhub_frontend/zubhub/src/assets/images/index.js index 8f14145ee..fdf21ecf4 100644 --- a/zubhub_frontend/zubhub/src/assets/images/index.js +++ b/zubhub_frontend/zubhub/src/assets/images/index.js @@ -1,5 +1,6 @@ import logo from './logos/logo.png' - +import unstructured from './logos/unstructured.png' export const images = { - logo + logo, + unstructured } \ No newline at end of file diff --git a/zubhub_frontend/zubhub/src/assets/images/logos/unstructured.png b/zubhub_frontend/zubhub/src/assets/images/logos/unstructured.png new file mode 100644 index 000000000..e8273b1fc Binary files /dev/null and b/zubhub_frontend/zubhub/src/assets/images/logos/unstructured.png differ diff --git a/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetails.styles.js b/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetails.styles.js index 4ef751df6..511b82e67 100644 --- a/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetails.styles.js +++ b/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetails.styles.js @@ -1,10 +1,10 @@ -import { colors } from "../../assets/js/colors" +import { colors } from '../../assets/js/colors'; export const activityDefailsStyles = theme => ({ container: { - borderRadius: 8, - backgroundColor: colors.white, - padding: 24 + borderRadius: 8, + backgroundColor: colors.white, + padding: 24, }, descriptionBodyStyle: { marginBottom: '0.7em', @@ -33,9 +33,9 @@ export const activityDefailsStyles = theme => ({ color: colors.black, }, card: { - borderRadius: 8, - backgroundColor: colors.white, - padding: 24 + borderRadius: 8, + backgroundColor: colors.white, + padding: 24, }, creatorProfileStyle: { width: '100%', @@ -64,13 +64,13 @@ export const activityDefailsStyles = theme => ({ }, }, closed: { - height: 0, - transition: '0.4s', - overflow: 'hidden' + height: 0, + transition: '0.4s', + overflow: 'hidden', }, expandableMargin: { - // marginBottom: 10, - marginTop: 30 + // marginBottom: 10, + marginTop: 30, }, expanded: { transition: '0.4s', @@ -79,5 +79,98 @@ export const activityDefailsStyles = theme => ({ flexDirection: 'column', gap: 32, marginTop: 20, - } -}) \ No newline at end of file + }, + pdfStyle: { + paddingTop: '2rem', + }, + pdfLogoStyle: { + width: '4.5rem', + height: '1rem', + borderRadius: '0', + }, + pdfMainLogo:{ + padding: '0', + }, + justifyPdf: { + display: 'flex', + justifyContent: 'space-between', + height: '2rem', + padding: '0', + }, + pdfTitle: { + width: '23rem', + + fontFamily: 'Raleway', + fontSize: '1.5rem', + fontWeight: 800, + }, + pdfSubtitle: { + fontFamily: 'Raleway', + fontSize: '1rem', + fontWeight: '600', + height: '1.5rem', + marginBottom: '1rem' + }, + + creatorProfilePdfStyle: { + width: '100%', + display: 'flex', + alignItems: 'center', + padding: '0', + justifyContent: 'flex-end', + gap: '0.5rem', + fontSize: '0.5rem' + }, + verticalSpace:{ + marginBottom: '2rem', + }, + textStyle:{ + fontSize: '0.7rem' + }, + divFooter: { + '@media screen' :{ + display: 'none', + }, + '@media print': { + position: 'fixed', + bottom: 0, + }, + }, + imageStyle:{ + width: '1rem', + display: 'flex', + columnGap: '1rem', + }, + imageIndividualStyle:{ + width: '8rem', + height: '8rem', + borderRadius: '0.3rem' + }, + footerStyle:{ + backgroundColor: 'var(--primary-color1)', + display: 'flex', + alignItems: 'center', + marginTop: 'auto', + + // justifyContent: 'space-between', + // alignItems: 'center' + }, + flexStyle:{ + display: 'flex', + flexDirection: 'column', + color: 'white', + alignItems: 'center', + justifyContent: 'center', + width: '12rem' + }, + linkStyle:{ + color: 'white', + }, + pdfFooterLogoStyle: { + width: '8.25rem', + height: '1.9375rem', + }, + customTypographyStyle:{ + margin: '0', + } +}); diff --git a/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetailsV2.jsx b/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetailsV2.jsx index c2ab283cc..58ca637bc 100644 --- a/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetailsV2.jsx +++ b/zubhub_frontend/zubhub/src/views/activity_details/ActivityDetailsV2.jsx @@ -10,7 +10,12 @@ import { MenuItem, Typography, makeStyles, + Container, } from '@material-ui/core'; +import QRCode from 'qrcode.react'; + +import html2pdf from 'html2pdf.js'; // Make sure the import path is correct +import { images } from '../../assets/images'; import { CloseOutlined, ExpandMore, MoreVert } from '@material-ui/icons'; import BookmarkBorderIcon from '@material-ui/icons/BookmarkBorder'; import VisibilityIcon from '@material-ui/icons/Visibility'; @@ -32,6 +37,7 @@ import { getUrlQueryObject } from '../../utils.js'; import { activityDefailsStyles } from './ActivityDetails.styles'; import { useReactToPrint } from 'react-to-print'; import Html2Pdf from 'html2pdf.js'; +import { MakeActivity } from './MakeActivity'; const API = new ZubHubAPI(); const authenticatedUserActivitiesGrid = { xs: 12, sm: 6, md: 6 }; @@ -85,26 +91,84 @@ export default function ActivityDetailsV2(props) { setOpen(!open); props.history.replace(window.location.pathname); }; + const [isPrinting, setIsPrinting] = useState(false); + const componentRef = useRef(); + + const handleDownload = () => { + setIsPrinting(true); // Reset after printing + }; + function beforeDownload() { + // Add your code here to execute before download + const downloadMessage = document.createElement('div'); + downloadMessage.innerText = 'Preparing download...'; + document.body.appendChild(downloadMessage); + } - const handleDownload = useReactToPrint({ + useEffect(() => { + if (isPrinting) { + setTimeout(() => { + handlePrint(); // Trigger the print when the component is rendered + }, 1000); + } + }, [isPrinting]); + const handlePrint = useReactToPrint({ onBeforePrint: () => setIsDownloading(true), onPrintError: error => setIsDownloading(false), - onAfterPrint: () => setIsDownloading(false), - content: () => ref.current, + onAfterPrint: () => { + setIsDownloading(false); + setIsPrinting(false); + }, + content: () => componentRef.current, removeAfterPrint: true, print: async printIframe => { + // console.log(printIframe); const document = printIframe.contentDocument; if (document) { const html = document.getElementsByTagName('html')[0]; const pdfOptions = { - padding: 10, + // padding: 10, filename: `${activity.title}.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true }, + pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }, }; + // Call the beforeDownload function before generating the PDF + beforeDownload(); + + // Generate the PDF + html2pdf() + .from(html) + .set(pdfOptions) + .outputPdf(pdf => { + // Remove the download message if it was added earlier + const downloadMessage = document.querySelector('.download-message'); + if (downloadMessage) { + downloadMessage.remove(); + } + + // Trigger the download + pdf.save(); + }); + const exporter = new Html2Pdf(html, pdfOptions); + + exporter.postProcess = () => { + console.log('hi'); + const totalPages = exporter.pdf.internal.getNumberOfPages(); + console.log(totalPages); + for (let i = 1; i <= totalPages; i++) { + exporter.pdf.setPage(i); + + // Add your footer content + const x = 10; // X-coordinate + const y = exporter.pdf.internal.pageSize.getHeight() - 10; // Y-coordinate + const text = `Your Footer Text Goes Here - Page ${i} of ${totalPages}`; + exporter.pdf.text(x, y, text); + } + }; + await exporter.getPdf(true); } }, @@ -151,6 +215,13 @@ export default function ActivityDetailsV2(props) { {isDownloading ? 'Downloading...' : 'Download PDF'} + {isPrinting && ( +