added basic portfolio page
This commit is contained in:
parent
fc51c78f1e
commit
dcbfe24de0
13 changed files with 230 additions and 9 deletions
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -5,14 +5,15 @@
|
|||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": false,
|
||||
"cSpell.words": [
|
||||
"Fontawesome",
|
||||
"YYYYMMDD",
|
||||
"developomp",
|
||||
"developomp's",
|
||||
"dompurify",
|
||||
"elasticlunr",
|
||||
"Fontawesome",
|
||||
"hljs",
|
||||
"katex",
|
||||
"texmath"
|
||||
"texmath",
|
||||
"tinycolor",
|
||||
"YYYYMMDD"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import fs from "fs"
|
||||
import simpleIcons from "simple-icons" // badge icons
|
||||
import readTimeEstimate from "read-time-estimate" // post read time estimation
|
||||
import tinycolor from "tinycolor2" // color manipulation
|
||||
|
||||
import { path2FileOrFolderName, path2URL, writeToFile } from "./util"
|
||||
import { generateToc, parseFrontMatter } from "./parseMarkdown"
|
||||
|
@ -354,12 +355,15 @@ function parsePortfolio(data: DataToPass): void {
|
|||
;(markdownData.badges as string[]).forEach((slug) => {
|
||||
const icon = simpleIcons.Get(slug)
|
||||
|
||||
const color = tinycolor(icon.hex).lighten(5).desaturate(5)
|
||||
|
||||
// save svg icon
|
||||
writeToFile(
|
||||
`${iconsDirectoryPath}/${icon.slug}.json`,
|
||||
JSON.stringify({
|
||||
svg: icon.svg,
|
||||
hex: icon.hex,
|
||||
hex: color.toHexString(),
|
||||
isDark: color.isDark(),
|
||||
title: icon.title,
|
||||
})
|
||||
)
|
||||
|
|
|
@ -2,6 +2,4 @@
|
|||
github: https://github.com/developomp
|
||||
---
|
||||
|
||||
## Skills
|
||||
|
||||
## Education
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: Mocha Downloader
|
||||
overview: A cross-platform desktop download manager built with web technologies.
|
||||
image: /img/icon.png
|
||||
image: /img/portfolio/mocha-downloader.png
|
||||
repo: https://github.com/Mocha-Downloader
|
||||
badges:
|
||||
- typescript
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: War Brokers Mods
|
||||
overview: A game mod for a unity game. Provides in-game UI and OBS overlays.
|
||||
image: /img/icon.png
|
||||
image: /img/portfolio/wbm.png
|
||||
repo: https://github.com/War-Brokers-Mods
|
||||
badges:
|
||||
- csharp
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
"@types/react-router-hash-link": "^2.4.4",
|
||||
"@types/react-select": "^5.0.1",
|
||||
"@types/styled-components": "^5.1.19",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.9.0",
|
||||
"@typescript-eslint/parser": "^5.9.0",
|
||||
"canvas": "^2.8.0",
|
||||
|
@ -68,6 +69,7 @@
|
|||
"prettier": "^2.5.1",
|
||||
"read-time-estimate": "^0.0.3",
|
||||
"simple-icons": "^6.5.0",
|
||||
"tinycolor2": "^1.4.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typescript": "^4.5.4"
|
||||
|
|
BIN
source/public/img/portfolio/mocha-downloader.png
Executable file
BIN
source/public/img/portfolio/mocha-downloader.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
source/public/img/portfolio/wbm.png
Normal file
BIN
source/public/img/portfolio/wbm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 759 KiB |
|
@ -15,6 +15,7 @@ import PostList from "./pages/PostList"
|
|||
import Search from "./pages/Search"
|
||||
import Page from "./pages/Page"
|
||||
import NotFound from "./pages/NotFound"
|
||||
import Portfolio from "./pages/Portfolio"
|
||||
|
||||
import theming from "./styles/theming"
|
||||
import GlobalStyle from "./styles/globalStyle"
|
||||
|
@ -94,9 +95,10 @@ const App = () => {
|
|||
path="/"
|
||||
element={<PostList howMany={5} title="Home" />}
|
||||
/>
|
||||
<Route path="/loading" element={<Loading />} />
|
||||
<Route path="/search" element={<Search />} />
|
||||
<Route path="/portfolio" element={<Portfolio />} />
|
||||
<Route path="/404" element={<NotFound />} />
|
||||
<Route path="/loading" element={<Loading />} />
|
||||
<Route path="/*" element={<Page />} />
|
||||
</Routes>
|
||||
)}
|
||||
|
|
73
source/src/components/Badge.tsx
Normal file
73
source/src/components/Badge.tsx
Normal file
|
@ -0,0 +1,73 @@
|
|||
import { useEffect, useState } from "react"
|
||||
import styled from "styled-components"
|
||||
|
||||
import theming from "../styles/theming"
|
||||
|
||||
const StyledBadge = styled.div<{ color: string; isDark: boolean }>`
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
||||
padding: 0.2rem 0.4rem 0 0.4rem;
|
||||
margin-right: 0.4rem;
|
||||
|
||||
font-size: 0.8rem;
|
||||
|
||||
background-color: ${(props) => props.color};
|
||||
color: ${(props) =>
|
||||
props.isDark ? theming.dark.color1 : theming.light.color1};
|
||||
`
|
||||
|
||||
const StyledSVG = styled.div<{ isDark: boolean }>`
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
margin-right: 0.2rem;
|
||||
|
||||
svg {
|
||||
height: 16px;
|
||||
fill: ${(props) =>
|
||||
props.isDark
|
||||
? theming.dark.color1
|
||||
: theming.light.color1} !important;
|
||||
}
|
||||
`
|
||||
|
||||
interface Badge {
|
||||
svg: string
|
||||
hex: string
|
||||
isDark: boolean
|
||||
title: string
|
||||
}
|
||||
|
||||
interface BadgeProps {
|
||||
slug: string
|
||||
}
|
||||
|
||||
const Badge = (props: BadgeProps) => {
|
||||
const [badgeData, setBadgeData] = useState<Badge | undefined>(undefined)
|
||||
const { slug } = props
|
||||
|
||||
const getBadgeData = async () => {
|
||||
return await require(`../data/icons/${slug}.json`)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getBadgeData().then((data) => {
|
||||
setBadgeData(data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (!badgeData) return <></>
|
||||
|
||||
return (
|
||||
<StyledBadge color={badgeData.hex} isDark={badgeData.isDark}>
|
||||
<StyledSVG
|
||||
isDark={badgeData.isDark}
|
||||
dangerouslySetInnerHTML={{ __html: badgeData.svg }}
|
||||
/>
|
||||
<span>{badgeData.title}</span>
|
||||
</StyledBadge>
|
||||
)
|
||||
}
|
||||
|
||||
export default Badge
|
67
source/src/pages/Portfolio/ProjectCard.tsx
Normal file
67
source/src/pages/Portfolio/ProjectCard.tsx
Normal file
|
@ -0,0 +1,67 @@
|
|||
import styled from "styled-components"
|
||||
import { faGithub } from "@fortawesome/free-brands-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
|
||||
import MainContent from "../../components/MainContent"
|
||||
import Badge from "../../components/Badge"
|
||||
|
||||
import { PortfolioProject } from "../../../types/types"
|
||||
import theming from "../../styles/theming"
|
||||
|
||||
const StyledProjectCard = styled(MainContent)`
|
||||
margin-bottom: 2rem;
|
||||
`
|
||||
|
||||
const StyledImg = styled.img`
|
||||
width: 100%;
|
||||
|
||||
object-fit: cover;
|
||||
margin-bottom: 1rem;
|
||||
`
|
||||
|
||||
const StyledGithubLink = styled.a`
|
||||
display: flex;
|
||||
float: right;
|
||||
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
margin-top: 1.5rem;
|
||||
|
||||
color: ${(props) =>
|
||||
theming.theme(props.theme.currentTheme, {
|
||||
light: theming.light.color1,
|
||||
dark: theming.dark.color1,
|
||||
})};
|
||||
|
||||
svg {
|
||||
font-size: 2rem;
|
||||
}
|
||||
`
|
||||
|
||||
interface ProjectCardProps {
|
||||
project: PortfolioProject
|
||||
}
|
||||
|
||||
const ProjectCard = (props: ProjectCardProps) => {
|
||||
const { project } = props
|
||||
|
||||
return (
|
||||
<StyledProjectCard>
|
||||
<StyledGithubLink href={project.repo}>
|
||||
<FontAwesomeIcon icon={faGithub} />
|
||||
Github
|
||||
</StyledGithubLink>
|
||||
<h1>{project.name}</h1>
|
||||
<StyledImg src={project.image} />
|
||||
|
||||
{project.badges.map((badge) => {
|
||||
return <Badge key={badge} slug={badge} />
|
||||
})}
|
||||
<hr />
|
||||
<div dangerouslySetInnerHTML={{ __html: project.overview }} />
|
||||
</StyledProjectCard>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProjectCard
|
64
source/src/pages/Portfolio/index.tsx
Normal file
64
source/src/pages/Portfolio/index.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
import { useEffect, useState } from "react"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
|
||||
import MainContent from "../../components/MainContent"
|
||||
import ProjectCard from "./ProjectCard"
|
||||
|
||||
import portfolio from "../../data/portfolio.json"
|
||||
|
||||
import { PortfolioProject } from "../../../types/types"
|
||||
|
||||
const Portfolio = () => {
|
||||
const [projects, setProjects] = useState<JSX.Element[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const _projects: JSX.Element[] = []
|
||||
|
||||
for (const projectID in portfolio.projects) {
|
||||
_projects.push(
|
||||
<ProjectCard
|
||||
key={projectID}
|
||||
project={
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
portfolio.projects[projectID] as PortfolioProject
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
setProjects(_projects)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>pomp | Portfolio</title>
|
||||
|
||||
<meta property="og:title" content="Portfolio" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="http://developomp.com" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content="http://developomp.com/icon/icon.svg"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content="developomp's Portfolio"
|
||||
/>
|
||||
</Helmet>
|
||||
|
||||
<MainContent>
|
||||
<h1>Portfolio</h1>
|
||||
<hr />
|
||||
<div dangerouslySetInnerHTML={{ __html: portfolio.overview }} />
|
||||
</MainContent>
|
||||
|
||||
<br />
|
||||
|
||||
{projects}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Portfolio
|
|
@ -2077,6 +2077,11 @@
|
|||
"@types/react" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/tinycolor2@^1.4.3":
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.3.tgz#ed4a0901f954b126e6a914b4839c77462d56e706"
|
||||
integrity sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ==
|
||||
|
||||
"@types/tough-cookie@*":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40"
|
||||
|
@ -9161,6 +9166,11 @@ timsort@^0.3.0:
|
|||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||
|
||||
tinycolor2@^1.4.2:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
||||
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
|
||||
|
||||
tmpl@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue