implemented pdf viewer functionality.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
export default function PageNotFound() {
|
||||
return (
|
||||
<>
|
||||
<h1>404</h1>
|
||||
<p>This is not the page you are looking for.</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -4,7 +4,10 @@ import PdfViewer from "./components/PdfViewer";
|
||||
export default function Resume() {
|
||||
return (
|
||||
<>
|
||||
<div id="resume-section">
|
||||
<h1>Resume</h1>
|
||||
<PdfViewer file="resume.pdf" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Document, Page, pdfjs } from "react-pdf";
|
||||
import "react-pdf/dist/Page/TextLayer.css";
|
||||
import "react-pdf/dist/Page/AnnotationLayer.css";
|
||||
@@ -9,13 +9,40 @@ export default function PdfViewer({ file }) {
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
const [numPages, setNumPages] = useState(0);
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
function prev() {
|
||||
if (pageNumber >= 2) {
|
||||
setPageNumber(pageNumber - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (pageNumber < numPages - 1) {
|
||||
setPageNumber(pageNumber + 1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("numPages: " + numPages);
|
||||
console.log("pageNumber: " + pageNumber);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="pdf-container">
|
||||
<Document file={file}>
|
||||
<Page pageNumber={1} />
|
||||
<Page pageNumber={2} />
|
||||
<button className="pdf-button shadow" onClick={() => prev()}>
|
||||
<span className="material-icons">arrow_back</span>
|
||||
</button>
|
||||
<Document
|
||||
file={file}
|
||||
onLoadSuccess={({ numPages: numPagesInPdf }) => {
|
||||
setNumPages(numPagesInPdf);
|
||||
}}
|
||||
>
|
||||
<Page pageNumber={pageNumber} />
|
||||
</Document>
|
||||
<button className="pdf-button shadow" onClick={() => next()}>
|
||||
<span className="material-icons">arrow_forward</span>
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -24,7 +24,7 @@ const SkillCard = ({ header, symbol, list, isActive, onToggle }) => {
|
||||
<span className="material-icons skill-symbol">{symbol}</span>
|
||||
<h3>{header}</h3>
|
||||
</div>
|
||||
{isActive && (
|
||||
{(isActive || !isMobile) && (
|
||||
<ul>
|
||||
{list.map((item, index) => (
|
||||
<li key={index}>{item}</li>
|
||||
|
||||
+30
-12
@@ -211,7 +211,6 @@ h4 {
|
||||
}
|
||||
|
||||
#skill-cards {
|
||||
border: 1px solid white;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -228,7 +227,7 @@ h4 {
|
||||
background-color: #ebd2ff;
|
||||
border-radius: 20px;
|
||||
min-width: 20vw;
|
||||
max-width: 40vw;
|
||||
max-width: 50vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
|
||||
@@ -236,7 +235,7 @@ h4 {
|
||||
display: grid;
|
||||
grid-template-columns: 20% 60%;
|
||||
grid-template-rows: 100%;
|
||||
column-gap: 20%;
|
||||
column-gap: 10%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
@@ -246,6 +245,10 @@ h4 {
|
||||
background-color: #4a245e;
|
||||
border-radius: 18px 18px 0 0;
|
||||
}
|
||||
.skill-card-header h3 {
|
||||
font-size: clamp(1.3rem, 2vw, 3rem);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.skill-symbol {
|
||||
font-variation-settings:
|
||||
@@ -311,6 +314,7 @@ h4 {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 1vw;
|
||||
}
|
||||
|
||||
.project-card img {
|
||||
@@ -447,12 +451,31 @@ h4 {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#resume-section {
|
||||
margin: 2vw;
|
||||
}
|
||||
|
||||
/**PDF Viewer**/
|
||||
.pdf-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: 100%;
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.pdf-button {
|
||||
background-color: #ebd2ff;
|
||||
color: #4a245e;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 1vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
|
||||
.pdf-button span {
|
||||
color: #4a245e;
|
||||
}
|
||||
|
||||
/**Animations**/
|
||||
@@ -614,21 +637,16 @@ h4 {
|
||||
margin-left: 5vw;
|
||||
}
|
||||
|
||||
.pdf-viewer {
|
||||
max-width: 100%;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.pdf-page {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#card-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 485px) {
|
||||
|
||||
+4
-2
@@ -3,14 +3,16 @@ import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter as Router, Routes, Route } from "react-router";
|
||||
import App from "./App.jsx";
|
||||
import Resume from "./Resume.jsx";
|
||||
import PageNotFound from "./PageNotFound.jsx";
|
||||
|
||||
const container = document.getElementById("app");
|
||||
const root = createRoot(container); // createRoot(container!) if you use TypeScript
|
||||
root.render(
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/" element={<App />} />
|
||||
<Route path="/resume" element={<Resume />} />
|
||||
<Route exact path="/" element={<App />} />
|
||||
<Route exact path="/resume" element={<Resume />} />
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
</Router>,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user