refactor: remove portfolio
|
@ -12,7 +12,6 @@
|
|||
- `apps`
|
||||
- `main` - https://developomp.com
|
||||
- `blog` - https://blog.developomp.com
|
||||
- `portfolio` - https://portfolio.developomp.com
|
||||
- `packages` - shared stuff used across different packages
|
||||
- `content` - Shared content
|
||||
- `eslint-config` - ESLint configuration files
|
||||
|
@ -46,7 +45,6 @@
|
|||
- `pnpm dev` - Run all apps and packages locally
|
||||
- blog - http://localhost:3000
|
||||
- main - http://localhost:5173
|
||||
- portfolio - http://localhost:5174
|
||||
- `pnpm lint` - Lint all apps and packages
|
||||
- `pnpm clean` - Remove all auto-generated content such as `node_modules` and `dist`.
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
"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",
|
||||
|
|
|
@ -75,13 +75,6 @@ export function parsePageData(
|
|||
|
||||
order: [],
|
||||
length: 0,
|
||||
|
||||
// portfolio (unused)
|
||||
|
||||
image: "",
|
||||
overview: "",
|
||||
badges: [],
|
||||
repo: "",
|
||||
}
|
||||
|
||||
// load and parse content differently depending on the content type
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -8,7 +8,7 @@
|
|||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
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>
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
|||
<meta property="og:site_name" content="developomp" />
|
||||
<meta
|
||||
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: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>
|
||||
import "./app.css"
|
||||
|
||||
import Navbar from "$/components/Navbar.svelte"
|
||||
</script>
|
||||
|
||||
<Navbar />
|
||||
<main
|
||||
class="mx-auto my-0 flex w-full max-w-5xl flex-col items-center px-8 py-0 text-center font-normal"
|
||||
>
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://developomp.com</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://blog.developomp.com</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://portfolio.developomp.com</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://developomp.com/resume</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>0.4</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://developomp.com</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://blog.developomp.com</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://developomp.com/resume</loc>
|
||||
<changefreq>always</changefreq>
|
||||
<priority>0.4</priority>
|
||||
</url>
|
||||
</urlset>
|
|
@ -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
|
||||
"blog",
|
||||
"main",
|
||||
"portfolio",
|
||||
|
||||
// packages
|
||||
"content",
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
"trailingSlash": false,
|
||||
"public": "apps/blog/build",
|
||||
"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
|
||||
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 iconsDirectoryPath = `${outPath}/icons`
|
||||
export const mapFilePath = `${outPath}/map.json`
|
||||
export const portfolioFilePath = `${outPath}/portfolio.json`
|
||||
export const searchIndexFilePath = `${outPath}/search.json`
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
import fs from "fs"
|
||||
|
||||
import { mapFilePath, markdownPath, outPath, portfolioFilePath } from "./config"
|
||||
import { mapFilePath, markdownPath, outPath } from "./config"
|
||||
import { fillTags, parseSeries, sortDates } from "./postProcess"
|
||||
import { recursiveParse } from "./recursiveParse"
|
||||
import { saveIndex } from "./searchIndex"
|
||||
import type { ContentMap, PortfolioData, SeriesMap } from "./types/types"
|
||||
import type { ContentMap, SeriesMap } from "./types/types"
|
||||
import { ParseMode } from "./types/types"
|
||||
|
||||
export const contentMap: ContentMap = {
|
||||
|
@ -25,10 +25,6 @@ export const contentMap: ContentMap = {
|
|||
series: {},
|
||||
}
|
||||
export const seriesMap: SeriesMap = {}
|
||||
export const portfolioData: PortfolioData = {
|
||||
skills: new Set(),
|
||||
projects: {},
|
||||
}
|
||||
|
||||
async function main() {
|
||||
/**
|
||||
|
@ -60,7 +56,6 @@ async function main() {
|
|||
// parse markdown
|
||||
await recursiveParse(ParseMode.POSTS, markdownPath + "/posts")
|
||||
await recursiveParse(ParseMode.SERIES, markdownPath + "/series")
|
||||
await recursiveParse(ParseMode.PORTFOLIO, markdownPath + "/projects")
|
||||
|
||||
sortDates()
|
||||
fillTags()
|
||||
|
@ -71,14 +66,6 @@ async function main() {
|
|||
*/
|
||||
|
||||
fs.writeFileSync(mapFilePath, JSON.stringify(contentMap))
|
||||
fs.writeFileSync(
|
||||
portfolioFilePath,
|
||||
JSON.stringify({
|
||||
...portfolioData,
|
||||
skills: Array.from(portfolioData.skills),
|
||||
}),
|
||||
)
|
||||
|
||||
saveIndex()
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import supersub from "remark-supersub"
|
|||
import { unified } from "unified"
|
||||
|
||||
import type { MarkdownData } from "./types/types"
|
||||
import { ParseMode } from "./types/types"
|
||||
import { nthIndex } from "./util"
|
||||
|
||||
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} path - filename of the markdown file
|
||||
* @param {ParseMode} mode
|
||||
*/
|
||||
export default async function parseMarkdown(
|
||||
markdownRaw: string,
|
||||
path: string,
|
||||
mode: ParseMode,
|
||||
): Promise<MarkdownData> {
|
||||
const fileHasFrontMatter = markdownRaw.startsWith("---")
|
||||
|
||||
|
@ -64,21 +61,11 @@ export default async function parseMarkdown(
|
|||
: {}
|
||||
|
||||
if (fileHasFrontMatter) {
|
||||
if (mode != ParseMode.PORTFOLIO) {
|
||||
if (!frontMatter.title)
|
||||
throw Error(`Title is not defined in file: ${path}`)
|
||||
if (!frontMatter.title)
|
||||
throw Error(`Title is not defined in file: ${path}`)
|
||||
|
||||
if (!frontMatter.date)
|
||||
throw Error(`Date is not defined in file: ${path}`)
|
||||
}
|
||||
|
||||
if (mode === ParseMode.PORTFOLIO) {
|
||||
if (frontMatter.overview) {
|
||||
frontMatter.overview = String(
|
||||
processor.processSync(frontMatter.overview),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!frontMatter.date)
|
||||
throw Error(`Date is not defined in file: ${path}`)
|
||||
}
|
||||
|
||||
frontMatter.content = touchupHTML(
|
||||
|
|
|
@ -5,7 +5,6 @@ import parseMarkdown from "../parseMarkdown"
|
|||
import { ParseMode } from "../types/types"
|
||||
import { path2FileOrFolderName, path2URL } from "../util"
|
||||
import parsePost from "./parsePost"
|
||||
import parseProjects from "./parseProjects"
|
||||
import parseSeries from "./parseSeries"
|
||||
|
||||
/**
|
||||
|
@ -98,9 +97,5 @@ async function parseFile(mode: ParseMode, path: string): Promise<void> {
|
|||
case ParseMode.SERIES:
|
||||
await parseSeries(dataToPass)
|
||||
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 {
|
||||
POSTS,
|
||||
SERIES,
|
||||
PORTFOLIO,
|
||||
}
|
||||
|
||||
export interface MarkdownData {
|
||||
|
@ -67,13 +66,6 @@ export interface PageData {
|
|||
|
||||
order: string[]
|
||||
length: number
|
||||
|
||||
// portfolio
|
||||
|
||||
image: string // image url
|
||||
overview: string
|
||||
badges: string[]
|
||||
repo: string
|
||||
}
|
||||
|
||||
export interface Badge {
|
||||
|
@ -106,31 +98,3 @@ export interface SeriesEntry {
|
|||
index: number
|
||||
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:
|
||||
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)
|
||||
|
@ -261,126 +264,6 @@ importers:
|
|||
specifier: ^5.0.10
|
||||
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:
|
||||
dependencies:
|
||||
'@developomp-site/eslint-config':
|
||||
|
|