Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add redirects, update icons #40

Merged
merged 9 commits into from
Jan 13, 2025
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
## Pradumna Saraf Portfolio
### Pradumnasaraf.github.io

This repository contains the source code for my portfolio website. It is built using HTML and CSS. It is hosted on GitHub Pages.
This repository contains the source code for my personal/portfolio/service website. It is built Next.js and Tailwind CSS. The Code is 100% open source and available for anyone to use.

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Pradumnasaraf/Pradumnasaraf.github.io)
![website screenshot](https://github.com/user-attachments/assets/c4e1fdf8-49fd-4e2b-a66c-bb55e84e3e01)

![Website Demo](https://github.com/Pradumnasaraf/Pradumnasaraf.github.io/assets/51878265/0b330ade-1645-4005-b4fd-2f1aeb6a17bf)

## 🌐 Website

A custom domain name is used for the website. It is hosted on GitHub Pages. The website is accessible at [pradumnasaraf.dev](https://pradumnasaraf.dev/)

## πŸ›‘οΈ License
### πŸ“œ License

**Pradumnasaraf.github.io** is licensed under the GPL-3.0 License - see the [LICENSE](/LICENSE) file for details.

## 🀝 Support
### πŸ›‘ Security

Don't forget to leave a star ⭐️
If you discover a security vulnerability within this project, please check the [SECURITY](SECURITY.md) for more information.
28 changes: 24 additions & 4 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,31 @@ const nextConfig = {
async redirects() {
return [
{
source: '/hey',
destination: '/',
permanent: true, // Permanent redirect (301)
source: '/monitoring',
destination: 'https://Pradumnasaraf.github.io/Monitoring',
permanent: true,
},
];
{
source: '/newsletter',
destination: 'https://pradumnasaa.substack.com',
permanent: true,
},
{
source: '/cv',
destination: 'https://www.canva.com/design/DAF_kKnj9WI/IT8NdwVQlzRK3DaMmXm18A/edit?utm_content=DAF_kKnj9WI&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton',
permanent: true,
},
{
source: '/resume',
destination: 'https://www.canva.com/design/DAF_kKnj9WI/IT8NdwVQlzRK3DaMmXm18A/edit?utm_content=DAF_kKnj9WI&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton',
permanent: true,
},
{
source: '/blog',
destination: 'https://blog.pradumnasaraf.dev',
permanent: true,
}
]
},
};

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 0 additions & 28 deletions src/app/camera/components/FullScreenModal.js

This file was deleted.

70 changes: 0 additions & 70 deletions src/app/camera/components/MasonryGrid.js

This file was deleted.

147 changes: 114 additions & 33 deletions src/app/camera/page.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use client';
import MasonryGrid from './components/MasonryGrid';
import { useEffect } from 'react';

import React, { useState, useEffect } from 'react';
import Masonry from 'react-masonry-css';
import { createPortal } from 'react-dom';
import './style.css';
const images = [
{ src: 'https://drive.google.com/thumbnail?id=1uu0wWGmbHC0VY7BT-n5DUpWz86_ozANg&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1G8IYlbeJUKvghC8FIlEmtyVo6fg_YxqZ&sz=w2000', alt: 'photo' },
Expand Down Expand Up @@ -38,52 +39,132 @@ const images = [
{ src: 'https://drive.google.com/thumbnail?id=1ISysXMTEBkqwt3-wCN0jFRNATZTWKi26&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1bifEZJm_rIx_Xs4pORmfXCCIVFuMH_DY&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=11VG8uzX2vUMSRtEnHsDxDMT3fcletqsY&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1JANNc-kNawn7jUGRs4MUZc9ib0wQ8JBP&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1YbOEXGJfIOXvRW6akB1HVmaIOOF2Jk1h&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1b3CqP5Hn0xI2m6d2jH9_uWrfn3z8rkI0&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1JANNc-kNawn7jUGRs4MUZc9ib0wQ8JBP&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1ko_WLnJ2SNNEO13WkKmRhpvobDQ6Q_Ko&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1b3CqP5Hn0xI2m6d2jH9_uWrfn3z8rkI0&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1ruE0RqOwTPK0AR17ap4hwfGDgWboP52p&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1O83nNCKCUZ4McHO1nlZXvo1OKqzLldyw&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1MxtU3yWE8BkSi-1gessGGaTKGKzO8SO6&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1FEQMnHybHi1TDvCHweOsB7ODeC06VjIs&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1nTQlYnaHPsy-kCrlV1bJocKgwlvqmyQc&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1K_Iteo-Rqrxi0ayMMAjOgsBSocg81Wmx&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=16ujZfroa5zjL09-UJWPyeRK0NUu1VkBi&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1FEQMnHybHi1TDvCHweOsB7ODeC06VjIs&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1P60hz5FIkEhoyxEJOtHCVprzm8sP4tt-&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1-umcEA-0sefXkCVXtpEFxvVAWqtnw2y1&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1sVamXny-K2Tfb_m_PGxQEdTiV99_r8q8&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1dD4-Qrc2Hk4dCFQKcBB4GRbsvrcJOt0Q&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1sVamXny-K2Tfb_m_PGxQEdTiV99_r8q8&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=16ujZfroa5zjL09-UJWPyeRK0NUu1VkBi&sz=w2000', alt: 'photo' },
{ src: 'https://drive.google.com/thumbnail?id=1-umcEA-0sefXkCVXtpEFxvVAWqtnw2y1&sz=w2000', alt: 'photo' },
]

// FullScreenModal Component
const FullScreenModal = ({ isOpen, imageSrc, onClose }) => {
if (!isOpen) return null;

return createPortal(
<div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50 p-5">
<button
onClick={onClose}
className="absolute top-6 right-6 flex items-center justify-center w-12 h-12 bg-white text-black text-2xl font-bold rounded-full shadow-lg border-2 border-black hover:bg-gray-100 transition-transform transform hover:scale-110"
aria-label="Close"
>
&times;
</button>
<img
src={imageSrc}
alt="Full Screen"
className="max-w-[90vw] max-h-[90vh] object-contain"
/>
</div>,
document.body
);
};

// Main Home Component
export default function Home() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [modalImageSrc, setModalImageSrc] = useState('');

const openModal = (src) => {
setModalImageSrc(src);
setIsModalOpen(true);
};

const closeModal = () => {
setIsModalOpen(false);
setModalImageSrc('');
};

const breakpointColumnsObj = {
default: 3,
1100: 3,
700: 2,
500: 1
};

useEffect(() => {
// Google Tag Manager Script
const scriptGTM = document.createElement('script');
scriptGTM.innerHTML = `
(function (w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({
'gtm.start': new Date().getTime(),
event: 'gtm.js',
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-WRGLMZCX');
`;
document.head.appendChild(scriptGTM);
return () => {
document.head.removeChild(scriptGTM);
};
}, []);
// Google Tag Manager Script
const scriptGTM = document.createElement('script');
scriptGTM.innerHTML = `
(function (w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({
'gtm.start': new Date().getTime(),
event: 'gtm.js',
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-WRGLMZCX');
`;
document.head.appendChild(scriptGTM);
return () => {
document.head.removeChild(scriptGTM);
};
}, []);

return (
<div className="px-24 py-8 mx-auto max-w-6xl">
<div className="p-4">
<MasonryGrid images={images} />
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{images.map((image, index) => (
<ImageItem
key={index}
src={image.src}
alt={image.alt}
onClick={() => openModal(image.src)}
/>
))}
</Masonry>

<FullScreenModal
isOpen={isModalOpen}
imageSrc={modalImageSrc}
onClose={closeModal}
/>
</div>
</div>
);
}
}

// ImageItem Component
const ImageItem = ({ src, alt, onClick }) => {
const [hasError, setHasError] = useState(false);

return !hasError ? (
<img
src={src}
alt={alt}
className="w-full h-auto object-cover cursor-pointer transition-transform transform hover:scale-105 grayscale-image"
onClick={onClick}
onError={() => setHasError(true)}
loading="lazy"
/>
) : null;
};
43 changes: 43 additions & 0 deletions src/app/not-found.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.not-found-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f8f9fa;
color: #333;
text-align: center;
font-family: Arial, sans-serif;
}

.not-found-title {
font-size: 3rem;
font-weight: bold;
color: #f57b85;
}

.not-found-description {
margin-top: 1rem;
font-size: 1.25rem;
color: #6c757d;
}

.not-found-description a {
color: #f57b85;
text-decoration: none;
}

.not-found-link {
font-size: 1.5em;
margin-top: 2rem;
padding: 0.5rem 1rem;
background-color: #2C3333;
color: white;
text-decoration: none;
border-radius: 10px;
transition: background-color 0.5s ease;
}

.not-found-link:hover {
opacity: 0.6;
}
Loading