Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
8e13b88
adding 3 blog posts
saurabh-pal-dn Apr 11, 2023
a8f6315
minor fixes to blogs
saurabh-pal-dn Apr 11, 2023
f507f2c
placeholder for
saurabh-pal-dn Apr 11, 2023
5361473
adding footer
saurabh-pal-dn Apr 12, 2023
a150627
minor fixes
saurabh-pal-dn Apr 12, 2023
ebd6fcf
removing shit 0
saurabh-pal-dn Apr 12, 2023
5e1b391
Restore Point
saurabh-pal-dn Apr 12, 2023
0617c50
adding getAllPopPosts()
saurabh-pal-dn Apr 13, 2023
c2e3cbd
adding pop Culture page (working)
saurabh-pal-dn Apr 13, 2023
c4623c0
making creds as env variables
saurabh-pal-dn Apr 14, 2023
d4592f1
removing loggers
saurabh-pal-dn Apr 14, 2023
7452991
fixing readme
saurabh-pal-dn Apr 14, 2023
ce2a4de
fixing '
saurabh-pal-dn Apr 14, 2023
cbbbea9
fixing regex
saurabh-pal-dn Apr 14, 2023
9838bbe
adding new blogs
saurabh-pal-dn Apr 14, 2023
aa7f6ad
minor fixes
saurabh-pal-dn Apr 16, 2023
ae44b3e
elliptical curve cryptography blog
saurabh-pal-dn Apr 18, 2023
c68f620
minor fixes
saurabh-pal-dn Apr 20, 2023
c18459c
adding top gun: maverick review
saurabh-pal-dn Apr 21, 2023
913da1f
minor fixes
saurabh-pal-dn Apr 21, 2023
ca6c78d
grammar fixes
saurabh-pal-dn Apr 26, 2023
ceec8d7
adding rpc
saurabh-pal-dn Apr 28, 2023
71c6cb1
stupid I am
saurabh-pal-dn Apr 28, 2023
e96f6ac
fixes
saurabh-pal-dn Apr 28, 2023
ed21375
grammar
saurabh-pal-dn Apr 28, 2023
3a870a3
minor fixes
saurabh-pal-dn Apr 28, 2023
ded699e
layout fixes
saurabh-pal-dn May 11, 2023
189d411
minor fixes
saurabh-pal-dn May 11, 2023
b8a5fd0
minor fixes
saurabh-pal-dn May 12, 2023
6ae8b1a
fixing grammar
saurabh-pal-dn May 13, 2023
6d23022
minor fixes
saurabh-pal-dn May 13, 2023
414ec63
adding quotes
saurabh-pal-dn May 16, 2023
e6a1652
UPI part 1 and 2
saurabh-pal-dn May 27, 2023
11f0918
upi part 3
saurabh-pal-dn May 28, 2023
b8a169a
bugfix: pop articles giving 404 on home page
saurabh-pal-dn May 31, 2023
9e9dc84
cbdc cybersecurity
saurabh-pal-dn Jun 6, 2023
2779c84
changing the date
saurabh-pal-dn Jun 24, 2023
6efbdb5
Minor changes to format
saurabh-pal-dn Aug 18, 2023
b9e6257
adding blog:
saurabh-pal-dn Oct 8, 2023
a865397
grammar fixes
saurabh-pal-dn Oct 8, 2023
ea6b42f
Merge branch 'main' of https://github.com/saurabh-pal-dn/blog_nextjs
saurabh-pal-dn Oct 9, 2023
d99917d
adding view counter:
saurabh-pal-dn Oct 14, 2023
602893e
adding blog: mumbai
saurabh-pal-dn Oct 24, 2023
4bb3e31
grammer changes
saurabh-pal-dn Oct 25, 2023
ce8064b
pop first
saurabh-pal-dn Nov 5, 2023
07ef66c
addition: pop post : one bag
saurabh-pal-dn Nov 5, 2023
bc4d14e
minor fixes
saurabh-pal-dn Nov 9, 2023
ca6197f
adding post
saurabh-pal-dn Nov 10, 2023
5c4380a
minor filitering logic
saurabh-pal-dn Nov 10, 2023
22a74a1
minor fix 2
saurabh-pal-dn Nov 10, 2023
0b78863
grammar fixes
saurabh-pal-dn Nov 18, 2023
a884bd4
minor fixes to top gun
saurabh-pal-dn Nov 19, 2023
d581c50
adding blog:
saurabh-pal-dn Feb 12, 2024
753a7fc
adding blog: lattice based encryption
saurabh-pal-dn Feb 12, 2024
bf8a5b3
update
saurabh-pal-dn Mar 17, 2024
6a887e3
minor fixes
saurabh-pal-dn Apr 28, 2024
9310456
mig from next 12 to 14
saurabh-pal-dn Apr 28, 2024
7240820
fixes v2
saurabh-pal-dn Apr 28, 2024
ce2ddfb
Anatomy of a murder (#1)
saurabh-pal-dn Feb 8, 2025
1348641
draft 1
Jul 10, 2025
1fe8c76
grammer fixes from grammerly
Jul 10, 2025
70879ec
format fix
Jul 10, 2025
e305041
webm to gif
Jul 13, 2025
6e0e800
minor additons
saurabh-pal-dn Jul 19, 2025
3efdd4a
Merge pull request #2 from saurabh-pal-dn:games
saurabh-pal-dn Jul 19, 2025
116d56f
site working again
saurabh-pal-dn Jul 20, 2025
640919d
minor fixes
saurabh-pal-dn Jul 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@
{
"argsIgnorePattern": "^_"
}
],
"no-console": [
2,
{
"allow": ["warn", "error"]
}
]
}
}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,11 @@ yarn-error.log*

# vercel
.vercel
secrets/spotify_secrets.yml
.vscode/settings.json
tsconfig.tsbuildinfo


target/
Cargo.lock
yarn.lock
31 changes: 1 addition & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,3 @@
# NextJS - Typescript - MDX - Blog

A Next.js starter for your next blog or personal site. Built with:

- [Typescript](https://www.typescriptlang.org/)
- Write posts with [MDX](https://mdxjs.com/)
- Style with [Tailwind CSS](https://tailwindcss.com/)
- Linting with [ESLint](https://eslint.org/)
- Formatting with [Prettier](https://prettier.io/)
- Linting, typechecking and formatting on by default using [`husky`](https://github.com/typicode/husky) for commit hooks
- Testing with [Jest](https://jestjs.io/) and [`react-testing-library`](https://testing-library.com/docs/react-testing-library/intro)

This Starter is **heavily** inspired by [Lee Robinson](https://github.com/leerob/leerob.io) and [Anson Lichtfuss](https://github.com/ansonlichtfuss/website).

👀 [View the Live Demo](https://nextjs-typescript-mdx-blog.vercel.app/)

## Getting Started

```bash
git clone https://github.com/ChangoMan/nextjs-typescript-mdx-blog.git
cd nextjs-typescript-mdx-blog

yarn install
# or
npm install

yarn dev
# or
npm run dev
```

Your new site will be up at http://localhost:3000/
A personal blog made with Next.js - MDX.
13 changes: 4 additions & 9 deletions components/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export const WEBSITE_HOST_URL = 'https://nextjs-typescript-mdx-blog.vercel.app';
const Head = ({ customMeta }: { customMeta?: MetaProps }): JSX.Element => {
const router = useRouter();
const meta: MetaProps = {
title: 'Hunter Chang - Website',
title: 'Saurabh Pal - Blog',
description:
'Sleep Deprived Father. Senior Web Developer. Lover of all things Ramen and Kpop.',
image: `${WEBSITE_HOST_URL}/images/site-preview.png`,
'Young, dumb and hungry to learn. A learned developer who likes to read about technology and talk on pop culture. PS I love the color black.',
image: `${WEBSITE_HOST_URL}/images/site-preview.jpg`,
type: 'website',
...customMeta,
};
Expand All @@ -23,15 +23,10 @@ const Head = ({ customMeta }: { customMeta?: MetaProps }): JSX.Element => {
<meta property="og:url" content={`${WEBSITE_HOST_URL}${router.asPath}`} />
<link rel="canonical" href={`${WEBSITE_HOST_URL}${router.asPath}`} />
<meta property="og:type" content={meta.type} />
<meta property="og:site_name" content="Hunter Chang - Website" />
<meta property="og:site_name" content="Saurabh Pal - Blog" />
<meta property="og:description" content={meta.description} />
<meta property="og:title" content={meta.title} />
<meta property="og:image" content={meta.image} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@huntarosan" />
<meta name="twitter:title" content={meta.title} />
<meta name="twitter:description" content={meta.description} />
<meta name="twitter:image" content={meta.image} />
{meta.date && (
<meta property="article:published_time" content={meta.date} />
)}
Expand Down
87 changes: 80 additions & 7 deletions components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MetaProps } from '../types/layout';
import Head from './Head';
import Navigation from './Navigation';
import ThemeSwitch from './ThemeSwitch';
import SpotifyTab from './SpotifyTab';

type LayoutProps = {
children: React.ReactNode;
Expand All @@ -17,7 +18,7 @@ const Layout = ({ children, customMeta }: LayoutProps): JSX.Element => {
<Head customMeta={customMeta} />
<header>
<div className="max-w-5xl px-8 mx-auto">
<div className="flex items-center justify-between py-6">
<div className="whitespace-nowrap ... flex items-center justify-between py-6 overflow-auto">
<Navigation />
<ThemeSwitch />
</div>
Expand All @@ -26,14 +27,86 @@ const Layout = ({ children, customMeta }: LayoutProps): JSX.Element => {
<main>
<div className="max-w-5xl px-8 py-4 mx-auto">{children}</div>
</main>
<footer className="py-8">
<div className="max-w-5xl px-8 mx-auto">
Built by{' '}
<SpotifyTab />
<footer className="flex items-center justify-center py-4">
<div>
<a
target="_blank"
rel="noopener noreferrer"
href="https://github.com/saurabh-pal-dn"
title="GitHub"
className="px-2"
>
<button type="button" aria-label="GitHub">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
focusable="false"
height="1.5em"
width="1.5em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>
</button>
</a>
<a
target="_blank"
rel="noopener noreferrer"
href="https://www.linkedin.com/in/saurabh-pal-a340a0151/"
title="LinkedIn"
className="px-2"
>
<button type="button" aria-label="LinkedIn">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
focusable="false"
height="1.5em"
width="1.5em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path>
<rect x="2" y="9" width="4" height="12"></rect>
<circle cx="4" cy="4" r="2"></circle>
</svg>
</button>
</a>
<a
className="text-gray-900 dark:text-white"
href="https://twitter.com/hunterhchang"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
title="Email"
className="px-2"
>
Hunter Chang
<button type="button" aria-label="Email">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
focusable="false"
height="1.5em"
width="1.5em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
<polyline points="22,6 12,13 2,6"></polyline>
</svg>
</button>
</a>
</div>
</footer>
Expand Down
17 changes: 13 additions & 4 deletions components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ import React from 'react';
const Navigation = (): JSX.Element => {
return (
<nav>
<Link href="/">
<a className="text-gray-900 dark:text-white pr-6 py-4">Home</a>
<Link href="/" className="text-gray-900 dark:text-white pr-6 py-4">
Home
</Link>
<Link href="/about">
<a className="text-gray-900 dark:text-white px-6 py-4">About</a>
<Link href="/blog" className="text-gray-900 dark:text-white px-6 py-4">
Tech
</Link>
{/* <Link href="/dashboard">
<a className="text-gray-900 dark:text-white px-6 py-4">Dashboard</a>
</Link> */}
<Link href="/about" className="text-gray-900 dark:text-white px-6 py-4">
About
</Link>
<Link href="/pop" className="text-gray-900 dark:text-white px-6 py-4">
Pop Cult
</Link>
</nav>
);
Expand Down
82 changes: 82 additions & 0 deletions components/SpotifyTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import useSWR from 'swr';
const imageUrls = [
'https://i.scdn.co/image/ab67616d0000b273f10439addbeefd4ecc1dd9d7',
'https://i.scdn.co/image/ab67616d0000b273982320da137d0de34410df61',
'https://i.scdn.co/image/ab67616d0000b2737a7e086c8705b91d247c2c24',
'https://i.scdn.co/image/ab67616d0000b2730c5b0b80fa8f564ddd3328c3',
'https://i.scdn.co/image/ab67616d0000b2732c920431e9c8d1a9b632bcd0',
'https://i.scdn.co/image/ab67616d0000b27313c6cb6a81c8db4dbc8b9924',
'https://i.scdn.co/image/ab67616d0000b2732a46046339bd779f95a8cf8b',
];
const randomIndex = Math.floor(Math.random() * imageUrls.length);

const backgroundImageurl = imageUrls[randomIndex];

const SpotifyTab = (): JSX.Element => {
const fetcher = (url) => fetch(url).then((r) => r.json());
const { data: song } = useSWR('/api/spotify', fetcher, {
refreshInterval: 5 * 1000,
fallbackData: 'loading',
});

return (
<>
<div className="css-foz3qc">
<div
className="css-ewsei0"
style={{
background: `url(${backgroundImageurl})`,
}}
>
<div className="chakra-skeleton css-cdkrf0">
<img
alt="Spotify album cover"
className="chakra-image css-1febq2i"
width={'100px'}
height={'100px'}
src={
song.album?.image ||
'https://i.scdn.co/image/ab67616d0000b273982320da137d0de34410df61'
}
/>
</div>

<div className="chakra-stack css-1meimlm">
<a
target="_blank"
rel="noopener noreferrer"
className="chakra-link css-mxtkhh"
href={
song.url ||
'https://open.spotify.com/track/7DY756WOLyOz2Xnhw4EFiC'
}
>
<p className="chakra-text css-i3jkqk">
{song.title || 'São Paulo (feat. Anitta)'}
</p>
</a>
<p className="chakra-text css-1vsww04">
{song.artists?.name[0] || 'The Weeknd'}
</p>
</div>
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
viewBox="0 0 496 512"
focusable="false"
className="chakra-icon css-hjkpk0"
name="spotify"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"></path>
</svg>
</div>
</div>
</>
);
};

export default SpotifyTab;
28 changes: 28 additions & 0 deletions components/ViewCounter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffect } from 'react';
import useSWR from 'swr';

function getCounterText(views: number) {
if (views > 1) {
return `${views.toLocaleString()} views`;
}
return `${views.toLocaleString()} view`;
}

const ViewCounter = ({ slug }): JSX.Element => {
const fetcher = (url) => fetch(url).then((r) => r.json());
const { data } = useSWR(`/api/views/${slug}`, fetcher);
const views: number = data?.total ?? 0; // this is required because in the initial run, data is returned as undefined as the hook passes a promise, later data is populated

useEffect(() => {
fetch(`/api/views/${slug}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
}, [slug]);
const text = getCounterText(views);
return <span>{text}</span>;
};

export default ViewCounter;
16 changes: 16 additions & 0 deletions constants/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const POP_POSTS_NOT_TO_DISPLAY_ON_PAGE: string[] = [
'mumbai-a-year-review-public-infra.mdx',
];
export const personalDescriptonAdjectives: string[] = [
'a Developer',
'Passionate',
'a Runner',
'an Artist',
'a Speaker',
'Dumb and Foolish',
'Restless',
'and much more ....',
];
export const personalDescriptonAdjectivesLength: number[] = [
11, 10, 8, 9, 9, 16, 8, 18,
];
Loading