diff --git a/.vscode/settings.json b/.vscode/settings.json index cedd8b7..0de0a25 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" ] } diff --git a/source/generate/recursiveParse.ts b/source/generate/recursiveParse.ts index 1ce1656..bcee91a 100644 --- a/source/generate/recursiveParse.ts +++ b/source/generate/recursiveParse.ts @@ -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, }) ) diff --git a/source/markdown/portfolio/0.md b/source/markdown/portfolio/0.md index 6def304..a0863ed 100644 --- a/source/markdown/portfolio/0.md +++ b/source/markdown/portfolio/0.md @@ -2,6 +2,4 @@ github: https://github.com/developomp --- -## Skills - ## Education diff --git a/source/markdown/portfolio/mocha downloader.md b/source/markdown/portfolio/mocha downloader.md index f4df632..3a2e8e6 100644 --- a/source/markdown/portfolio/mocha downloader.md +++ b/source/markdown/portfolio/mocha downloader.md @@ -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 diff --git a/source/markdown/portfolio/wbm.md b/source/markdown/portfolio/wbm.md index ff364cd..97a3674 100644 --- a/source/markdown/portfolio/wbm.md +++ b/source/markdown/portfolio/wbm.md @@ -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 diff --git a/source/package.json b/source/package.json index fb20a3d..f2e2bdb 100644 --- a/source/package.json +++ b/source/package.json @@ -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" diff --git a/source/public/img/portfolio/mocha-downloader.png b/source/public/img/portfolio/mocha-downloader.png new file mode 100755 index 0000000..0a23088 Binary files /dev/null and b/source/public/img/portfolio/mocha-downloader.png differ diff --git a/source/public/img/portfolio/wbm.png b/source/public/img/portfolio/wbm.png new file mode 100644 index 0000000..043f25d Binary files /dev/null and b/source/public/img/portfolio/wbm.png differ diff --git a/source/src/App.tsx b/source/src/App.tsx index de98e46..977f14a 100644 --- a/source/src/App.tsx +++ b/source/src/App.tsx @@ -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={} /> - } /> } /> + } /> } /> + } /> } /> )} diff --git a/source/src/components/Badge.tsx b/source/src/components/Badge.tsx new file mode 100644 index 0000000..28d37ba --- /dev/null +++ b/source/src/components/Badge.tsx @@ -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(undefined) + const { slug } = props + + const getBadgeData = async () => { + return await require(`../data/icons/${slug}.json`) + } + + useEffect(() => { + getBadgeData().then((data) => { + setBadgeData(data) + }) + }, []) + + if (!badgeData) return <> + + return ( + + + {badgeData.title} + + ) +} + +export default Badge diff --git a/source/src/pages/Portfolio/ProjectCard.tsx b/source/src/pages/Portfolio/ProjectCard.tsx new file mode 100644 index 0000000..4d51521 --- /dev/null +++ b/source/src/pages/Portfolio/ProjectCard.tsx @@ -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 ( + + + + Github + +

{project.name}

+ + + {project.badges.map((badge) => { + return + })} +
+
+ + ) +} + +export default ProjectCard diff --git a/source/src/pages/Portfolio/index.tsx b/source/src/pages/Portfolio/index.tsx new file mode 100644 index 0000000..7069cd8 --- /dev/null +++ b/source/src/pages/Portfolio/index.tsx @@ -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([]) + + useEffect(() => { + const _projects: JSX.Element[] = [] + + for (const projectID in portfolio.projects) { + _projects.push( + + ) + } + + setProjects(_projects) + }, []) + + return ( + <> + + pomp | Portfolio + + + + + + + + + +

Portfolio

+
+
+ + +
+ + {projects} + + ) +} + +export default Portfolio diff --git a/source/yarn.lock b/source/yarn.lock index 332ee0d..19f1a4a 100644 --- a/source/yarn.lock +++ b/source/yarn.lock @@ -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"