refactor: remove portfolio
|
@ -12,7 +12,6 @@
|
||||||
- `apps`
|
- `apps`
|
||||||
- `main` - https://developomp.com
|
- `main` - https://developomp.com
|
||||||
- `blog` - https://blog.developomp.com
|
- `blog` - https://blog.developomp.com
|
||||||
- `portfolio` - https://portfolio.developomp.com
|
|
||||||
- `packages` - shared stuff used across different packages
|
- `packages` - shared stuff used across different packages
|
||||||
- `content` - Shared content
|
- `content` - Shared content
|
||||||
- `eslint-config` - ESLint configuration files
|
- `eslint-config` - ESLint configuration files
|
||||||
|
@ -46,7 +45,6 @@
|
||||||
- `pnpm dev` - Run all apps and packages locally
|
- `pnpm dev` - Run all apps and packages locally
|
||||||
- blog - http://localhost:3000
|
- blog - http://localhost:3000
|
||||||
- main - http://localhost:5173
|
- main - http://localhost:5173
|
||||||
- portfolio - http://localhost:5174
|
|
||||||
- `pnpm lint` - Lint all apps and packages
|
- `pnpm lint` - Lint all apps and packages
|
||||||
- `pnpm clean` - Remove all auto-generated content such as `node_modules` and `dist`.
|
- `pnpm clean` - Remove all auto-generated content such as `node_modules` and `dist`.
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-tailwindcss": "^0.5.9",
|
"prettier-plugin-tailwindcss": "^0.5.9",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-collapse": "^5.1.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"serve": "^14.2.0",
|
"serve": "^14.2.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.0",
|
||||||
|
|
|
@ -75,13 +75,6 @@ export function parsePageData(
|
||||||
|
|
||||||
order: [],
|
order: [],
|
||||||
length: 0,
|
length: 0,
|
||||||
|
|
||||||
// portfolio (unused)
|
|
||||||
|
|
||||||
image: "",
|
|
||||||
overview: "",
|
|
||||||
badges: [],
|
|
||||||
repo: "",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load and parse content differently depending on the content type
|
// load and parse content differently depending on the content type
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en" class="dark">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="About developomp - socials, links, discord server, contact, blog, portfolio, resume, etc."
|
content="About developomp - socials, links, discord server, contact, blog, resume, etc."
|
||||||
/>
|
/>
|
||||||
<title>developomp</title>
|
<title>developomp</title>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<meta property="og:site_name" content="developomp" />
|
<meta property="og:site_name" content="developomp" />
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
property="og:description"
|
||||||
content="About developomp - socials, links, discord server, contact, blog, portfolio, resume, etc."
|
content="About developomp - socials, links, discord server, contact, blog, resume, etc."
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://developomp.com" />
|
<meta property="og:url" content="https://developomp.com" />
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<script>
|
|
||||||
import { page } from "$app/stores"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<nav
|
|
||||||
class="mx-auto flex h-14 max-w-screen-mobile flex-col items-center justify-between px-4 xs:flex-row"
|
|
||||||
>
|
|
||||||
<!-- only show home button when not in home -->
|
|
||||||
<a
|
|
||||||
href="/"
|
|
||||||
aria-current={$page.url.pathname === "/" ? "page" : undefined}
|
|
||||||
class="left-0"
|
|
||||||
style={$page.url.pathname === "/" ? "visibility: hidden;" : ""}
|
|
||||||
>
|
|
||||||
Home
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<ul class="flex list-none gap-4 no-underline">
|
|
||||||
<li aria-current={$page.url.pathname === "/" ? "page" : undefined}>
|
|
||||||
<a target="_blank" href="https://blog.developomp.com">Blog</a>
|
|
||||||
</li>
|
|
||||||
<li aria-current={$page.url.pathname === "/about" ? "page" : undefined}>
|
|
||||||
<a target="_blank" href="https://portfolio.developomp.com">
|
|
||||||
Portfolio
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
li {
|
|
||||||
@apply inline;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,10 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import "./app.css"
|
import "./app.css"
|
||||||
|
|
||||||
import Navbar from "$/components/Navbar.svelte"
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Navbar />
|
|
||||||
<main
|
<main
|
||||||
class="mx-auto my-0 flex w-full max-w-5xl flex-col items-center px-8 py-0 text-center font-normal"
|
class="mx-auto my-0 flex w-full max-w-5xl flex-col items-center px-8 py-0 text-center font-normal"
|
||||||
>
|
>
|
||||||
|
|
|
@ -10,11 +10,6 @@
|
||||||
<changefreq>always</changefreq>
|
<changefreq>always</changefreq>
|
||||||
<priority>0.8</priority>
|
<priority>0.8</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
|
||||||
<loc>https://portfolio.developomp.com</loc>
|
|
||||||
<changefreq>always</changefreq>
|
|
||||||
<priority>0.9</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
<url>
|
||||||
<loc>https://developomp.com/resume</loc>
|
<loc>https://developomp.com/resume</loc>
|
||||||
<changefreq>always</changefreq>
|
<changefreq>always</changefreq>
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
extends: ["next/core-web-vitals", "@developomp-site/eslint-config"],
|
|
||||||
rules: {
|
|
||||||
"react-hooks/exhaustive-deps": "off",
|
|
||||||
"react/no-unescaped-entities": "off",
|
|
||||||
},
|
|
||||||
}
|
|
36
apps/portfolio/.gitignore
vendored
|
@ -1,36 +0,0 @@
|
||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/.pnp
|
|
||||||
.pnp.js
|
|
||||||
|
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
/test-results
|
|
||||||
|
|
||||||
# next.js
|
|
||||||
/.next/
|
|
||||||
/out/
|
|
||||||
|
|
||||||
# production
|
|
||||||
/build
|
|
||||||
|
|
||||||
# misc
|
|
||||||
.DS_Store
|
|
||||||
*.pem
|
|
||||||
|
|
||||||
# debug
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env*.local
|
|
||||||
|
|
||||||
# vercel
|
|
||||||
.vercel
|
|
||||||
|
|
||||||
# typescript
|
|
||||||
*.tsbuildinfo
|
|
||||||
next-env.d.ts
|
|
|
@ -1,5 +0,0 @@
|
||||||
/** @type {import("prettier").Options} */
|
|
||||||
module.exports = {
|
|
||||||
...require("@developomp-site/prettier-config"),
|
|
||||||
plugins: ["prettier-plugin-tailwindcss"],
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
import { expect, test } from "@playwright/test"
|
|
||||||
|
|
||||||
test("Should return 404 for invalid routes", async ({ page }) => {
|
|
||||||
const response = await page.goto("/path/that/does/not/exist")
|
|
||||||
expect(response?.status()).toEqual(404)
|
|
||||||
})
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { expect, test } from "@playwright/test"
|
|
||||||
|
|
||||||
const prefix = "pomp's portfolio | "
|
|
||||||
|
|
||||||
test("should have proper title", async ({ page }) => {
|
|
||||||
await page.goto("/")
|
|
||||||
await expect(page).toHaveTitle(`${prefix}Home`)
|
|
||||||
|
|
||||||
await page.goto("/project/developomp-site")
|
|
||||||
await expect(page).toHaveTitle(`${prefix}developomp-site`)
|
|
||||||
|
|
||||||
await page.goto("/404")
|
|
||||||
await expect(page).toHaveTitle(`${prefix}Page Not Found`)
|
|
||||||
})
|
|
|
@ -1,8 +0,0 @@
|
||||||
// https://next-sitemap.iamvishnusankar.com/docs/documentation/configuration
|
|
||||||
/** @type {import('next-sitemap').IConfig} */
|
|
||||||
module.exports = {
|
|
||||||
siteUrl: "https://portfolio.developomp.com",
|
|
||||||
generateRobotsTxt: true,
|
|
||||||
outDir: "dist",
|
|
||||||
priority: 0.8,
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
/** @type {import('next').NextConfig} */
|
|
||||||
const nextConfig = {
|
|
||||||
output: "export",
|
|
||||||
distDir: "dist",
|
|
||||||
images: { unoptimized: true },
|
|
||||||
experimental: {
|
|
||||||
externalDir: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = nextConfig
|
|
|
@ -1,55 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@developomp-site/portfolio",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "open-cli http://localhost:5174 && next dev -p 5174",
|
|
||||||
"build": "next build",
|
|
||||||
"postbuild": "next-sitemap",
|
|
||||||
"serve": "serve dist --listen 5174",
|
|
||||||
"test:e2e": "playwright test",
|
|
||||||
"lint": "next lint",
|
|
||||||
"clean": "rm -rf .next .turbo dist node_modules test-results"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@developomp-site/blog": "workspace:*",
|
|
||||||
"@developomp-site/content": "workspace:*",
|
|
||||||
"@developomp-site/eslint-config": "workspace:*",
|
|
||||||
"@developomp-site/playwright-config": "workspace:*",
|
|
||||||
"@developomp-site/prettier-config": "workspace:*",
|
|
||||||
"@developomp-site/tailwind-config": "workspace:*",
|
|
||||||
"@fontsource/noto-sans-kr": "^5.0.5",
|
|
||||||
"@fontsource/source-code-pro": "^5.0.5",
|
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
||||||
"@kunukn/react-collapse": "^2.2.10",
|
|
||||||
"@playwright/test": "^1.36.2",
|
|
||||||
"@types/highlight.js": "^10.1.0",
|
|
||||||
"@types/katex": "^0.16.7",
|
|
||||||
"@types/node": "^20.10.5",
|
|
||||||
"@types/react": "18.2.17",
|
|
||||||
"@types/react-collapse": "^5.0.1",
|
|
||||||
"@types/react-dom": "18.2.7",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
||||||
"@typescript-eslint/parser": "^6.15.0",
|
|
||||||
"autoprefixer": "^10.4.16",
|
|
||||||
"eslint": "^8.56.0",
|
|
||||||
"eslint-config-next": "13.4.12",
|
|
||||||
"highlight.js": "^11.8.0",
|
|
||||||
"katex": "^0.16.8",
|
|
||||||
"next": "13.4.12",
|
|
||||||
"next-sitemap": "^4.1.8",
|
|
||||||
"open-cli": "^7.2.0",
|
|
||||||
"postcss": "^8.4.32",
|
|
||||||
"postcss-load-config": "^4.0.1",
|
|
||||||
"prettier": "^3.2.5",
|
|
||||||
"prettier-plugin-tailwindcss": "^0.5.9",
|
|
||||||
"react": "18.2.0",
|
|
||||||
"react-collapse": "^5.1.1",
|
|
||||||
"react-dom": "18.2.0",
|
|
||||||
"serve": "^14.2.0",
|
|
||||||
"tailwindcss": "^3.4.0",
|
|
||||||
"typescript": "^5.3.3"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
import { createConfig } from "@developomp-site/playwright-config"
|
|
||||||
|
|
||||||
export default createConfig({
|
|
||||||
port: 5174,
|
|
||||||
})
|
|
|
@ -1,7 +0,0 @@
|
||||||
/** @type {import('postcss-load-config').Config} */
|
|
||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {},
|
|
||||||
},
|
|
||||||
}
|
|
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.5 KiB |
|
@ -1,22 +0,0 @@
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
* {
|
|
||||||
@apply scroll-m-16 leading-8;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
@apply bg-dark-ui-bg font-noto-sans text-dark-text-default;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
@apply m-0 flex h-full min-h-screen w-full scroll-m-16 flex-col items-center p-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul,
|
|
||||||
ol {
|
|
||||||
list-style: circle;
|
|
||||||
padding-left: 2.5rem;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
import "@fortawesome/fontawesome-svg-core/styles.css"
|
|
||||||
import "@fontsource/noto-sans-kr/400.css"
|
|
||||||
import "@fontsource/noto-sans-kr/700.css"
|
|
||||||
import "@fontsource/source-code-pro"
|
|
||||||
import "@developomp-site/blog/src/styles/anchor.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/blockQuote.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/button.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/callout.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/checkbox.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/code.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/colorChip.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/heading.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/hr.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/img.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/katex.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/kbd.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/list.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/mark.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/scrollbar.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/subSup.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/table.scss"
|
|
||||||
import "@developomp-site/blog/src/styles/theme-visibility.scss"
|
|
||||||
import "./global.scss"
|
|
||||||
|
|
||||||
import { type Metadata } from "next"
|
|
||||||
import Image from "next/image"
|
|
||||||
|
|
||||||
import Header from "@/components/Header"
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
metadataBase: new URL("https://portfolio.developomp.com"),
|
|
||||||
title: {
|
|
||||||
template: "pomp's portfolio | %s",
|
|
||||||
default: "",
|
|
||||||
},
|
|
||||||
description: "developomp's portfolio",
|
|
||||||
openGraph: {
|
|
||||||
title: "pomp's portfolio",
|
|
||||||
siteName: "developomp's portfolio",
|
|
||||||
description: "developomp's portfolio",
|
|
||||||
type: "website",
|
|
||||||
url: "https://portfolio.developomp.com",
|
|
||||||
images: "https://portfolio.developomp.com/favicon.svg",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<html lang="en" className="dark">
|
|
||||||
<head>
|
|
||||||
<link
|
|
||||||
rel="shortcut icon"
|
|
||||||
type="image/svg+xml"
|
|
||||||
href="/favicon.svg"
|
|
||||||
/>
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<noscript>
|
|
||||||
<figure>
|
|
||||||
<Image
|
|
||||||
src="/img/nojs.avif"
|
|
||||||
height={500}
|
|
||||||
width={544}
|
|
||||||
alt="No javascript?"
|
|
||||||
/>
|
|
||||||
<figcaption>
|
|
||||||
Image compressed down to 4.5kB because you probably
|
|
||||||
have potato internet :D
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
<Header />
|
|
||||||
<div className="mb-10 mt-20 w-full max-w-screen-md px-4">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
import { type Metadata } from "next"
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
metadataBase: new URL("https://portfolio.developomp.com"),
|
|
||||||
title: "pomp's portfolio | Page Not Found",
|
|
||||||
openGraph: {
|
|
||||||
title: "pomp's portfolio | Page Not Found",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function NotFound() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1 className="w-fit px-4 py-2 text-5xl dark:bg-dark-text-default dark:text-dark-ui-bg">
|
|
||||||
404
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<h2 className="glitch layers text-5xl">Page Not Found</h2>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
import type { ProjectKey } from "@developomp-site/content/exports/portfolio"
|
|
||||||
import portfolio from "@developomp-site/content/exports/portfolio"
|
|
||||||
import type { Metadata } from "next"
|
|
||||||
|
|
||||||
import Badge from "@/components/Badge"
|
|
||||||
import ProjectCard from "@/components/ProjectCard"
|
|
||||||
|
|
||||||
function getSkills(): JSX.Element[] {
|
|
||||||
return portfolio.skills.map((slug) => {
|
|
||||||
return <Badge key={slug} slug={slug} />
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProjects(): JSX.Element[] {
|
|
||||||
return (Object.keys(portfolio.projects) as ProjectKey[]).map(
|
|
||||||
(projectID) => (
|
|
||||||
<ProjectCard
|
|
||||||
key={projectID}
|
|
||||||
projectID={projectID}
|
|
||||||
project={portfolio.projects[projectID]}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
metadataBase: new URL("https://blog.developomp.com"),
|
|
||||||
title: "pomp's portfolio | Home",
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1 className="mb-8">developomp's Portfolio</h1>
|
|
||||||
<hr />
|
|
||||||
<div className="my-4 flex flex-wrap gap-2">{getSkills()}</div>
|
|
||||||
<div className="projects">{getProjects()}</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
import "./style.scss"
|
|
||||||
|
|
||||||
import Toc from "@developomp-site/blog/src/app/[category]/[[...slug]]/Toc"
|
|
||||||
import type { ProjectKey } from "@developomp-site/content/exports/portfolio"
|
|
||||||
import portfolio from "@developomp-site/content/exports/portfolio"
|
|
||||||
import { faGithub } from "@fortawesome/free-brands-svg-icons"
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
|
||||||
import { type Metadata } from "next"
|
|
||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import Badge from "@/components/Badge"
|
|
||||||
|
|
||||||
interface Data {
|
|
||||||
title: string
|
|
||||||
toc?: string
|
|
||||||
content: string
|
|
||||||
|
|
||||||
image: string // image url
|
|
||||||
overview: string
|
|
||||||
badges: string[]
|
|
||||||
repo: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Params {
|
|
||||||
id: ProjectKey
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
params: Params
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData(id: ProjectKey): Promise<Data> {
|
|
||||||
const content = await import(
|
|
||||||
`@developomp-site/content/dist/content/projects/${id}.json`
|
|
||||||
)
|
|
||||||
const data = portfolio.projects[id]
|
|
||||||
|
|
||||||
return {
|
|
||||||
content: content.content,
|
|
||||||
toc: content.toc,
|
|
||||||
title: data.name,
|
|
||||||
image: data.image,
|
|
||||||
overview: data.overview,
|
|
||||||
badges: data.badges,
|
|
||||||
repo: data.repo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateStaticParams(): Promise<Params[]> {
|
|
||||||
return (Object.keys(portfolio.projects) as ProjectKey[]).map((id) => ({
|
|
||||||
id,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
||||||
const data = await getData(params.id)
|
|
||||||
return {
|
|
||||||
metadataBase: new URL("https://portfolio.developomp.com"),
|
|
||||||
title: data.title,
|
|
||||||
openGraph: {
|
|
||||||
title: `pomp's portfolio | ${data.title}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function Project({ params }: Props) {
|
|
||||||
const data = await getData(params.id)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<h1 className="mb-4 text-4xl">{data.title}</h1>
|
|
||||||
<Link
|
|
||||||
href={data.repo}
|
|
||||||
className="text-dark-text-default duration-100 hover:text-gray-400"
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon className="h-12" icon={faGithub} />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
{data.badges.map((slug) => {
|
|
||||||
return <Badge key={slug} slug={slug} />
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<Toc data={data.toc} />
|
|
||||||
|
|
||||||
{/* page content */}
|
|
||||||
<div
|
|
||||||
className="project-description"
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: data.content,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
.project-description {
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
@apply mb-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
@apply mt-10 text-3xl;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
@apply mt-6 indent-2 text-xl;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
@apply mt-6 indent-4 text-base;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
@apply mt-6 indent-6 text-base;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
@apply mt-6 indent-8 text-base;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
import "./style.scss"
|
|
||||||
|
|
||||||
import { type Badge as BadgeType } from "@developomp-site/content/src/types/types"
|
|
||||||
|
|
||||||
interface BadgeProps {
|
|
||||||
slug: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function Badge({ slug }: BadgeProps) {
|
|
||||||
const badgeData: BadgeType = await import(
|
|
||||||
`@developomp-site/content/dist/icons/${slug}.json`
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!badgeData)
|
|
||||||
throw `"@developomp-site/content/dist/icons/${slug}.json" does not exist`
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{ backgroundColor: badgeData.hex }}
|
|
||||||
className={`flex w-fit items-center px-2 py-1 text-xs ${
|
|
||||||
badgeData.isDark
|
|
||||||
? "text-dark-text-default"
|
|
||||||
: "text-light-text-default"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`badge mr-1 inline-block w-6 align-middle ${
|
|
||||||
badgeData.isDark ? "dark-badge" : "light-badge"
|
|
||||||
}`}
|
|
||||||
dangerouslySetInnerHTML={{ __html: badgeData.svg }}
|
|
||||||
/>
|
|
||||||
<span>{badgeData.title}</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
import Badge from "./Badge"
|
|
||||||
|
|
||||||
export default Badge
|
|
|
@ -1,11 +0,0 @@
|
||||||
.light-badge {
|
|
||||||
svg {
|
|
||||||
@apply dark:fill-light-text-default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark-badge {
|
|
||||||
svg {
|
|
||||||
@apply dark:fill-dark-text-default;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import Link from "next/link"
|
|
||||||
import { type FC } from "react"
|
|
||||||
|
|
||||||
const Header: FC = () => {
|
|
||||||
return (
|
|
||||||
<header className="fixed top-0 z-50 flex w-screen justify-center dark:bg-dark-ui dark:text-dark-text-default">
|
|
||||||
<div className="my-0 flex h-16 w-full max-w-5xl items-center">
|
|
||||||
<Link
|
|
||||||
className="flex items-center"
|
|
||||||
href="/"
|
|
||||||
aria-label="homepage"
|
|
||||||
>
|
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
||||||
<img
|
|
||||||
className="m-4 block h-10 cursor-pointer"
|
|
||||||
src="/favicon.svg"
|
|
||||||
alt="logo"
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Header
|
|
|
@ -1,3 +0,0 @@
|
||||||
import Header from "./Header"
|
|
||||||
|
|
||||||
export default Header
|
|
|
@ -1,39 +0,0 @@
|
||||||
import "./style.scss"
|
|
||||||
|
|
||||||
import type { PortfolioProject } from "@developomp-site/content/src/types/types"
|
|
||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import Badge from "@/components/Badge"
|
|
||||||
|
|
||||||
interface ProjectCardProps {
|
|
||||||
projectID: string
|
|
||||||
project: PortfolioProject
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ProjectCard({ projectID, project }: ProjectCardProps) {
|
|
||||||
return (
|
|
||||||
<Link href={`/project/${projectID}`}>
|
|
||||||
<div className="project">
|
|
||||||
<h2 className="mb-4">{project.name}</h2>
|
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
||||||
<img
|
|
||||||
className="mb-4 w-full object-cover"
|
|
||||||
src={project.image}
|
|
||||||
alt="project thumbnail"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
{project.badges.map((badge) => (
|
|
||||||
<Badge key={badge} slug={badge} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<hr className="my-1" />
|
|
||||||
<div
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: project.overview,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
import ProjectCard from "./ProjectCard"
|
|
||||||
|
|
||||||
export default ProjectCard
|
|
|
@ -1,17 +0,0 @@
|
||||||
.project {
|
|
||||||
// general
|
|
||||||
@apply cursor-pointer rounded-md;
|
|
||||||
|
|
||||||
// spacing
|
|
||||||
@apply m-auto mb-8 p-8;
|
|
||||||
|
|
||||||
// color
|
|
||||||
@apply bg-dark-card-bg dark:text-dark-text-default;
|
|
||||||
|
|
||||||
// glow
|
|
||||||
@apply duration-75 hover:shadow-glow dark:hover:shadow-dark-text-default;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
@apply text-3xl;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
/** @type {import('tailwindcss').Config} */
|
|
||||||
module.exports = {
|
|
||||||
presets: [require("@developomp-site/tailwind-config/tailwind.config.js")],
|
|
||||||
content: [
|
|
||||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
|
||||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
||||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
||||||
],
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
|
||||||
"allowJs": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"jsx": "preserve",
|
|
||||||
"incremental": true,
|
|
||||||
"plugins": [
|
|
||||||
{
|
|
||||||
"name": "next"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"next-env.d.ts",
|
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx",
|
|
||||||
".next/types/**/*.ts",
|
|
||||||
"build/types/**/*.ts",
|
|
||||||
"dist/types/**/*.ts"
|
|
||||||
],
|
|
||||||
"exclude": ["node_modules"]
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ module.exports = {
|
||||||
// apps
|
// apps
|
||||||
"blog",
|
"blog",
|
||||||
"main",
|
"main",
|
||||||
"portfolio",
|
|
||||||
|
|
||||||
// packages
|
// packages
|
||||||
"content",
|
"content",
|
||||||
|
|
|
@ -13,13 +13,6 @@
|
||||||
"trailingSlash": false,
|
"trailingSlash": false,
|
||||||
"public": "apps/blog/build",
|
"public": "apps/blog/build",
|
||||||
"ignore": ["**/.*"]
|
"ignore": ["**/.*"]
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "portfolio",
|
|
||||||
"cleanUrls": true,
|
|
||||||
"trailingSlash": false,
|
|
||||||
"public": "apps/portfolio/dist",
|
|
||||||
"ignore": ["**/.*"]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
20
main.tf
|
@ -57,23 +57,3 @@ resource "aws_route53_record" "blog_acme_challenge" {
|
||||||
ttl = 60
|
ttl = 60
|
||||||
records = ["RXaOhzFg2U4ZtEU_Dj_2ylAX3D8xXpdRCq1KjoaB9Sc"]
|
records = ["RXaOhzFg2U4ZtEU_Dj_2ylAX3D8xXpdRCq1KjoaB9Sc"]
|
||||||
}
|
}
|
||||||
|
|
||||||
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record
|
|
||||||
resource "aws_route53_record" "portfolio" {
|
|
||||||
allow_overwrite = true
|
|
||||||
zone_id = data.aws_route53_zone.developomp_com.zone_id
|
|
||||||
name = "portfolio.${data.aws_route53_zone.developomp_com.name}"
|
|
||||||
type = "A"
|
|
||||||
ttl = 60
|
|
||||||
records = ["199.36.158.100"]
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record
|
|
||||||
resource "aws_route53_record" "portfolio_acme_challenge" {
|
|
||||||
allow_overwrite = true
|
|
||||||
zone_id = data.aws_route53_zone.developomp_com.zone_id
|
|
||||||
name = "_acme-challenge.portfolio.${data.aws_route53_zone.developomp_com.name}"
|
|
||||||
type = "TXT"
|
|
||||||
ttl = 60
|
|
||||||
records = ["YxFtDJ-Qf1yE8KX2mzf4cbfkPBR74IbbWX_0l5gGnLg"]
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import portfolio from "../dist/portfolio.json" assert { type: "json" }
|
|
||||||
import type { PortfolioProject } from "../src/types/types"
|
|
||||||
|
|
||||||
export type ProjectKey = keyof typeof portfolio.projects
|
|
||||||
|
|
||||||
// sort of like src/types/types.ts > PortfolioData but exported
|
|
||||||
export default portfolio as {
|
|
||||||
// waiting for https://github.com/microsoft/TypeScript/issues/32063
|
|
||||||
skills: string[]
|
|
||||||
|
|
||||||
projects: {
|
|
||||||
[key in ProjectKey]: PortfolioProject
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
---
|
|
||||||
name: developomp-site
|
|
||||||
overview: my websites for blogging, portfolio, resume, etc.
|
|
||||||
image: /img/portfolio/developomp-site.avif
|
|
||||||
repo: https://github.com/developomp/developomp-site
|
|
||||||
badges:
|
|
||||||
- typescript
|
|
||||||
- tailwindcss
|
|
||||||
- react
|
|
||||||
- svelte
|
|
||||||
- nextdotjs
|
|
||||||
- firebase
|
|
||||||
- terraform
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
developomp-site is a monorepo managed by [turborepo](https://turbo.build/repo)
|
|
||||||
and pnpm workspace.
|
|
||||||
|
|
||||||
- https://developomp.com - about me, built with **Svelte with SvelteKit**
|
|
||||||
- https://blog.developomp.com - Blogging site, built with **React with NextJS**
|
|
||||||
- https://portfolio.developomp.com - Portfolio, built with **React with NextJS**
|
|
||||||
|
|
||||||
## Interesting Stuff
|
|
||||||
|
|
||||||
- [markdown parsing][markdown-parsing]
|
|
||||||
- [test post](https://blog.developomp.com/posts/test-post)
|
|
||||||
|
|
||||||
[markdown-parsing]: https://github.com/developomp/developomp-site/tree/081855a4ecb6f5bf74b76758c358ea54b465b2b7/packages/blog-content
|
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
name: War Brokers Mods
|
|
||||||
overview: A game mod for a unity game. Provides in-game UI and OBS overlays.
|
|
||||||
image: /img/portfolio/wbm.avif
|
|
||||||
repo: https://github.com/War-Brokers-Mods
|
|
||||||
badges:
|
|
||||||
- rust
|
|
||||||
- csharp
|
|
||||||
- svelte
|
|
||||||
- tailwindcss
|
|
||||||
- unity
|
|
||||||
- tauri
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
The War Brokers Mods (WBM) is a mod for the game
|
|
||||||
[War Brokers](https://warbrokers.io) consisting of 3 sub-projects:
|
|
||||||
|
|
||||||
- [mod][mod] - Built with C#, it uses the [BepInEx][bepinex] framework to patch
|
|
||||||
different aspects of the game
|
|
||||||
- [OBS overlay][overlays] - Customizable overlays for [OBS studio](https://github.com/obsproject/obs-studio)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- [installer][installer] - Utility for installing updating the mod. Built with [tauri][tauri],
|
|
||||||
[rust][rust], [svelte][svelte], and [tailwind css][tailwindcss].
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[mod]: https://github.com/War-Brokers-Mods/WBM
|
|
||||||
[overlays]: https://github.com/War-Brokers-Mods/WBM-Overlays
|
|
||||||
[installer]: https://github.com/War-Brokers-Mods/WBM-installer
|
|
||||||
[bepinex]: https://github.com/BepInEx/BepInEx
|
|
||||||
[tauri]: https://github.com/tauri-apps/tauri
|
|
||||||
[rust]: https://github.com/rust-lang/rust
|
|
||||||
[svelte]: https://github.com/sveltejs/svelte
|
|
||||||
[tailwindcss]: https://github.com/tailwindlabs/tailwindcss
|
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
name: War Brokers Projects
|
|
||||||
overview: An attempt to bring together community projects related to War Brokers with the goal of making them more visible and making collaboration easier.
|
|
||||||
image: /img/portfolio/wbp.avif
|
|
||||||
repo: https://github.com/War-Brokers
|
|
||||||
badges:
|
|
||||||
- csharp
|
|
||||||
- typescript
|
|
||||||
- express
|
|
||||||
- swagger
|
|
||||||
- firebase
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
WBP (War Brokers Projects) is an attempt to bring together community projects
|
|
||||||
related to War Brokers with the goal of making them more visible and making
|
|
||||||
collaboration easier.
|
|
||||||
|
|
||||||
You can find more information in their [homepage][homepage] or in their [GitHub organization][github]
|
|
||||||
|
|
||||||
[Homepage]: https://war-brokers-projects.notion.site/War-Brokers-Projects-0ab13d7077a843e79b99a328e00d2008
|
|
||||||
[github]: https://github.com/orgs/War-Brokers/repositories
|
|
|
@ -4,5 +4,4 @@ export const outPath = "./dist" // path to the json database
|
||||||
export const contentDirectoryPath = `${outPath}/content`
|
export const contentDirectoryPath = `${outPath}/content`
|
||||||
export const iconsDirectoryPath = `${outPath}/icons`
|
export const iconsDirectoryPath = `${outPath}/icons`
|
||||||
export const mapFilePath = `${outPath}/map.json`
|
export const mapFilePath = `${outPath}/map.json`
|
||||||
export const portfolioFilePath = `${outPath}/portfolio.json`
|
|
||||||
export const searchIndexFilePath = `${outPath}/search.json`
|
export const searchIndexFilePath = `${outPath}/search.json`
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
|
|
||||||
import { mapFilePath, markdownPath, outPath, portfolioFilePath } from "./config"
|
import { mapFilePath, markdownPath, outPath } from "./config"
|
||||||
import { fillTags, parseSeries, sortDates } from "./postProcess"
|
import { fillTags, parseSeries, sortDates } from "./postProcess"
|
||||||
import { recursiveParse } from "./recursiveParse"
|
import { recursiveParse } from "./recursiveParse"
|
||||||
import { saveIndex } from "./searchIndex"
|
import { saveIndex } from "./searchIndex"
|
||||||
import type { ContentMap, PortfolioData, SeriesMap } from "./types/types"
|
import type { ContentMap, SeriesMap } from "./types/types"
|
||||||
import { ParseMode } from "./types/types"
|
import { ParseMode } from "./types/types"
|
||||||
|
|
||||||
export const contentMap: ContentMap = {
|
export const contentMap: ContentMap = {
|
||||||
|
@ -25,10 +25,6 @@ export const contentMap: ContentMap = {
|
||||||
series: {},
|
series: {},
|
||||||
}
|
}
|
||||||
export const seriesMap: SeriesMap = {}
|
export const seriesMap: SeriesMap = {}
|
||||||
export const portfolioData: PortfolioData = {
|
|
||||||
skills: new Set(),
|
|
||||||
projects: {},
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +56,6 @@ async function main() {
|
||||||
// parse markdown
|
// parse markdown
|
||||||
await recursiveParse(ParseMode.POSTS, markdownPath + "/posts")
|
await recursiveParse(ParseMode.POSTS, markdownPath + "/posts")
|
||||||
await recursiveParse(ParseMode.SERIES, markdownPath + "/series")
|
await recursiveParse(ParseMode.SERIES, markdownPath + "/series")
|
||||||
await recursiveParse(ParseMode.PORTFOLIO, markdownPath + "/projects")
|
|
||||||
|
|
||||||
sortDates()
|
sortDates()
|
||||||
fillTags()
|
fillTags()
|
||||||
|
@ -71,14 +66,6 @@ async function main() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fs.writeFileSync(mapFilePath, JSON.stringify(contentMap))
|
fs.writeFileSync(mapFilePath, JSON.stringify(contentMap))
|
||||||
fs.writeFileSync(
|
|
||||||
portfolioFilePath,
|
|
||||||
JSON.stringify({
|
|
||||||
...portfolioData,
|
|
||||||
skills: Array.from(portfolioData.skills),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
saveIndex()
|
saveIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import supersub from "remark-supersub"
|
||||||
import { unified } from "unified"
|
import { unified } from "unified"
|
||||||
|
|
||||||
import type { MarkdownData } from "./types/types"
|
import type { MarkdownData } from "./types/types"
|
||||||
import { ParseMode } from "./types/types"
|
|
||||||
import { nthIndex } from "./util"
|
import { nthIndex } from "./util"
|
||||||
|
|
||||||
const processor = unified() // interface for remark and rehype
|
const processor = unified() // interface for remark and rehype
|
||||||
|
@ -50,12 +49,10 @@ const processor = unified() // interface for remark and rehype
|
||||||
*
|
*
|
||||||
* @param {string} markdownRaw - raw unparsed text data of the markdown file
|
* @param {string} markdownRaw - raw unparsed text data of the markdown file
|
||||||
* @param {string} path - filename of the markdown file
|
* @param {string} path - filename of the markdown file
|
||||||
* @param {ParseMode} mode
|
|
||||||
*/
|
*/
|
||||||
export default async function parseMarkdown(
|
export default async function parseMarkdown(
|
||||||
markdownRaw: string,
|
markdownRaw: string,
|
||||||
path: string,
|
path: string,
|
||||||
mode: ParseMode,
|
|
||||||
): Promise<MarkdownData> {
|
): Promise<MarkdownData> {
|
||||||
const fileHasFrontMatter = markdownRaw.startsWith("---")
|
const fileHasFrontMatter = markdownRaw.startsWith("---")
|
||||||
|
|
||||||
|
@ -64,7 +61,6 @@ export default async function parseMarkdown(
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
if (fileHasFrontMatter) {
|
if (fileHasFrontMatter) {
|
||||||
if (mode != ParseMode.PORTFOLIO) {
|
|
||||||
if (!frontMatter.title)
|
if (!frontMatter.title)
|
||||||
throw Error(`Title is not defined in file: ${path}`)
|
throw Error(`Title is not defined in file: ${path}`)
|
||||||
|
|
||||||
|
@ -72,15 +68,6 @@ export default async function parseMarkdown(
|
||||||
throw Error(`Date is not defined in file: ${path}`)
|
throw Error(`Date is not defined in file: ${path}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode === ParseMode.PORTFOLIO) {
|
|
||||||
if (frontMatter.overview) {
|
|
||||||
frontMatter.overview = String(
|
|
||||||
processor.processSync(frontMatter.overview),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
frontMatter.content = touchupHTML(
|
frontMatter.content = touchupHTML(
|
||||||
String(processor.processSync(markdownRaw)),
|
String(processor.processSync(markdownRaw)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import parseMarkdown from "../parseMarkdown"
|
||||||
import { ParseMode } from "../types/types"
|
import { ParseMode } from "../types/types"
|
||||||
import { path2FileOrFolderName, path2URL } from "../util"
|
import { path2FileOrFolderName, path2URL } from "../util"
|
||||||
import parsePost from "./parsePost"
|
import parsePost from "./parsePost"
|
||||||
import parseProjects from "./parseProjects"
|
|
||||||
import parseSeries from "./parseSeries"
|
import parseSeries from "./parseSeries"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,9 +97,5 @@ async function parseFile(mode: ParseMode, path: string): Promise<void> {
|
||||||
case ParseMode.SERIES:
|
case ParseMode.SERIES:
|
||||||
await parseSeries(dataToPass)
|
await parseSeries(dataToPass)
|
||||||
break
|
break
|
||||||
|
|
||||||
case ParseMode.PORTFOLIO:
|
|
||||||
await parseProjects(dataToPass)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
import type { SimpleIcon } from "simple-icons"
|
|
||||||
import * as icons from "simple-icons"
|
|
||||||
import tinycolor from "tinycolor2"
|
|
||||||
|
|
||||||
import { portfolioData } from ".."
|
|
||||||
import { contentDirectoryPath, iconsDirectoryPath } from "../config"
|
|
||||||
import { generateToc } from "../parseMarkdown"
|
|
||||||
import { writeToFile } from "../util"
|
|
||||||
import type { DataToPass } from "."
|
|
||||||
|
|
||||||
export default async function parseProjects({
|
|
||||||
urlPath,
|
|
||||||
markdownRaw,
|
|
||||||
markdownData,
|
|
||||||
}: DataToPass): Promise<void> {
|
|
||||||
if (markdownData.badges) {
|
|
||||||
;(markdownData.badges as string[]).forEach((slug) => {
|
|
||||||
// todo: handle cases when icon is not on simple-icons
|
|
||||||
const icon: SimpleIcon =
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
icons["si" + slug[0].toUpperCase() + slug.slice(1)]
|
|
||||||
|
|
||||||
portfolioData.skills.add(slug)
|
|
||||||
|
|
||||||
const color = tinycolor(icon.hex).lighten(5).desaturate(5)
|
|
||||||
|
|
||||||
// save svg icon
|
|
||||||
writeToFile(
|
|
||||||
`${iconsDirectoryPath}/${icon.slug}.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
svg: icon.svg,
|
|
||||||
hex: color.toHexString(),
|
|
||||||
isDark: color.isDark(),
|
|
||||||
title: icon.title,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove /projects/ prefix
|
|
||||||
portfolioData.projects[urlPath.replace("/projects/", "")] = {
|
|
||||||
name: markdownData.name as string,
|
|
||||||
image: markdownData.image as string,
|
|
||||||
overview: markdownData.overview as string,
|
|
||||||
badges: (markdownData.badges as string[]) || [],
|
|
||||||
repo: (markdownData.repo as string) || "",
|
|
||||||
}
|
|
||||||
|
|
||||||
writeToFile(
|
|
||||||
`${contentDirectoryPath}${urlPath}.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
content: markdownData.content,
|
|
||||||
toc: await generateToc(markdownRaw),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -32,7 +32,6 @@ export interface ContentMap {
|
||||||
export enum ParseMode {
|
export enum ParseMode {
|
||||||
POSTS,
|
POSTS,
|
||||||
SERIES,
|
SERIES,
|
||||||
PORTFOLIO,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarkdownData {
|
export interface MarkdownData {
|
||||||
|
@ -67,13 +66,6 @@ export interface PageData {
|
||||||
|
|
||||||
order: string[]
|
order: string[]
|
||||||
length: number
|
length: number
|
||||||
|
|
||||||
// portfolio
|
|
||||||
|
|
||||||
image: string // image url
|
|
||||||
overview: string
|
|
||||||
badges: string[]
|
|
||||||
repo: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Badge {
|
export interface Badge {
|
||||||
|
@ -106,31 +98,3 @@ export interface SeriesEntry {
|
||||||
index: number
|
index: number
|
||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Portfolio
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface PortfolioData {
|
|
||||||
// a set of valid simple icons slug
|
|
||||||
skills: Set<string>
|
|
||||||
|
|
||||||
// key: url
|
|
||||||
projects: {
|
|
||||||
[key: string]: PortfolioProject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PortfolioOverview {
|
|
||||||
// link to my github
|
|
||||||
github: string
|
|
||||||
description: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PortfolioProject {
|
|
||||||
name: string
|
|
||||||
image: string // url to the image
|
|
||||||
overview: string
|
|
||||||
badges: string[] // array of valid simpleIcons slug
|
|
||||||
repo: string // url of the git repository
|
|
||||||
}
|
|
||||||
|
|
123
pnpm-lock.yaml
generated
|
@ -140,6 +140,9 @@ importers:
|
||||||
react:
|
react:
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
|
react-collapse:
|
||||||
|
specifier: ^5.1.1
|
||||||
|
version: 5.1.1(react@18.2.0)
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: 18.2.0
|
specifier: 18.2.0
|
||||||
version: 18.2.0(react@18.2.0)
|
version: 18.2.0(react@18.2.0)
|
||||||
|
@ -261,126 +264,6 @@ importers:
|
||||||
specifier: ^5.0.10
|
specifier: ^5.0.10
|
||||||
version: 5.0.10(@types/node@18.19.3)(sass@1.69.5)
|
version: 5.0.10(@types/node@18.19.3)(sass@1.69.5)
|
||||||
|
|
||||||
apps/portfolio:
|
|
||||||
devDependencies:
|
|
||||||
'@developomp-site/blog':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../blog
|
|
||||||
'@developomp-site/content':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../packages/content
|
|
||||||
'@developomp-site/eslint-config':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../packages/eslint-config
|
|
||||||
'@developomp-site/playwright-config':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../packages/playwright-config
|
|
||||||
'@developomp-site/prettier-config':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../packages/prettier-config
|
|
||||||
'@developomp-site/tailwind-config':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../packages/tailwind-config
|
|
||||||
'@fontsource/noto-sans-kr':
|
|
||||||
specifier: ^5.0.5
|
|
||||||
version: 5.0.5
|
|
||||||
'@fontsource/source-code-pro':
|
|
||||||
specifier: ^5.0.5
|
|
||||||
version: 5.0.5
|
|
||||||
'@fortawesome/free-brands-svg-icons':
|
|
||||||
specifier: ^6.4.0
|
|
||||||
version: 6.4.0
|
|
||||||
'@fortawesome/free-solid-svg-icons':
|
|
||||||
specifier: ^6.4.0
|
|
||||||
version: 6.4.0
|
|
||||||
'@fortawesome/react-fontawesome':
|
|
||||||
specifier: ^0.2.0
|
|
||||||
version: 0.2.0(@fortawesome/fontawesome-svg-core@6.5.1)(react@18.2.0)
|
|
||||||
'@kunukn/react-collapse':
|
|
||||||
specifier: ^2.2.10
|
|
||||||
version: 2.2.10(react-dom@18.2.0)(react@18.2.0)
|
|
||||||
'@playwright/test':
|
|
||||||
specifier: ^1.36.2
|
|
||||||
version: 1.36.2
|
|
||||||
'@types/highlight.js':
|
|
||||||
specifier: ^10.1.0
|
|
||||||
version: 10.1.0
|
|
||||||
'@types/katex':
|
|
||||||
specifier: ^0.16.7
|
|
||||||
version: 0.16.7
|
|
||||||
'@types/node':
|
|
||||||
specifier: ^20.10.5
|
|
||||||
version: 20.10.5
|
|
||||||
'@types/react':
|
|
||||||
specifier: 18.2.17
|
|
||||||
version: 18.2.17
|
|
||||||
'@types/react-collapse':
|
|
||||||
specifier: ^5.0.1
|
|
||||||
version: 5.0.1
|
|
||||||
'@types/react-dom':
|
|
||||||
specifier: 18.2.7
|
|
||||||
version: 18.2.7
|
|
||||||
'@typescript-eslint/eslint-plugin':
|
|
||||||
specifier: ^6.15.0
|
|
||||||
version: 6.15.0(@typescript-eslint/parser@6.15.0)(eslint@8.56.0)(typescript@5.3.3)
|
|
||||||
'@typescript-eslint/parser':
|
|
||||||
specifier: ^6.15.0
|
|
||||||
version: 6.15.0(eslint@8.56.0)(typescript@5.3.3)
|
|
||||||
autoprefixer:
|
|
||||||
specifier: ^10.4.16
|
|
||||||
version: 10.4.16(postcss@8.4.32)
|
|
||||||
eslint:
|
|
||||||
specifier: ^8.56.0
|
|
||||||
version: 8.56.0
|
|
||||||
eslint-config-next:
|
|
||||||
specifier: 13.4.12
|
|
||||||
version: 13.4.12(eslint@8.56.0)(typescript@5.3.3)
|
|
||||||
highlight.js:
|
|
||||||
specifier: ^11.8.0
|
|
||||||
version: 11.8.0
|
|
||||||
katex:
|
|
||||||
specifier: ^0.16.8
|
|
||||||
version: 0.16.8
|
|
||||||
next:
|
|
||||||
specifier: 13.4.12
|
|
||||||
version: 13.4.12(react-dom@18.2.0)(react@18.2.0)
|
|
||||||
next-sitemap:
|
|
||||||
specifier: ^4.1.8
|
|
||||||
version: 4.1.8(next@13.4.12)
|
|
||||||
open-cli:
|
|
||||||
specifier: ^7.2.0
|
|
||||||
version: 7.2.0
|
|
||||||
postcss:
|
|
||||||
specifier: ^8.4.32
|
|
||||||
version: 8.4.32
|
|
||||||
postcss-load-config:
|
|
||||||
specifier: ^4.0.1
|
|
||||||
version: 4.0.1(postcss@8.4.32)
|
|
||||||
prettier:
|
|
||||||
specifier: ^3.2.5
|
|
||||||
version: 3.2.5
|
|
||||||
prettier-plugin-tailwindcss:
|
|
||||||
specifier: ^0.5.9
|
|
||||||
version: 0.5.9(prettier-plugin-svelte@3.1.2)(prettier@3.2.5)
|
|
||||||
react:
|
|
||||||
specifier: 18.2.0
|
|
||||||
version: 18.2.0
|
|
||||||
react-collapse:
|
|
||||||
specifier: ^5.1.1
|
|
||||||
version: 5.1.1(react@18.2.0)
|
|
||||||
react-dom:
|
|
||||||
specifier: 18.2.0
|
|
||||||
version: 18.2.0(react@18.2.0)
|
|
||||||
serve:
|
|
||||||
specifier: ^14.2.0
|
|
||||||
version: 14.2.0
|
|
||||||
tailwindcss:
|
|
||||||
specifier: ^3.4.0
|
|
||||||
version: 3.4.0
|
|
||||||
typescript:
|
|
||||||
specifier: ^5.3.3
|
|
||||||
version: 5.3.3
|
|
||||||
|
|
||||||
packages/content:
|
packages/content:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@developomp-site/eslint-config':
|
'@developomp-site/eslint-config':
|
||||||
|
|