diff --git a/public/contents/blog/netmasking-a-band-aid-solution-for-a-bleeding-internet.mdx b/public/contents/blog/netmasking-a-band-aid-solution-for-a-bleeding-internet.mdx index f372921..490c39e 100644 --- a/public/contents/blog/netmasking-a-band-aid-solution-for-a-bleeding-internet.mdx +++ b/public/contents/blog/netmasking-a-band-aid-solution-for-a-bleeding-internet.mdx @@ -6,3 +6,4 @@ description: 'A detailed explanation on netmask, IP4, IPV6, and how we keep shif banner: 'nilaysharan/blog/netmask/bannerr' tags: 'tech,network' --- + diff --git a/public/contents/projects/echoes.mdx b/public/contents/projects/echoes.mdx new file mode 100644 index 0000000..e69de29 diff --git a/public/contents/projects/hestia.mdx b/public/contents/projects/hestia.mdx new file mode 100644 index 0000000..e69de29 diff --git a/public/contents/projects/humantd.mdx b/public/contents/projects/humantd.mdx new file mode 100644 index 0000000..0510a3b --- /dev/null +++ b/public/contents/projects/humantd.mdx @@ -0,0 +1,11 @@ +--- +title: 'HumanTD' +slug: humantd +publishedAt: '2023-06-08' +description: 'Portal that tracks down a person of interest by using backtracking and video footage from CCTV cameras.' +banner: 'nilaysharan/project/humantd/qwlr8aaqfn7xwb1dazqr' +tags: 'react,tailwindcss,typescript' +github: 'github.com/nilaysharan/humantd' +--- + +sabdakbsdj diff --git a/public/contents/projects/medbud.mdx b/public/contents/projects/medbud.mdx new file mode 100644 index 0000000..e69de29 diff --git a/public/contents/projects/social-media-backend.mdx b/public/contents/projects/social-media-backend.mdx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index cb70c00..ccf2750 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -61,8 +61,7 @@ const Page = () => { I find great joy in learning from feedback and criticism, so please feel free to reach out to me. I also enjoy occasional writing and creating unconventional projects, both of which - you can find featured here. Thank you for visiting, and I hope - you enjoy it! + you can find featured here.


diff --git a/src/app/api/blog/[slug]/route.ts b/src/app/api/blog/[slug]/route.ts index 55119ef..261e3a4 100644 --- a/src/app/api/blog/[slug]/route.ts +++ b/src/app/api/blog/[slug]/route.ts @@ -12,7 +12,8 @@ export async function GET(req: NextRequest) { try { const preRoutes = preFetch({ type: 'blog' }); - const preRoute = preRoutes.find((route) => route.slug === slug); + const preRoute = preRoutes?.find((route) => route.slug === slug); + if (!preRoute) return new NextResponse(null, { status: 404 }); const file = await getFileBySlug( preRoute?.source as string, preRoute?.slug as string diff --git a/src/app/api/projects/[slug]/route.ts b/src/app/api/projects/[slug]/route.ts new file mode 100644 index 0000000..d379fe4 --- /dev/null +++ b/src/app/api/projects/[slug]/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from 'next/server'; + +import { getFileBySlug, preFetch } from '@/lib/mdx.server'; + +export async function GET(req: NextRequest) { + const BASE_URL = `${req.nextUrl.origin}/api/projects/`; + const url = new URL(req.url || '', BASE_URL); + + const slug = url.pathname.split('/').pop() || ''; + + if (!slug) return new NextResponse(null, { status: 404 }); + + try { + const preRoutes = preFetch({ type: 'projects' }); + const preRoute = preRoutes?.find((route) => route.slug === slug); + const file = await getFileBySlug( + preRoute?.source as string, + preRoute?.slug as string + ); + + if (!file) + return new NextResponse(null, { status: 404, statusText: 'Not found ' }); + + return NextResponse.json(file); + } catch (error) { + return NextResponse.json({ error: error }); + } +} diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index 8847d44..1125b90 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -11,6 +11,7 @@ import BlogCard from '@/components/content/blogs/BlogCard'; import ContentPlaceholder from '@/components/content/ContenPlaceholder'; import StyledInput from '@/components/content/form/StyledInput'; import Tag, { SkipNavTag } from '@/components/content/Tag'; +import Seo from '@/components/Seo'; import { BlogFrontmatter } from '@/types/frontmatters'; @@ -77,6 +78,10 @@ const Page = () => { return ( <> +

diff --git a/src/app/page.tsx b/src/app/page.tsx index 74be786..94b2c18 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -14,6 +14,7 @@ import ProjectCard from '@/components/content/projects/ProjectCard'; import ButtonLink from '@/components/links/ButtonLink'; import CustomLink from '@/components/links/CustomLink'; import UnstyledLink from '@/components/links/UnstyledLink'; +import Seo from '@/components/Seo'; import { BlogFrontmatter, ProjectFrontmatter } from '@/types/frontmatters'; @@ -33,157 +34,166 @@ export default function HomePage() { useInjectContentMeta('projects', 'featuredProjects') || []; const populatedPosts = useInjectContentMeta('blog', 'featuredBlogs') || []; return ( -
-
-
-

- -

-

- You can call me Nilay -

-

- I'm a programmer based in India. I try to solve real-world problems - and create value. I build products with robust functionality and - secure code. -

-

- Don't forget to sign my{' '} - guestbook! -

-
- About me! -
-
- + +
+
+
+

+ +

+

- - Resume - - Nilay +

+

- - nilay.sharan - - +

- - SubstantialCattle5 - -

-
- - - -
- {/* Projects */} -
-
-

- Curated Projects -

-

- Below are some of my favorite projects over the years, a few of - which have been featured in Yantra, Social Transformers, Devsoc and - more. -

-
    - {populatedProjects.map((project, i) => ( - 2 && 'hidden sm:block')} - /> - ))} -
- - See more project - -
-
- {/* Blogs */} -
-
-

- Blogs Archive -

-

- When I'm not working on projects, I enjoy travelling, taking - pictures and writing blogs. Here are a few select. -

-
    - {populatedPosts.map((post, i) => ( - 2 && 'hidden sm:block')} - /> - ))} -
- - See more Blogs - -
-
-
+ Don't forget to sign my{' '} + guestbook! +

+
+ About me! +
+
+ + + Resume + + + + nilay.sharan + + + + SubstantialCattle5 + +
+ + + + +
+ {/* Projects */} +
+
+

+ Curated Projects +

+

+ Below are some of my favorite projects over the years, a few of + which have been featured in Yantra, Social Transformers, Devsoc + and more. +

+
    + {populatedProjects.map((project, i) => ( + 2 && 'hidden sm:block')} + /> + ))} +
+ + See more project + +
+
+ {/* Blogs */} +
+
+

+ Blogs Archive +

+

+ When I'm not working on projects, I enjoy travelling, taking + pictures and writing blogs. Here are a few select. +

+
    + {populatedPosts.map((post, i) => ( + 2 && 'hidden sm:block')} + /> + ))} +
+ + See more Blogs + +
+
+
+ ); } diff --git a/src/app/projects/[slug]/page.tsx b/src/app/projects/[slug]/page.tsx new file mode 100644 index 0000000..d6ce233 --- /dev/null +++ b/src/app/projects/[slug]/page.tsx @@ -0,0 +1,59 @@ +'use client'; +import { usePathname } from 'next/navigation'; +import * as React from 'react'; +import Typewriter from 'typewriter-effect'; + +import ProjectPage from '@/components/content/projects/ProjectPage'; +import Seo from '@/components/Seo'; + +import { ProjectFrontmatter } from '@/types/frontmatters'; + +export default function PagePage() { + const [data, setData] = React.useState<{ + code: string; + frontmatter: ProjectFrontmatter; + }>(); + const [slug, setSlug] = React.useState(''); + + const pathName = usePathname().split('/').pop(); + + React.useEffect(() => { + if (pathName) { + setSlug(pathName); + } + }, [pathName]); + + React.useEffect(() => { + fetch(`/api/projects/${slug}`) + .then((res) => res.json()) + .then((data) => { + return setData(data); + }); + }, [slug]); + + if (!data) { + return ( +

+ +

+ ); + } + + return ( + <> + +
+ +
+ + ); +} diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx new file mode 100644 index 0000000..e187fcf --- /dev/null +++ b/src/components/Seo.tsx @@ -0,0 +1,200 @@ +import Head from 'next/head'; +import { useRouter } from 'next/router'; + +import { openGraph } from '@/lib/helper.client'; + +const defaultMeta = { + title: 'Nilay Nath Sharan', + siteName: 'nilaysharan.vercel.app', + description: + 'An online portfolio and blog by Nilay Sharan. Showcase of my projects, and some of my thoughts.', + url: 'https://nilaysharan.vercel.app', + image: 'https://nilaysharan.verce.app/favicon/large-og.jpg', + type: 'website', + robots: 'follow, index', +}; + +type SeoProps = { + date?: string; + templateTitle?: string; + isBlog?: boolean; + banner?: string; + canonical?: string; +} & Partial; + +export default function Seo(props: SeoProps) { + const router = useRouter(); + const meta = { + ...defaultMeta, + ...props, + }; + meta['title'] = props.templateTitle + ? `${props.templateTitle} | ${meta.siteName}` + : meta.title; + + // Use siteName if there is templateTitle + // but show full title if there is none + meta.image = openGraph({ + description: meta.description, + siteName: props.templateTitle ? meta.siteName : meta.title, + templateTitle: props.templateTitle, + banner: props.banner, + isBlog: props.isBlog, + }); + + return ( + + {meta.title} + + + + + {/* Open Graph */} + + + + + + {/* Twitter */} + + + + + + {meta.date && ( + <> + + + + + )} + {meta.isBlog && ( +