Skip to content

Commit

Permalink
Merge pull request #41 from whysosaket/newsletter
Browse files Browse the repository at this point in the history
Newsletter
  • Loading branch information
whysosaket authored Sep 25, 2024
2 parents 8e9b3ed + 5bbdef4 commit 80ad698
Show file tree
Hide file tree
Showing 11 changed files with 1,108 additions and 155 deletions.
958 changes: 867 additions & 91 deletions my-app/package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion my-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@
},
"dependencies": {
"@headlessui/react": "^2.1.8",
"@wojtekmaj/react-hooks": "^1.21.0",
"framer-motion": "^11.5.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-icons": "^5.3.0",
"react-pdf": "^9.1.1",
"react-router-dom": "^6.26.2",
"react-secure-storage": "^1.3.2",
"react-slick": "^0.30.2",
"slick-carousel": "^1.8.1",
"toastify-js": "^1.12.0"
"toastify-js": "^1.12.0",
"vite-plugin-static-copy": "^1.0.6"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
Expand Down
Binary file added my-app/public/Newsletter.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions my-app/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Events from "./pages/Events";
import Base from "./layouts/Base";
import Subscribe from "./components/Subscribe";
import { useState } from "react";
import NewsletterPage from "./pages/NewsletterPage";

export default function App() {
const [isVisible, setIsVisible] = useState(false);
Expand All @@ -27,6 +28,7 @@ export default function App() {
<Route path="/community" element={<Community />} />
<Route path="/events" element={<Events />} />
<Route path="/contact-us" element={<ContactForm />} />
<Route path="/newsletter" element={<NewsletterPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Base>
Expand Down
2 changes: 1 addition & 1 deletion my-app/src/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const navigation = [
{ name: "Home", to: "/" },
{ name: "Community", to: "/community" },
{ name: "Events", to: "/events" },
{ name: "Newsletter", to: "/newsletter" },
{ name: "About us", to: "about-us" },
{ name: "Contact us", to: "/contact-us" },
];
export { navigation };
4 changes: 2 additions & 2 deletions my-app/src/pages/Community.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ export default function Community() {
"w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-blue-700",
"ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none",
selected
? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-white"
? "bg-white shadow "
: "text-white hover:bg-white/[0.12] hover:text-blue-100"
)
}
>
Expand Down
2 changes: 1 addition & 1 deletion my-app/src/pages/Events.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export default function Events() {
"ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none",
selected
? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-white"
: " text-white hover:bg-white/[0.12] hover:text-blue-100"
)
}
>
Expand Down
180 changes: 180 additions & 0 deletions my-app/src/pages/NewsletterPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { pdfjs } from "react-pdf";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Document, Page } from "react-pdf";
import { useResizeObserver } from "@wojtekmaj/react-hooks";
import "react-pdf/dist/esm/Page/AnnotationLayer.css";
import "react-pdf/dist/esm/Page/TextLayer.css";
import { IoChevronBack, IoChevronForward } from "react-icons/io5";
import { API_URL } from "../lib/constants";

import "../styles/newsletter.css";
import Newsletter from "../components/Newsletter";

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

const NewsletterPage = () => {
const [file, setFile] = useState();
const [editions, setEditions] = useState([]);
const [numPages, setNumPages] = useState();
const [pageNumber, setPageNumber] = useState(1);
const [containerRef, setContainerRef] = useState(null);
const [containerWidth, setContainerWidth] = useState();
const [loading, setLoading] = useState(true);

// Memoize the options object to prevent unnecessary reloads
const options = useMemo(
() => ({
cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,
}),
[]
);

const onDocumentLoadSuccess = ({ numPages }) => {
setNumPages(numPages);
};

const onResize = useCallback((entries) => {
const [entry] = entries;
if (entry) {
setContainerWidth(entry.contentRect.width);
}
}, []);

useResizeObserver(containerRef, resizeObserverOptions, onResize);

const getNewsletters = async () => {
try {
const response = await fetch(`${API_URL}/newsletter`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

const data = await response.json();
if(data.success){
setEditions(data.newsletter);
if(data.newsletter.length>0) getNewsletter(data.newsletter[0].id)
}
setLoading(false);
} catch (error) {
setLoading(false);
}
};

const getNewsletter = async (id) => {
try {
const response = await fetch(`${API_URL}/newsletter/${id}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

const data = await response.json();
if(data.success){
const pdfResponse = await fetch(data.newsletter.link);
const blob = await pdfResponse.blob();
const fileUrl = URL.createObjectURL(blob);
setFile(fileUrl);
}
setLoading(false);
} catch (error) {
setLoading(false);
}
};

useEffect(()=>{
getNewsletters();
},[])

const forward = () => {
if (pageNumber + 1 <= numPages) setPageNumber(pageNumber + 1);
};

const backward = () => {
if (pageNumber - 1 >= 1) setPageNumber(pageNumber - 1);
};

const [selectedValue, setSelectedValue] = useState('Option 1');

// Handle change event
const handleChange = (event) => {
setLoading(true);
setSelectedValue(event.target.value);
getNewsletter(event.target.value);
};

return (
<div className="text-white flex flex-col justify-center">
<h1 className="text-4xl tracking-tight my-2 font-extrabold text-pastel text-center sm:text-5xl md:text-6xl">
Newsletters
</h1>
<div className="flex justify-center mt-4 mb-8">
<div className="mx-auto">
<label htmlFor="dropdown" className="mb-2 text-lg font-medium text-gray-300 text-center">
Select an edition:
</label>
<select
id="dropdown"
value={selectedValue}
onChange={handleChange}
className="block w-64 px-3 py-2 border border-gray-300 bg-gray-700 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
>
{
editions.map((item, index)=>{
return <option key={index} value={item.id}>{item.edition}</option>
})
}
</select>
</div>
</div>
{
loading&&
<div className="h-24 w-4/6 rounded-xl bg-white/30 text-transparent mx-auto animate-pulse">
asda
</div>
}
{!loading&&file&&
<div>
<div className="flex justify-center">
<div className="flex justify-center gap-12">
<button onClick={backward}><IoChevronBack size={25} /></button>
{pageNumber} of {numPages}
<button onClick={forward}><IoChevronForward size={25} /></button>
</div>
</div>
<div>
<div className="Example__container__document mx-auto" ref={setContainerRef}>
<Document
file={file}
onLoadSuccess={onDocumentLoadSuccess}
options={options}
>
<Page
pageNumber={pageNumber}
width={
containerWidth ? Math.min(containerWidth, maxWidth) : maxWidth
}
/>
</Document>
</div>
</div>
<div className="flex justify-center">
<div className="flex justify-center gap-12">
<button onClick={backward}><IoChevronBack size={25} /></button>
{pageNumber} of {numPages}
<button onClick={forward}><IoChevronForward size={25} /></button>
</div>
</div>
</div>}
<div className="my-6">
<Newsletter />
</div>
</div>
);
};

export default NewsletterPage;
51 changes: 51 additions & 0 deletions my-app/src/styles/newsletter.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.Example input,
.Example button {
font: inherit;
}

.Example header {
background-color: #323639;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
padding: 20px;
color: white;
}

.Example header h1 {
font-size: inherit;
margin: 0;
}

.Example__container {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px 0;
padding: 10px;
}

.Example__container__load {
margin-top: 1em;
color: white;
}

.Example__container__document {
width: 100%;
max-width: calc(100% - 2em);
margin: 1em 0;
}

.Example__container__document .react-pdf__Document {
display: flex;
flex-direction: column;
align-items: center;
}

.Example__container__document .react-pdf__Page {
margin: 1em 0;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
}

.Example__container__document .react-pdf__message {
padding: 20px;
color: white;
}
54 changes: 0 additions & 54 deletions package-lock.json

This file was deleted.

5 changes: 0 additions & 5 deletions package.json

This file was deleted.

0 comments on commit 80ad698

Please sign in to comment.