Skip to content

Commit

Permalink
Merge pull request #192 from makeopensource/152-pdf-submission
Browse files Browse the repository at this point in the history
Added a page to view pdf submissions
  • Loading branch information
jessehartloff authored Nov 12, 2024
2 parents 717d000 + 1f67e64 commit 1a9610b
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions devU-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"react": "^17.0.2",
"react-datepicker": "^4.1.1",
"react-dom": "^17.0.1",
"react-pdf": "^9.1.1",
"react-redux": "^7.2.4",
"react-router-breadcrumbs-hoc": "^4.1.0",
"react-router-dom": "^5.2.0",
Expand Down
2 changes: 2 additions & 0 deletions devU-client/src/components/authenticatedRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import CoursePreviewPage from './pages/courses/coursePreviewPage'
import CoursesListPage from "./pages/listPages/courses/coursesListPage";
import AssignmentProblemFormPage from './pages/forms/assignments/assignmentProblemFormPage'
import InstructorSubmissionspage from "./pages/submissions/InstructorSubmissionspage";
import SubmissionFileView from './pages/submissions/submissionFileView'

import WebhookURLForm from './pages/webhookURLForm'

Expand Down Expand Up @@ -53,6 +54,7 @@ const AuthenticatedRouter = () => (
component={InstructorSubmissionspage}/>
<Route exact path='/course/:courseId/assignment/:assignmentId/submission/:submissionId/feedback'
component={SubmissionFeedbackPage}/>
<Route exact path ='/course/:courseId/assignment/:assignmentId/submission/:submissionId/fileView' component={SubmissionFileView}/>
// TBD, undecided where webhooks should be placed
{/*<Route exact path='/webhookURLPage' component={webhookURLForm}/>*/}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import {prettyPrintDateTime} from "../../../utils/date.utils";
//import React, { useState } from 'react';
//import { Document, Page } from 'react-pdf';
//import StickyNote from 'react-sticky-notes';
import { useHistory } from 'react-router-dom'


const SubmissionDetailPage = () => {
// const [notes, setNotes] = useState([]);
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [setAlert] = useActionless(SET_ALERT)
const history = useHistory()

const { submissionId, assignmentId, courseId } = useParams<{submissionId: string, assignmentId: string, courseId: string}>()
const [submissionScore, setSubmissionScore] = useState<SubmissionScore | null>(null)
Expand Down Expand Up @@ -208,6 +210,7 @@ const SubmissionDetailPage = () => {

</div>
<h2 className={styles.content_title}>Content</h2>
<Button onClick={() => history.push(`/course/${selectedSubmission.courseId}/assignment/${selectedSubmission.assignmentId}/submission/${submissionId}/fileView`)}>View File</Button>
<div className={styles.scrollableContent}>
<pre>{selectedSubmission.content}</pre>
</div>
Expand Down
112 changes: 112 additions & 0 deletions devU-client/src/components/pages/submissions/submissionFileView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import RequestService from 'services/request.service'
import { Submission } from 'devu-shared-modules'
import {Document, Page} from 'react-pdf'
import { pdfjs } from 'react-pdf'
import PageWrapper from 'components/shared/layouts/pageWrapper'
import { getToken } from 'utils/authentication.utils'

import config from '../../../config'
const proxiedUrls = {
'/api': `${config.apiUrl}`,
}

function _replaceUrl(userUrl: string) {
const proxy: string | undefined = Object.keys(proxiedUrls).find((key) => {
if (userUrl.startsWith(key)) return true
return false
})

if (!proxy) return userUrl

return userUrl.replace(proxy, proxiedUrls[proxy as keyof typeof proxiedUrls])
}


pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;

const SubmissionFileView = () => {
const { courseId, assignmentId, submissionId } = useParams<{ courseId: string, assignmentId: string, submissionId: string }>()
const [bucket, setBucket] = useState('')
const [filename, setFilename] = useState('')
const authToken = getToken()

const [file, setFile] = useState<File | Blob | null>(null)
const [numPages, setNumPages] = useState(0)

useEffect(() => {
fetchData()
}, [])

useEffect(() => {
if (bucket && filename) {
fetchFile()
}
}, [bucket, filename])

const fetchData = async () => {
try {
await RequestService.get<Submission>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/${submissionId}`)
.then((data) => {
const submissionFiles = JSON.parse(data.content)
const [tempbucket,tempfilename] = submissionFiles.filepaths[0].split('/')
setBucket(tempbucket)
setFilename(tempfilename)


})
} catch (e) {
console.error(e)
}
}

const fetchFile = async () => {
try {
const url = _replaceUrl(`/api/course/${courseId}/file-upload/${bucket}/${filename}`)
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/pdf',
'Authorization': `Bearer ${authToken}`,
},
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const arrayBuffer = await response.arrayBuffer();
const blob = new Blob([arrayBuffer], { type: 'application/pdf' });
const file = new File([blob], filename, { type: 'application/pdf' });

setFile(file);
} catch (e) {
console.error(e)
}
}

const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
setNumPages(numPages)
}

return (
<PageWrapper>
<div style={{maxWidth:"900px", margin:"auto"}}>
{file &&
<Document file={file} onLoadSuccess={onDocumentLoadSuccess}>
{[...Array(numPages)].map((_, index) => (
<div style={{marginBottom:"20px"}}>
<Page key={index} pageNumber={index + 1} renderTextLayer={false} renderAnnotationLayer={false} scale={1.5}/>
</div>
))}
</Document>
}
</div>
<br/>

</PageWrapper>
)

}

export default SubmissionFileView

0 comments on commit 1a9610b

Please sign in to comment.