forked from vickonrails/next-starter-peacock
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/vickonrails/next-starter-…
…peacock into update-to-next-14
- Loading branch information
Showing
121 changed files
with
1,934 additions
and
2,628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"extends": "next/core-web-vitals", | ||
"rules": { | ||
"no-console": "error", | ||
"jsx-quotes": [ | ||
"error", | ||
"prefer-double" | ||
], | ||
"quotes": [ | ||
"error", | ||
"single", | ||
{ | ||
"avoidEscape": true | ||
} | ||
] | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use client' | ||
import React, { useEffect } from 'react' | ||
|
||
import hljs from 'highlight.js/lib/core'; | ||
import javascript from 'highlight.js/lib/languages/javascript'; | ||
|
||
export default function Content({ html }) { | ||
useEffect(() => { | ||
hljs.registerLanguage('javascript', javascript) | ||
hljs.highlightAll(); | ||
}, []); | ||
|
||
return ( | ||
<div className="content-body mb-8" dangerouslySetInnerHTML={{ __html: html }} /> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import { Chips, Container } from '@components'; | ||
import { IContentType, getContentData, getContentList, getContentTypes } from '@utils/content'; | ||
import { CONTENT_TYPES_MAP } from '@utils/content-types'; | ||
import { Metadata } from 'next'; | ||
import Image from 'next/image'; | ||
import { notFound } from 'next/navigation'; | ||
import BackButton from '../../../components/back-button'; | ||
import { author, site } from '../../../config/index.json'; | ||
import Content from './content'; | ||
|
||
export async function generateMetadata({ params }): Promise<Metadata> { | ||
const { title, previewImage, description } = await getContentData(params.slug, params.contentType) | ||
return { | ||
title: `${title} | ${site.siteTitle}`, | ||
description: description ?? site.siteDescription, | ||
openGraph: { | ||
title: `${title} | ${site.siteName}`, | ||
description: description ?? site.siteDescription, | ||
url: site.siteUrl, | ||
images: previewImage ?? site.siteImage, | ||
siteName: site.siteName, | ||
}, | ||
twitter: { | ||
card: 'summary_large_image', | ||
creator: author.twitterHandle, | ||
images: previewImage ?? site.siteImage | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* statically generate all content pages | ||
*/ | ||
export async function generateStaticParams() { | ||
const contentTypes = getContentTypes(); | ||
|
||
return contentTypes.map(contentType => { | ||
const contentList = getContentList(contentType); | ||
return contentList.map(({ slug }) => { | ||
return { | ||
contentType, | ||
slug | ||
} | ||
}) | ||
}).flat() | ||
} | ||
|
||
/** | ||
* Renders articles markdown posts | ||
*/ | ||
|
||
async function fetchContentData(slug: string, contentType: IContentType) { | ||
return await getContentData(slug, contentType) | ||
} | ||
|
||
type Params = { | ||
slug: string | ||
contentType: IContentType | ||
} | ||
|
||
export default async function ContentPage({ params }) { | ||
const { slug, contentType } = params as Params | ||
|
||
if (!CONTENT_TYPES_MAP.has(contentType)) { | ||
return notFound(); | ||
} | ||
|
||
const content = await fetchContentData(slug, contentType); | ||
if (content.draft) return notFound(); | ||
|
||
if (contentType === 'works') return <WorkPage work={content} /> | ||
|
||
return ( | ||
<Container width="narrow"> | ||
<header> | ||
<section className="pt-16"> | ||
<h1 className="my-0 font-bold font-display mb-2 text-2xl/normal md:text-4xl max-w-xl">{content.title}</h1> | ||
<time className="block text-accent-4 mb-8">{content.date.toString()}</time> | ||
{content.previewImage && ( | ||
<Image className="pb-8 block object-cover" src={content.previewImage} height={550} width={1200} alt="" /> | ||
)} | ||
</section> | ||
</header> | ||
|
||
<Content html={content.contentHtml} /> | ||
{content.tags && <Chips items={content.tags} />} | ||
</Container> | ||
|
||
); | ||
}; | ||
|
||
function WorkPage({ work }: { work: IContentData }) { | ||
|
||
return ( | ||
<Container className="flex flex-col lg:flex-row gap-4 pt-12"> | ||
<section className="w-full lg:w-1/3 border-r border-accent-8 p-2 pr-8"> | ||
<div className="mb-8 flex flex-col items-start gap-5"> | ||
<BackButton /> | ||
<h1 className="text-4xl font-bold font-display text-accent-3">{work.title}</h1> | ||
<p className="text-accent-4">{work.description}</p> | ||
<button>Se Demo</button> | ||
</div> | ||
|
||
<ul> | ||
<TechStack techStack={work.techStack ?? []} /> | ||
<MetadataListItem item="Date" value={work.date.toString()} /> | ||
{work.problem && <MetadataListItem item="Problem" value={work.problem ?? ''} />} | ||
</ul> | ||
|
||
</section> | ||
|
||
<section className="w-full lg:w-2/3 p-2"> | ||
<Image src={work.previewImage ?? ''} height={1000} width={1000} alt="" className="mb-4" /> | ||
<Content html={work.contentHtml} /> | ||
</section> | ||
|
||
</Container> | ||
) | ||
} | ||
|
||
function MetadataListItem({ item, value }: { item: string, value: string }) { | ||
return ( | ||
<li className="list-none flex gap-4 border-b border-accent-8 py-3 text-sm"> | ||
<span className="text-accent-4 w-1/3">{item}</span> | ||
<span className="w-2/3 text-accent-2">{value}</span> | ||
</li> | ||
|
||
) | ||
} | ||
|
||
function TechStack({ techStack }: { techStack: string[] }) { | ||
if (!techStack.length) return null | ||
return ( | ||
<li className="list-none flex gap-4 border-b border-accent-8 py-3 text-sm"> | ||
<span className="text-accent-4 w-1/3 flex-shrink-0">Tech Stack</span> | ||
|
||
<ul className="flex flex-wrap gap-2 flex-grow-0"> | ||
{techStack.map(tech => | ||
<li key={tech} className="select-none bg-accent-8 text-accent-2 px-2 py-1 rounded-md">{tech}</li> | ||
)} | ||
</ul> | ||
</li> | ||
) | ||
} | ||
|
||
export interface IContentData { | ||
id: string; | ||
contentHtml: string; | ||
date: Date; | ||
title: string; | ||
previewImage?: string; | ||
description?: string; | ||
tags?: string[]; | ||
category?: string; | ||
problem?: string; | ||
techStack?: string[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { Container, ContentList } from '@components'; | ||
import { IContentType, getContentList, getContentTypes } from '@utils/content'; | ||
import { CONTENT_TYPES_MAP } from '@utils/content-types'; | ||
import { Metadata } from 'next'; | ||
import { notFound } from 'next/navigation'; | ||
import { site } from '../../config/index.json'; | ||
import { generateRSS } from '@utils/rss'; | ||
|
||
/** generate list page metadata */ | ||
export function generateMetadata({ params }): Metadata { | ||
const contentType = CONTENT_TYPES_MAP.get(params.contentType) | ||
return { | ||
title: `${contentType.title} | ${site.siteTitle}`, | ||
description: contentType.description | ||
} | ||
} | ||
|
||
export async function generateStaticParams() { | ||
generateRSS(); | ||
|
||
const contentTypes = getContentTypes(); | ||
return Array.from(contentTypes).map(contentType => ({ | ||
contentType | ||
})) | ||
} | ||
|
||
/** | ||
* Index page `/index` | ||
*/ | ||
export default function ContentListPage({ params }) { | ||
const contentType = params.contentType as IContentType | ||
|
||
// redirect to 404 with wrong contentType | ||
if (!CONTENT_TYPES_MAP.has(contentType)) { | ||
return notFound(); | ||
} | ||
|
||
const content = getContentList(contentType); | ||
const isNotes = contentType.toLowerCase() === 'notes'; | ||
const { title, path, description } = CONTENT_TYPES_MAP.get(contentType); | ||
|
||
return ( | ||
<> | ||
<Container width={isNotes ? 'narrow' : 'default'}> | ||
<section className="flex flex-col py-20 gap-2 max-w-2xl"> | ||
<h1 className="text-4xl font-bold font-display"> | ||
{title} | ||
</h1> | ||
<p className="text-accent-4 text-lg"> | ||
{description} | ||
</p> | ||
</section> | ||
|
||
<ContentList | ||
basePath={path} | ||
items={content} | ||
contentType={contentType} | ||
/> | ||
</Container> | ||
</> | ||
); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
|
||
import { Container, ContentList } from '@components'; | ||
import { IContentType, getContentWithTag } from '@utils/content'; | ||
import { CONTENT_TYPES_MAP } from '@utils/content-types'; | ||
|
||
// TODO: I need to rethink the tags page. I don't think I want to have a page for each tag. | ||
// /notes/tags/programming & /articles/tags/programming. Instead I want to have a single page for all tags | ||
// /tags/programming. I think this will be easier to manage and will be more intuitive for readers. | ||
|
||
/** | ||
* Index page `/index` | ||
*/ | ||
export default function ContentListPage({ params }) { | ||
const contentType = params.contentType as IContentType | ||
const tag = params.tag as IContentType | ||
|
||
const content = getContentWithTag(tag, contentType); | ||
const isNotes = contentType.toLowerCase() === 'notes'; | ||
const { title, path, description } = CONTENT_TYPES_MAP.get(contentType); | ||
|
||
return ( | ||
<> | ||
<Container width={isNotes ? 'narrow' : 'default'}> | ||
<section className="flex flex-col py-20 gap-2 max-w-2xl"> | ||
<h1 className="text-4xl font-bold font-display"> | ||
{title} Tags | ||
</h1> | ||
<p className="text-accent-4 text-lg"> | ||
{description} | ||
</p> | ||
</section> | ||
<ContentList | ||
basePath={path} | ||
items={content} | ||
contentType={contentType} | ||
/> | ||
</Container> | ||
</> | ||
); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use client' | ||
|
||
import React from 'react' | ||
import { motion } from 'framer-motion' | ||
|
||
const variants = { | ||
hidden: { opacity: 0, y: 20 }, | ||
enter: { opacity: 1, y: 0 } | ||
} | ||
|
||
export default function Template({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<motion.main | ||
variants={variants} | ||
initial="hidden" | ||
animate="enter" | ||
transition={{ type: 'linear' }} | ||
> | ||
{children} | ||
</motion.main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
|
||
import { Container } from '@components'; | ||
import SiteConfig from '../../config/index.json'; | ||
|
||
export const metadata = { | ||
title: `About Me | ${SiteConfig.site.siteName}`, | ||
description: SiteConfig.site.siteDescription | ||
} | ||
|
||
/** | ||
* About page `/about` | ||
*/ | ||
|
||
export default function About() { | ||
return ( | ||
<Container width="narrow"> | ||
{/* Content goes here */} | ||
<header className="pt-12 pb-4"> | ||
<h1 className="text-3xl font-bold mb-6 md:text-4xl font-display">About Me 🧘🏾♂️</h1> | ||
</header> | ||
<div className="flex text-accent-4"> | ||
<div> | ||
<p className="mb-4"> | ||
Victor is a dynamic and innovative software engineer with over six years of experience in the tech industry. Specializing in full-stack development, Victor combines a deep understanding of backend technologies with a passion for front-end design, creating seamless and efficient user experiences. His journey in the tech world began with a Bachelor's degree in Computer Science, followed by a rapid ascent through various roles, from junior developer to a lead engineer. | ||
</p> | ||
<p> | ||
Victor's expertise lies in leveraging the latest technologies to build scalable, responsive web applications and cloud-based solutions. His skill set encompasses a wide range of technologies including JavaScript (React.js, Node.js), Python, and cloud platforms like AWS and Azure. | ||
</p> | ||
</div> | ||
</div> | ||
</Container> | ||
); | ||
}; | ||
|
Binary file not shown.
Oops, something went wrong.