init
This commit is contained in:
commit
04099b0f05
35 changed files with 1742 additions and 0 deletions
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
caydenwebsite
|
||||||
7
.idea/cat-activity.xml
generated
Normal file
7
.idea/cat-activity.xml
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CatActivitySettingProjectState">
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
<option name="firstInit" value="false" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/caydenwebsite.iml
generated
Normal file
8
.idea/caydenwebsite.iml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
7
.idea/discord.xml
generated
Normal file
7
.idea/discord.xml
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="ASK" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
15
.idea/git_toolbox_prj.xml
generated
Normal file
15
.idea/git_toolbox_prj.xml
generated
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GitToolBoxProjectSettings">
|
||||||
|
<option name="commitMessageIssueKeyValidationOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
<option name="commitMessageValidationEnabledOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
13
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
13
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N806" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/caydenwebsite.iml" filepath="$PROJECT_DIR$/.idea/caydenwebsite.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"singleQuote": true,
|
||||||
|
"useTabs": true
|
||||||
|
}
|
||||||
5
AGENTS.md
Normal file
5
AGENTS.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!-- BEGIN:nextjs-agent-rules -->
|
||||||
|
# This is NOT the Next.js you know
|
||||||
|
|
||||||
|
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||||
|
<!-- END:nextjs-agent-rules -->
|
||||||
1
CLAUDE.md
Normal file
1
CLAUDE.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
@AGENTS.md
|
||||||
36
README.md
Normal file
36
README.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
23
app/blog/[slug]/page.tsx
Normal file
23
app/blog/[slug]/page.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import Link from "next/link"
|
||||||
|
import { ArrowLeftIcon } from "@heroicons/react/24/solid"
|
||||||
|
import { getArticleData } from "@/lib/articles";
|
||||||
|
|
||||||
|
const Article = async ({ params }: { params: Promise<{ slug: string }> }) => {
|
||||||
|
const { slug } = await params;
|
||||||
|
const articleData = await getArticleData(slug);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={"mx-auto w-10/12 md:w-1/2 mt-20 flex flex-col gap-5"}>
|
||||||
|
<div className={"flex justify-between font-poppins"}>
|
||||||
|
<Link href={"/blog"} className={"flex flex-row gap-1 place-items-center"}>
|
||||||
|
<ArrowLeftIcon width={20} />
|
||||||
|
<p>blog homepage</p>
|
||||||
|
</Link>
|
||||||
|
<p>{articleData.date.toString()}</p>
|
||||||
|
</div>
|
||||||
|
<article className={"article"} dangerouslySetInnerHTML={{ __html: articleData.contentHtml }} />
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Article;
|
||||||
21
app/blog/page.tsx
Normal file
21
app/blog/page.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import {getCategorizedArticles} from "@/lib/articles";
|
||||||
|
import ArticleItemList from "@/components/ArticleListItem";
|
||||||
|
|
||||||
|
export default function BlogPage() {
|
||||||
|
const articles = getCategorizedArticles()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section className={"mx-auto w-11/12 md:w-1/2 mt-20 flex flex-col gap-16 mb-20"}>
|
||||||
|
<header className={"font-cormorantGaramond font-light text-6xl text-center"}>
|
||||||
|
<h1>Shrimple blog.</h1>
|
||||||
|
</header>
|
||||||
|
<section className={"md:grid md:grid-cols-2 flex flex-col gap-10"}>
|
||||||
|
{articles != null && Object.keys(articles).map((article) => (
|
||||||
|
<ArticleItemList category={article} articles={articles[article]} key={article}/>
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
7
app/contact/page.tsx
Normal file
7
app/contact/page.tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export default function Contact() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
||||||
|
<h1 className="text-4xl font-bold">Contact page, wip.</h1>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
BIN
app/favicon.ico
Normal file
BIN
app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
84
app/globals.css
Normal file
84
app/globals.css
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--font-cormorantGaramond: "Cormorant_Garamond", "sans-serif";
|
||||||
|
--font-poppins: "Poppins", "sans-serif";
|
||||||
|
|
||||||
|
/* Nord: Polar Night */
|
||||||
|
--color-nord-0: #2e3440;
|
||||||
|
--color-nord-1: #3b4252;
|
||||||
|
--color-nord-2: #4D535F;
|
||||||
|
--color-nord-3: #434c5e;
|
||||||
|
|
||||||
|
/* Nord: Snow Storm */
|
||||||
|
--color-nord-4: #d8dee9;
|
||||||
|
--color-nord-5: #e5e9f0;
|
||||||
|
--color-nord-6: #eceff4;
|
||||||
|
|
||||||
|
/* Nord: Frost */
|
||||||
|
--color-nord-7: #8fbcbb;
|
||||||
|
--color-nord-8: #88c0d0;
|
||||||
|
--color-nord-9: #81a1c1;
|
||||||
|
--color-nord-10: #5e81ac;
|
||||||
|
|
||||||
|
/* Nord: Aurora */
|
||||||
|
--color-nord-11: #bf616a;
|
||||||
|
--color-nord-12: #d08770;
|
||||||
|
--color-nord-13: #ebcb8b;
|
||||||
|
--color-nord-14: #a3be8c;
|
||||||
|
--color-nord-15: #b48ead;
|
||||||
|
|
||||||
|
/* Optional semantic aliases */
|
||||||
|
--color-polar-night-dark: #2e3440;
|
||||||
|
--color-polar-night: #3b4252;
|
||||||
|
--color-polar-night-light: #434c5e;
|
||||||
|
--color-polar-night-lighter: #4c566a;
|
||||||
|
|
||||||
|
--color-snow-storm-dark: #d8dee9;
|
||||||
|
--color-snow-storm: #e5e9f0;
|
||||||
|
--color-snow-storm-light: #eceff4;
|
||||||
|
|
||||||
|
--color-frost-green: #8fbcbb;
|
||||||
|
--color-frost-cyan: #88c0d0;
|
||||||
|
--color-frost-blue: #81a1c1;
|
||||||
|
--color-frost-deep-blue: #5e81ac;
|
||||||
|
|
||||||
|
--color-aurora-red: #bf616a;
|
||||||
|
--color-aurora-orange: #d08770;
|
||||||
|
--color-aurora-yellow: #ebcb8b;
|
||||||
|
--color-aurora-green: #a3be8c;
|
||||||
|
--color-aurora-purple: #b48ead;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article {
|
||||||
|
@apply flex flex-col gap-3 font-poppins text-lg tracking-wide mb-20
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > h1 {
|
||||||
|
@apply text-4xl font-cormorantGaramond text-center tracking-tight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > h2 {
|
||||||
|
@apply text-3xl font-cormorantGaramond text-center tracking-tight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > ol {
|
||||||
|
@apply list-decimal flex flex-col mx-10 gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > ul {
|
||||||
|
@apply list-disc flex flex-col mx-10 gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > pre {
|
||||||
|
@apply bg-neutral-950 text-neutral-50 p-5 overflow-scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > blockquote {
|
||||||
|
@apply pl-5 italic border-l-2 border-neutral-600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article > p > img {
|
||||||
|
@apply w-1/2 mx-auto;
|
||||||
|
}
|
||||||
|
|
||||||
38
app/layout.tsx
Normal file
38
app/layout.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import type {Metadata} from "next";
|
||||||
|
import {Cormorant_Garamond, Poppins} from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
import Header from "@/components/layout/layout-header";
|
||||||
|
|
||||||
|
const cormorantGaramond = Cormorant_Garamond({
|
||||||
|
subsets: ['latin'],
|
||||||
|
variable: "--font-cormorantGaramond",
|
||||||
|
weight: ['400']
|
||||||
|
})
|
||||||
|
|
||||||
|
const poppins = Poppins({
|
||||||
|
subsets: ['latin'],
|
||||||
|
variable: "--font-poppins",
|
||||||
|
weight: ['400', '600']
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Create Next App",
|
||||||
|
description: "Generated by create next app",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html
|
||||||
|
lang="en"
|
||||||
|
className={`${cormorantGaramond.variable} ${poppins.variable} bg-neutral-100 h-full antialiased`}
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<body className="min-h-full flex flex-col bg-polar-night-lighter text-snow-storm text-shadow-snow-storm-dark">{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
app/page.tsx
Normal file
14
app/page.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section className={"mx-auto w-11/12 md:w-1/2 mt-20 flex flex-col gap-16 mb-20 color-nord-9"}>
|
||||||
|
<header className={"font-cormorantGaramond font-light text-6xl text-center"}>
|
||||||
|
<h1>Hello there, world.</h1>
|
||||||
|
</header>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
7
articles/setup.md
Normal file
7
articles/setup.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: "The art of the side hustle"
|
||||||
|
category: "business"
|
||||||
|
date: "02-02-2023"
|
||||||
|
---
|
||||||
|
|
||||||
|
# The art of the side hustle.
|
||||||
27
articles/squirt.md
Normal file
27
articles/squirt.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
title: "Squirt"
|
||||||
|
category: "personal"
|
||||||
|
date: "29-06-2026"
|
||||||
|
---
|
||||||
|
|
||||||
|
# The Squirt Article
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Squirt is a playful and energetic topic that can represent movement, surprise, and a little bit of chaos. Sometimes, the smallest things can make the biggest splash.
|
||||||
|
|
||||||
|
In everyday life, a squirt might be something simple: a splash of water, a squeeze from a bottle, or a sudden burst of energy. It is quick, unexpected, and often memorable.
|
||||||
|
|
||||||
|
## A Small Burst of Fun
|
||||||
|
|
||||||
|
There is something fun about the word squirt. It feels lighthearted and informal. It does not take itself too seriously, which makes it a great subject for a personal article.
|
||||||
|
|
||||||
|
Whether it reminds you of summer days, water fights, or tiny moments of surprise, squirt can be a symbol of simple joy.
|
||||||
|
|
||||||
|
## Final Thoughts
|
||||||
|
|
||||||
|
Not every article needs to be serious or complicated. Sometimes, writing about something small and silly is enough to create a moment of fun.
|
||||||
|
|
||||||
|
Squirt may be simple, but it still makes a splash.
|
||||||
|
|
||||||
|
I had NO fucking idea what to put here, so, yeah, squirt.
|
||||||
7
articles/stress.md
Normal file
7
articles/stress.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: "Charles de Souza"
|
||||||
|
category: "personal"
|
||||||
|
date: "02-04-2023"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Stress and management
|
||||||
26
components/ArticleListItem.tsx
Normal file
26
components/ArticleListItem.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import Link from "next/link"
|
||||||
|
import type { ArticleItem} from "@/types";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
category: string,
|
||||||
|
articles: ArticleItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const ArticleItemList = ({ category, articles }: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={"flex flex-col gap-5"}>
|
||||||
|
<h2 className={"font-cormorantGaramond text-4xl"}>{category}</h2>
|
||||||
|
<div className={"flex flex-col gap-2.5 font-poppins text-lg"}>
|
||||||
|
{articles.map((article, id) => (
|
||||||
|
<Link href={`/blog/${article.id}`} key={id} className={"hover:text-nord-12 transition duration-250"}>
|
||||||
|
{article.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArticleItemList
|
||||||
62
components/layout/layout-header.tsx
Normal file
62
components/layout/layout-header.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import Link from 'next/link';
|
||||||
|
import Logo from "../../public/borb.png"
|
||||||
|
|
||||||
|
const Header = () => {
|
||||||
|
const [navbar, setNavbar] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<header className="font-poppins bg-polar-night-light z-10">
|
||||||
|
<div className="justify-between px-2 lg:px-0 mx-auto lg:max-w-7xl md:items-center md:flex md:px-4">
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between md:block">
|
||||||
|
<div className='flex items-center justify-between md:py-3 gap-10'>
|
||||||
|
<Link href={"/"} className="flex flex-col items-center gap-0 leading-none">
|
||||||
|
<Image src={Logo} width={100} alt='Logo'/>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="md:hidden">
|
||||||
|
<button
|
||||||
|
className="p-2 text-gray-700 rounded-md outline-none focus:border-gray-400 focus:border"
|
||||||
|
onClick={() => setNavbar(!navbar)}>
|
||||||
|
{navbar ? (
|
||||||
|
<div className="bar text-white"></div>
|
||||||
|
) : (
|
||||||
|
<div className="close text-white"></div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr className='md:opacity-0 md:pt-3'></hr>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className={`flex-1 justify-self-center md:block md:pb-0 md:mt-0 ${navbar ? 'p-12 md:p-0 block' : 'hidden'}`}>
|
||||||
|
<ul className=" md:h-auto items-center justify-center md:flex">
|
||||||
|
<li className="text-xl text-white py-2 my-2 md:my-0 md:px-6 text-center md:border-b-0 border-white hover:text-nord-12 transition duration-250">
|
||||||
|
<Link href="/" onClick={() => setNavbar(!navbar)}
|
||||||
|
className='sm:px-52 md:px-0'>Home</Link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li className="text-xl text-white py-2 my-2 md:my-0 px-6 text-center md:border-b-0 border-white hover:text-nord-12 transition duration-250">
|
||||||
|
<Link href="/blog" onClick={() => setNavbar(!navbar)}
|
||||||
|
className='sm:px-52 md:px-0'>Blog</Link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li className="text-xl text-white py-2 my-2 md:my-0 px-6 text-center md:border-b-0 border-white hover:text-nord-12 transition duration-250">
|
||||||
|
<Link href="/contact" onClick={() => setNavbar(!navbar)}
|
||||||
|
className='sm:px-48 md:px-0'>Contact</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Header
|
||||||
18
eslint.config.mjs
Normal file
18
eslint.config.mjs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTs from "eslint-config-next/typescript";
|
||||||
|
|
||||||
|
const eslintConfig = defineConfig([
|
||||||
|
...nextVitals,
|
||||||
|
...nextTs,
|
||||||
|
// Override default ignores of eslint-config-next.
|
||||||
|
globalIgnores([
|
||||||
|
// Default ignores of eslint-config-next:
|
||||||
|
".next/**",
|
||||||
|
"out/**",
|
||||||
|
"build/**",
|
||||||
|
"next-env.d.ts",
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
74
lib/articles.ts
Normal file
74
lib/articles.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
import fs from "fs"
|
||||||
|
import matter from "gray-matter"
|
||||||
|
import path from "path"
|
||||||
|
import moment from "moment"
|
||||||
|
import {remark} from "remark";
|
||||||
|
import html from "remark-html"
|
||||||
|
|
||||||
|
import type {ArticleItem} from "@/types";
|
||||||
|
|
||||||
|
const articlesDirectory = path.join(process.cwd(), "articles");
|
||||||
|
|
||||||
|
const getSortedArticles = (): ArticleItem[] => {
|
||||||
|
const fileNames = fs.readdirSync(articlesDirectory);
|
||||||
|
|
||||||
|
const allArticlesData = fileNames.map((fileName) => {
|
||||||
|
const id = fileName.replace(/\.md$/, "");
|
||||||
|
|
||||||
|
const fullPath = path.join(articlesDirectory, fileName);
|
||||||
|
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||||
|
|
||||||
|
const matterResult = matter(fileContents);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
title: matterResult.data.title,
|
||||||
|
date: matterResult.data.date,
|
||||||
|
category: matterResult.data.category,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return allArticlesData.sort((a, b) => {
|
||||||
|
const format = "DD-MM-YYYY";
|
||||||
|
const dateOne = moment(a.date, format);
|
||||||
|
const dateTwo = moment(b.date, format);
|
||||||
|
|
||||||
|
return dateTwo.valueOf() - dateOne.valueOf();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCategorizedArticles = (): Record<string, ArticleItem[]> => {
|
||||||
|
const sortedArticles = getSortedArticles();
|
||||||
|
const categorisedArticles: Record<string, ArticleItem[]> = {}
|
||||||
|
|
||||||
|
sortedArticles.forEach((article) => {
|
||||||
|
if (!categorisedArticles[article.category]) {
|
||||||
|
categorisedArticles[article.category] = []
|
||||||
|
}
|
||||||
|
categorisedArticles[article.category].push(article);
|
||||||
|
})
|
||||||
|
|
||||||
|
return categorisedArticles;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getArticleData = async (id: string) => {
|
||||||
|
const fullPath = path.join(articlesDirectory, `${id}.md`);
|
||||||
|
|
||||||
|
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||||
|
|
||||||
|
const matterResult = matter(fileContents);
|
||||||
|
|
||||||
|
const processedContent = await remark()
|
||||||
|
.use(html)
|
||||||
|
.process(matterResult.content)
|
||||||
|
|
||||||
|
const contentHtml = processedContent.toString();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
contentHtml,
|
||||||
|
title: matterResult.data.title,
|
||||||
|
category: matterResult.data.category,
|
||||||
|
date: moment(matterResult.data.date, "DD-MM-YYYY").format("MMMM Do YYYY")
|
||||||
|
}
|
||||||
|
}
|
||||||
7
next.config.ts
Normal file
7
next.config.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
/* config options here */
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
34
package.json
Normal file
34
package.json
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "myblog",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@heroicons/react": "^2.2.0",
|
||||||
|
"eslint-config-prettier": "^10.1.8",
|
||||||
|
"eslint-plugin-prettier": "^5.5.6",
|
||||||
|
"gray-matter": "^4.0.3",
|
||||||
|
"moment": "^2.30.1",
|
||||||
|
"next": "16.2.9",
|
||||||
|
"prettier": "^3.9.4",
|
||||||
|
"react": "19.2.4",
|
||||||
|
"react-dom": "19.2.4",
|
||||||
|
"remark": "^15.0.1",
|
||||||
|
"remark-html": "^16.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4.3.1",
|
||||||
|
"@types/node": "^20.19.43",
|
||||||
|
"@types/react": "^19.2.17",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"eslint": "^9.39.4",
|
||||||
|
"eslint-config-next": "16.2.9",
|
||||||
|
"tailwindcss": "^4.3.1",
|
||||||
|
"typescript": "^5.9.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
postcss.config.mjs
Normal file
7
postcss.config.mjs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
const config = {
|
||||||
|
plugins: {
|
||||||
|
"@tailwindcss/postcss": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
BIN
public/fatdudesquirting.jpg
Normal file
BIN
public/fatdudesquirting.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
34
tsconfig.json
Normal file
34
tsconfig.json
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts",
|
||||||
|
"**/*.mts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
6
types/index.ts
Normal file
6
types/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export type ArticleItem = {
|
||||||
|
id: string,
|
||||||
|
title: string,
|
||||||
|
date: string,
|
||||||
|
category: string
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue