Added this website as content to hobbies, refactored some items into site-layout
All checks were successful
Build and Test - Staging / test (pull_request) Successful in 5m6s
Build and Test - Staging / build_and_push (pull_request) Successful in 5m14s
Build and Test - Staging / deploy_staging (pull_request) Successful in 3s

This commit is contained in:
2025-12-10 16:59:54 -08:00
parent 25c08f7a1d
commit 649b596c7c
9 changed files with 171 additions and 29 deletions

View File

@@ -16,6 +16,7 @@ Dechorionator
ebox
fhhs
flowbite
Gitea
HDFS
headshot
Homelab

View File

@@ -1,10 +1,23 @@
---
import InlineLink from "@components/InlineLink.astro";
const { pathname } = Astro.url;
---
<footer
class="border-t-caperren-green-dark text-caperren-green-dark z-50 flex w-full max-w-full items-center justify-between border-t bg-black px-6 py-2 text-sm"
>
<span>{import.meta.env.PUBLIC_BUILD_ENVIRONMENT || "development"}</span>
<div>
<InlineLink
class:list={[
"text-caperren-green-dark hover:text-caperren-green",
pathname === "/hobby/this-website"
? "border-caperren-green-dark hover:border-caperren-green border-b-2"
: false,
]}
href="/hobby/this-website">About This Website</InlineLink
>
</div>
<span>{import.meta.env.PUBLIC_REPO_VERSION_HASH || "invalid"}</span>
</footer>

View File

@@ -7,16 +7,10 @@ interface Props extends ComponentPropsBase {
}
const { class: className, href, target } = Astro.props;
const { pathname } = Astro.url;
let finalTarget: string | undefined = target;
if (target === undefined) {
if (href.startsWith("/")) {
finalTarget = "";
} else {
finalTarget = "_blank";
}
}
const finalTarget =
target === undefined ? (href.startsWith("/") ? undefined : "_blank") : target;
---
<>
@@ -24,6 +18,7 @@ if (target === undefined) {
class:list={["text-blue-500", "hover:text-blue-300", className]}
href={href}
target={finalTarget}
aria-current={pathname === href ? "page" : undefined}
>
<slot />
</a>

View File

@@ -1,20 +1,12 @@
---
import type { navLink } from "@interfaces/site-layout.ts";
import { getHrefPath, getNavLinkSuffix } from "@data/site-layout.ts";
const items: navLink[] = Astro.props.items;
const depth: number = Astro.props.depth ?? 0;
const paths: string[] = Astro.props.paths ?? [];
const getNavLinkSuffix = (entry: navLink): string => {
return "-" + [...paths, entry.path].join("-");
};
const getHrefPath = (entry: navLink): string => {
return entry.pubpath
? entry.pubpath
: "/" +
(paths && paths.length ? [...paths, entry.path].join("/") : entry.path);
};
const { pathname } = Astro.url;
---
@@ -29,21 +21,22 @@ const { pathname } = Astro.url;
{
items.map(
(entry) =>
(entry.enabled ?? true) && (
(entry.enabled ?? true) &&
!(entry.hidden ?? false) && (
<li class="">
{Array.isArray(entry.children) && entry.children.length ? (
<div>
<button
id={"dropdownNavbarLink" + getNavLinkSuffix(entry)}
id={"dropdownNavbarLink" + getNavLinkSuffix(paths, entry)}
data-dropdown-toggle={
"dropdownNavbar" + getNavLinkSuffix(entry)
"dropdownNavbar" + getNavLinkSuffix(paths, entry)
}
data-dropdown-placement="bottom-start"
data-dropdown-offset-distance="5"
data-dropdown-offset-skidding="12"
class:list={[
"hover:text-caperren-green-light lg:hover:text-caperren-green-light flex w-full items-center justify-between lg:p-0 lg:hover:bg-transparent",
pathname.startsWith(getHrefPath(entry))
pathname.startsWith(getHrefPath(paths, entry))
? "border-caperren-green border-b-2"
: false,
]}
@@ -65,7 +58,7 @@ const { pathname } = Astro.url;
</svg>
</button>
<div
id={"dropdownNavbar" + getNavLinkSuffix(entry)}
id={"dropdownNavbar" + getNavLinkSuffix(paths, entry)}
class="border-caperren-green z-10 hidden w-max max-w-screen border bg-black px-6 shadow-sm"
>
<Astro.self
@@ -78,16 +71,18 @@ const { pathname } = Astro.url;
) : (
<div>
<a
href={getHrefPath(entry)}
target={getHrefPath(entry).startsWith("/") ? "" : "_blank"}
href={getHrefPath(paths, entry)}
target={
getHrefPath(paths, entry).startsWith("/") ? "" : "_blank"
}
class:list={[
"hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent lg:p-0",
pathname === getHrefPath(entry)
pathname === getHrefPath(paths, entry)
? "border-caperren-green border-b-2"
: false,
]}
aria-current={
pathname === getHrefPath(entry) ? "page" : undefined
pathname === getHrefPath(paths, entry) ? "page" : undefined
}
>
{entry.navText}

View File

@@ -14,6 +14,7 @@ const keys: { [key: string]: string } = {
TDD: "Test driven development",
UPS: "Uninterruptible power supply",
VISA: "Virtual instrument software architecture",
VPS: "Virtual private server",
};
const key: string | undefined = Astro.props.key;

View File

@@ -13,7 +13,11 @@ const { class: className, lineItems, depth = 0 } = Astro.props;
---
<ul
class:list={["list-inside list-disc", className, depth > 0 ? "ps-3" : false]}
class:list={[
"list-outside list-disc",
className,
depth > 0 ? "ps-3" : "ms-3",
]}
>
{
lineItems ? (

View File

@@ -1,6 +1,7 @@
import type { navLink } from "@interfaces/site-layout.ts";
export const siteLayout: navLink[] = [
// Standard navbar entries
{ navText: "About", path: "" },
{ navText: "Education", path: "education" },
{
@@ -187,6 +188,7 @@ export const siteLayout: navLink[] = [
},
{ enabled: false, navText: "NixOS", path: "nixos" },
{ navText: "Body Mods", path: "body-mods" },
{ navText: "This Website", path: "this-website" },
],
},
{
@@ -268,3 +270,13 @@ export const getPaths = (
}
return [...new Set(foundPaths)];
};
export const getNavLinkSuffix = (paths: string[], entry: navLink): string => {
return "-" + [...paths, entry.path].join("-");
};
export const getHrefPath = (paths: string[], entry: navLink): string => {
return entry.pubpath
? entry.pubpath
: "/" +
(paths && paths.length ? [...paths, entry.path].join("/") : entry.path);
};

View File

@@ -1,5 +1,6 @@
export interface navLink {
enabled?: boolean;
hidden?: boolean;
navText: string;
path?: string;
pubpath?: string;

View File

@@ -0,0 +1,120 @@
---
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import H3 from "@components/H3.astro";
import InlineLink from "@components/InlineLink.astro";
import PageGroup from "@components/PageGroup.astro";
import Paragraph from "@components/Paragraph.astro";
import Paragraphs from "@components/Paragraphs.astro";
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
import SkillMatrix from "@components/SkillMatrix/SkillMatrix.astro";
import type { categorySkills } from "@interfaces/skill-matrix.ts";
const categorizedSkills: categorySkills[] = [
{
category: "Software & Environments",
skills: [
{
item: "DevOps",
subItems: [
{ item: "Github Actions" },
{ item: "dev/staging/production environments" },
{ item: "automatic build/test/deploy" },
],
},
{ item: "Git" },
{
item: "Docker",
subItems: [
{ item: "Custom Builds" },
{ item: "Registry & Asset Management" },
],
},
{
item: "Programming Languages",
subItems: [
{ item: "HTML" },
{ item: "CSS" },
{ item: "Typescript" },
{ item: "Bash" },
{ item: "Makefile" },
],
},
{
item: "Web Frameworks",
subItems: [
{ item: "Astro" },
{ item: "tailwindcss" },
{ item: "flowbite" },
],
},
{
item: "Operating Systems",
subItems: [
{
item: "Linux",
subItems: [{ item: "NixOS" }, { item: "Alpine Linux" }],
},
],
},
],
},
];
---
<ExperienceLayout title="This Website" subTitles={["Hobbies"]}>
<PageGroup>
<Fragment slot="header"><H3>Summary</H3></Fragment>
<Paragraphs>
<Paragraph>
While I've traditionally used Wordpress to build my websites in the
past, I finally decided to make a custom one after developing the skills
to do so at <InlineLink
href="/experience/spacex/hardware-test-engineer-i-ii"
>SpaceX</InlineLink
>. I still wouldn't call myself a web developer by trade, but I take
great pride in being able to create things on my own, and have also felt
that Wordpress was overkill for a simple portfolio website. It also gave
me a chance to put my DevOps skills to use at home, which I've been
wanting to do for a while.
</Paragraph>
<Paragraph>
The core framework of my website is <InlineLink
href="https://astro.build/">Astro</InlineLink
>, chosen for its focus on static site generation and de-duplication of
code via re-usable <InlineLink
href="https://docs.astro.build/en/basics/astro-components/"
>components</InlineLink
>. This seemed like the perfect middle-ground of providing enough
structure and quality-of-life features to reduce the overall effort of
building the site, without being overly bloated or opinionated. So far
I've been incredibly happy with this decision, and would recommend it to
others looking to build static websites. To add some helpful styling
utilities, and basic web components, <InlineLink
href="https://tailwindcss.com">tailwindcss</InlineLink
> and <InlineLink href="https://flowbite.com">flowbite</InlineLink> were also
added. Like my decision to use Astro, these both provided good starting points
for creating a website that felt like my own, without struggling for too long
at the start.
</Paragraph>
<Paragraph>
From the DevOps perspective, I created a Makefile within the repo for
local development targets to build, run, and test both in a pure
context, and within a Docker container. After pushing updates on a
branch to my local Gitea instance, and opening a pull request, the
website performs spelling checks, runs unit tests, and integration
tests. Once these pass, the website is built into a Docker container and
uploaded to the registry in my Gitea instance. The image is then
deployed to staging on my <PopoverWordDefinition key="VPS" />, allowing
for manual validation of the changes. In order to merge, the build,
test, and deploy actions must pass, and ideally I should be empirically
validating the staging deployment. After merging and closing the pull
request, another action builds, tests, and deploys the main branch in
the same way as before, but to production, and is what you see here!
</Paragraph>
</Paragraphs>
<SkillMatrix categorizedSkills={categorizedSkills} />
</PageGroup>
</ExperienceLayout>