diff options
| author | Kevin Hoerr <kjhoerr@protonmail.com> | 2022-11-21 18:19:16 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-21 18:19:16 -0500 |
| commit | 651f019141b488a82fd42028bce5b0003abbfaf5 (patch) | |
| tree | 5be06913d021752cb0a1d3f809f66b27359619c5 /src | |
| parent | 6ec00afac5afc892dca5a184b66467d9408f14a5 (diff) | |
| download | submelon.dev-651f019141b488a82fd42028bce5b0003abbfaf5.tar.gz submelon.dev-651f019141b488a82fd42028bce5b0003abbfaf5.tar.bz2 submelon.dev-651f019141b488a82fd42028bce5b0003abbfaf5.zip | |
Layout changes (#15)
* Layout refactor and standardization
* Use split to condense short array
* Fix verbage
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/Footer.tsx | 103 | ||||
| -rw-r--r-- | src/components/Layout.tsx | 30 | ||||
| -rw-r--r-- | src/components/index.ts | 4 | ||||
| -rw-r--r-- | src/pages/404.tsx | 35 | ||||
| -rw-r--r-- | src/pages/index.tsx | 113 | ||||
| -rw-r--r-- | src/util/timestamp.ts | 48 |
6 files changed, 147 insertions, 186 deletions
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx deleted file mode 100644 index 3e6932b..0000000 --- a/src/components/Footer.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React from "react"; -import { Footer } from "../styles"; - -const SHORT_CHARS = [ - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", -]; - -function toShort(valu: number): string { - return ( - valu - .toString() - .match(/.{1,2}/g) - ?.map((s) => SHORT_CHARS[parseInt(s)]) - .join("") ?? "" - ); -} - -function getTimestamp(seconds: number): string { - const date = new Date(seconds * 1000); - const dateArr = [ - date.getUTCFullYear(), - date.getUTCMonth(), - date.getUTCDate(), - date.getUTCHours(), - date.getUTCMinutes(), - ]; - - return dateArr.map(toShort).join(".") + "-0"; -} - -const FooterInfo = ({ timestamp }) => { - return ( - <Footer> - <span> - ©2022 kjhoerr@https://submelon.dev/: - {getTimestamp(parseInt(timestamp))} - </span> - </Footer> - ); -}; - -export default FooterInfo; diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx new file mode 100644 index 0000000..6cc70ed --- /dev/null +++ b/src/components/Layout.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { IconContext } from "react-icons/lib"; +import { Content, Footer } from "../styles"; +import package_json from "../../package.json"; +import { getTimestamp } from "../util/timestamp"; + +const VERSION = package_json.version; + +const Layout = ({ children }) => { + return ( + <React.StrictMode> + <main> + <IconContext.Provider + value={{ size: "20", style: { marginBottom: "-4px" } }} + > + <Content>{children}</Content> + + <Footer> + <span> + ©2022 kjhoerr@https://submelon.dev/: + {getTimestamp(Number(VERSION))} + </span> + </Footer> + </IconContext.Provider> + </main> + </React.StrictMode> + ); +}; + +export default Layout; diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..6e7bcb7 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,4 @@ +import BlockLink from "./BlockLink"; +import Layout from "./Layout"; + +export { BlockLink, Layout }; diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 0a593d6..d8d27cb 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,26 +1,23 @@ -import * as React from "react"; -import BlockLink from "../components/BlockLink"; -import { BlockBody, BlockHeader, Content } from "../styles"; +import React from "react"; +import { BlockLink, Layout } from "../components"; +import { BlockBody, BlockHeader } from "../styles"; import "../styles/main.css"; -// markup const NotFoundPage = (): React.ReactElement => { return ( - <main> - <Content> - <BlockHeader>Not found</BlockHeader> - <BlockBody> - Sorry{" "} - <span role="img" aria-label="Pensive emoji"> - 😔 - </span>{" "} - we couldn't find what you were looking for. - </BlockBody> - <BlockLink href="/" aria-label="Return to the front page"> - Home - </BlockLink> - </Content> - </main> + <Layout> + <BlockHeader>Not found</BlockHeader> + <BlockBody> + Sorry{" "} + <span role="img" aria-label="Pensive emoji"> + 😔 + </span>{" "} + we couldn't find what you were looking for. + </BlockBody> + <BlockLink href="/" aria-label="Return to the front page"> + Home + </BlockLink> + </Layout> ); }; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index e4b4ec6..370a10d 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,74 +2,59 @@ import React from "react"; import { StaticImage } from "gatsby-plugin-image"; import "../styles/main.css"; import { FaGithub, FaMastodon } from "react-icons/fa"; -import BlockLink from "../components/BlockLink"; -import Footer from "../components/Footer"; -import { BlockBody, BlockHeader, Content } from "../styles"; -import package_json from "../../package.json"; -import { IconContext } from "react-icons"; +import { BlockLink, Layout } from "../components"; +import { BlockBody, BlockHeader } from "../styles"; -const VERSION = package_json.version; - -// markup const IndexPage = (): React.ReactElement => { return ( - <main> - <IconContext.Provider - value={{ size: "20", style: { marginBottom: "-4px" } }} + <Layout> + <div> + <StaticImage + src="../images/main.png" + alt="Picture of Kevin Hoerr" + placeholder="tracedSVG" + layout="fixed" + width={350} + height={350} + /> + </div> + <BlockHeader>Hello!</BlockHeader> + <BlockBody> + <p> + I'm a computer science and math graduate from Millersville + University. I work as an IT consultant and specialize in development + operations and systems validation for web applications. + </p> + <p> + My most recent projects have been focused on full-stack development. I + use Kubernetes for orchestration and NextJS for the front-end. For + back-end development, I have built services enabled by Java with + Spring Boot, Quarkus, and rust+actix-web with a GraphQL serving public + API. + </p> + <p> + I run a personal Kubernetes cluster at home using MicroOS and k3d. I + have also run multiple clusters via DigitalOcean with deployments + dedicated for hosting git projects, CI/CD, and code coverage. Since + then all projects have been moved to GitHub. + </p> + <em>- Kevin H.</em> + </BlockBody> + <BlockLink + href="https://cybr.es/@kjhoerr" + rel="me" + aria-label="My Mastodon account" > - <Content> - <div> - <StaticImage - src="../images/main.png" - alt="Picture of Kevin Hoerr" - placeholder="tracedSVG" - layout="fixed" - width={350} - height={350} - /> - </div> - <BlockHeader>Hello!</BlockHeader> - <BlockBody> - <p> - I'm a computer science and math graduate from Millersville - University. I work as an IT consultant and specialize in - development operations and systems validation for web - applications. - </p> - <p> - My most recent projects have been focused on full-stack - development. I use Kubernetes for orchestration and NextJS for the - front-end. For back-end development, I have built services enabled - by Java with Spring Boot, Quarkus, and rust+actix-web with a - GraphQL serving public API. - </p> - <p> - I run a personal Kubernetes cluster at home using MicroOS and k3d. - I have also run multiple clusters via DigitalOcean with - deployments dedicated for hosting git projects, CI/CD, and code - coverage. Since then all projects have been moved to GitHub. - </p> - <em>- Kevin H.</em> - </BlockBody> - <BlockLink - href="https://cybr.es/@kjhoerr" - rel="me" - aria-label="My Mastodon account" - > - <FaMastodon /> @kjhoerr@cybr.es - </BlockLink> - <BlockLink - href="https://github.com/kjhoerr" - rel="me" - aria-label="My GitHub account with my most active personal projects" - > - <FaGithub /> kjhoerr on GitHub - </BlockLink> - </Content> - - <Footer timestamp={VERSION} /> - </IconContext.Provider> - </main> + <FaMastodon /> @kjhoerr@cybr.es + </BlockLink> + <BlockLink + href="https://github.com/kjhoerr" + rel="me" + aria-label="My GitHub account with my most active personal projects" + > + <FaGithub /> kjhoerr on GitHub + </BlockLink> + </Layout> ); }; diff --git a/src/util/timestamp.ts b/src/util/timestamp.ts new file mode 100644 index 0000000..f53f5ad --- /dev/null +++ b/src/util/timestamp.ts @@ -0,0 +1,48 @@ +const SHORT_CHARS = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + +/** + * Transforms a number into a custom 62 char expression of that number, + * effectively making a "short" version of that number (0-9a-zA-Z). This does + * NOT convert to a base-62 number. + * + * There are vast gaps in the effective translation of numbers, which is why + * this function is mostly for concisely translating dates prior to the year + * 2063. Since all other values associated with dates (month, day, hours, + * minutes, seconds) effectively fall within the range of a single character, + * this is an accepted shortcoming. + * + * Examples: + * + * 0 = 0 + * + * 48 = M + * + * 2022 = km (in base-62 this would be wC) + */ +export function toShort(valu: number): string { + return ( + valu + .toString() + .match(/.{1,2}/g) + ?.map((s) => SHORT_CHARS[parseInt(s)]) + .join("") ?? "" + ); +} + +/** + * Translates a Unix EPOCH timestamp to a 62-char expression of the date. See + * the `toShort()` method for more details on the meaning of the final output. + */ +export function getTimestamp(seconds: number): string { + const date = new Date(seconds * 1000); + const dateArr = [ + date.getUTCFullYear(), + date.getUTCMonth(), + date.getUTCDate(), + date.getUTCHours(), + date.getUTCMinutes(), + ]; + + return dateArr.map(toShort).join(".") + "-0"; +} |
