Fixed weird floating footer behavior, updated Timeline to handle new growing scrolling content div, fixed grammar issue on chubby buttons, removed used nginx configs and Dockerfile comments, made Table not go full-w automatically, added tests to ensure no orphaned astro pages or site layout entries exist, dummy sitemap index so code analysis doesn't freak out
Some checks failed
Build and Test - Staging / test (pull_request) Failing after 3m28s
Build and Test - Staging / build_and_push (pull_request) Has been skipped
Build and Test - Staging / deploy_staging (pull_request) Has been skipped

This commit is contained in:
2025-11-11 15:16:15 -08:00
parent 85a86f3681
commit c9f921ba5b
17 changed files with 78 additions and 76 deletions

View File

@@ -26,8 +26,4 @@ COPY --from=build /app/dist /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html
#COPY entrypoint.sh /entrypoint.sh
EXPOSE 80
#ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -3,11 +3,14 @@ import {defineConfig} from 'astro/config';
import sitemap from "@astrojs/sitemap";
import tailwindcss from "@tailwindcss/vite";
// We don't have access to short imports this early in the build chain
// noinspection ES6PreferShortImport
import {siteLayout, getPaths} from "./src/data/site-layout.ts";
const disabledPaths = getPaths(siteLayout, [], true)
// https://astro.build/config
export default defineConfig({
site: "https://caperren.com",
prefetch: {
@@ -20,6 +23,9 @@ export default defineConfig({
})
],
vite: {
plugins: [tailwindcss()],
plugins: [
// @ts-ignore
tailwindcss()
],
},
});

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env sh
set -e
# Generate a unique token per container launch
TOKEN="$(cat /proc/sys/kernel/random/uuid)" # or: TOKEN="$(date +%s%N)"
# Write it into a file NGINX will include
cat >/etc/nginx/conf.d/_release_token.conf <<EOF
# auto-generated at container start
set \$release_token "$TOKEN";
EOF
# Then exec nginx
exec nginx -g 'daemon off;'

View File

@@ -14,12 +14,6 @@ http {
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
#include /etc/nginx/conf.d/_release_token.conf;
#etag off;
#add_header ETag "\"W/$release_token\"" always;
#add_header Cache-Control "max-age=0, must-revalidate" always;
gzip on;
gzip_proxied any;

View File

@@ -1,7 +1,7 @@
---
---
<footer class="fixed bottom-0 left-0 z-20 w-full px-6 py-2 bg-black border-t border-t-caperren-green-dark text-caperren-green-dark text-sm flex items-center justify-between">
<footer class="z-50 w-full max-w-full px-6 py-2 bg-black border-t border-t-caperren-green-dark text-caperren-green-dark text-sm flex items-center justify-between">
<span>{import.meta.env.PUBLIC_BUILD_ENVIRONMENT || "development"}</span>
<span>{import.meta.env.PUBLIC_REPO_VERSION_HASH || "invalid"}</span>
</footer>

View File

@@ -8,7 +8,7 @@ const paddingClasses: string = `px-${columnPadding} py-${rowPadding}`;
---
<div class="relative max-w-full overflow-x-auto">
<table class="w-full text-sm text-left">
<table class="text-sm text-left">
<thead class="text-xs border-b-3 border-caperren-green uppercase bg-black">
<tr>
{data.header.map(headingText => (

View File

@@ -5,7 +5,6 @@ const timeline: timelineEntry[] = Astro.props.timeline || [];
---
<custom-timeline>
<div class="relative z-10 grid gap-6 grid-flow-row sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 3xl:grid-cols-6"
data-timeline>
{timeline.map((entry, index) => (

View File

@@ -7,7 +7,6 @@ class CustomTimeline extends HTMLElement {
super();
this._eventElements = this._getNodeElements();
window.addEventListener("load", this._paintLeaderLines);
}
@@ -26,8 +25,10 @@ class CustomTimeline extends HTMLElement {
}
}).filter(pair => pair !== undefined)
let contentBodyScrolling = document.getElementById("content-body-scrolling")
pairs.forEach(pair => {
new LeaderLine({
let line = new LeaderLine({
start: pair[0],
end: pair[1],
color: '#10ac25',
@@ -37,6 +38,7 @@ class CustomTimeline extends HTMLElement {
startPlug: "square",
endPlug: "arrow3"
});
contentBodyScrolling?.addEventListener("scroll", () => line.position())
});
}
}

View File

@@ -4,22 +4,18 @@ export const siteLayout: navLink[] = [
{navText: "About", path: ""},
{navText: "Education", path: "education"},
{
enabled: false,
navText: "Experiences",
path: "experience",
children: [
{
enabled: false,
navText: "SpaceX",
path: "spacex",
children: [
{
enabled: false,
navText: "Hardware Test Engineer I/II",
path: "hardware-test-engineer-i-ii"
},
{
enabled: false,
navText: "Avionics Test Engineering Internship",
path: "avionics-test-engineering-internship"
}
@@ -151,8 +147,9 @@ export const siteLayout: navLink[] = [
navText: "Projects",
path: "projects",
children: [
{navText: "Shed Solar", path: "shed-solar", enabled: false},
{navText: "OSSM Overkill Edition", path: "ossm-overkill-edition", enabled: false},
{navText: "Rachael Ray Light Box", path: "rachael-ray-light-box", enabled: false},
{navText: "Shed Solar", path: "shed-solar", enabled: false},
]
},
{enabled: false, navText: "NixOS", path: "nixos"},

View File

@@ -16,13 +16,15 @@ const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true;
<head>
<meta charset="UTF-8"/>
<link rel="icon" href="/favicon-solid.png" type="image/png"/>
<!--suppress HtmlUnknownTarget -->
<link rel="sitemap" href="/sitemap-index.xml"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{pageEnabled ? pageTitle : "Corwin Perren"}</title>
</head>
<body class="bg-black text-white">
<body class="flex flex-col bg-black text-white h-dvh">
<div id="content-body-scrolling" class="grow overflow-y-scroll">
<Navbar/>
<main class="mx-6 mt-6 mb-14">
<main class="mx-6 my-6">
{(Astro.props.title && showTitle && pageEnabled) && (
<h1 class="font-extrabold md:text-3xl md:mb-6">{Astro.props.title}</h1>
)}
@@ -30,6 +32,7 @@ const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true;
<slot/>
)}
</main>
</div>
<Footer/>
<script src="../scripts/main.ts"></script>
</body>

View File

@@ -68,7 +68,6 @@ const headerCarouselGroup: carouselGroup = {
While my first iteration was sized appropriately and went together with no issues, the ball mount neck ended up
snapping due to a low infill percentage. After changing that area to 100% infill, including a handful of the
rear mount layers that it attached to, a second iteration has worked perfectly for a few years now! If you're
interested in printing this yourself, feel free to download the model and print it yourself using the button
under the photos!
interested in printing this yourself, feel free to download the model using the button under the photos!
</p>
</HobbyLayout>

View File

@@ -39,7 +39,7 @@ const headerCarouselGroup: carouselGroup = {
Through college, I learned electronics and PCB design, embedded and pc programming, basic mechanical design and
fabrication, on top of learning how to work well with others in a team.
I quickly realized that robotics was an ideal focus due to its inherent multi-disciplinary nature, and joined
the OSU Robotics club, which introduced me to people who are still my best friends today.
the OSU Robotics Club, which introduced me to people who are still my best friends today.
Through student engineering jobs, I had the unique opportunity to work on some incredible projects such as the
<a class="text-blue-500 hover:text-blue-300"
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler">robotic oceanographic

View File

@@ -0,0 +1,5 @@
<sitemapindex>
<sitemap>
<loc>https://caperren.com/sitemap-0.xml</loc>
</sitemap>
</sitemapindex>

View File

@@ -11,7 +11,6 @@ for (const pagePath of getPaths()) {
test(`${pagePath}: Has Title`, async ({page}) => {
await page.goto(pagePath);
console.log(await page.title());
expect(await page.title()).not.toBe("Corwin Perren")
});
}

View File

@@ -1,15 +0,0 @@
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import { expect, test } from 'vitest';
import Navbar from "@components/Navbar.astro"
test('Card with slots', async () => {
const container = await AstroContainer.create();
const result = await container.renderToString(Navbar, {
slots: {
default: 'Card content',
},
});
// expect(result).toContain('This is a card');
// expect(result).toContain('Card content');
});

32
test/endpoints.spec.ts Normal file
View File

@@ -0,0 +1,32 @@
import {expect, test} from "vitest";
import {siteLayout, getPaths} from "@data/site-layout.ts";
// Paths that should be known to Astro statically
const astroStaticPaths = new Set(
Object.keys(import.meta.glob("/src/pages/**/*.astro"))
.map((path) =>
path
.replace("/src/pages", "")
.replace(/index\.astro$/, "")
.replace(/\.astro$|\.md$/, "")
.replace(/\/$/, "")
|| "/"
));
// Paths that exist in the site layout
const siteLayoutPaths = new Set([...getPaths(siteLayout), ...getPaths(siteLayout, [], true)]);
// Paths that exist in Astro's static paths, but not in site layout
const astroNotLayoutPaths = astroStaticPaths.difference(siteLayoutPaths);
// Paths that exist in site layout, but not in Astro's static paths
const siteLayoutNotAstroPaths = siteLayoutPaths.difference(astroStaticPaths);
test('Pages Missing from Site Layout', async () => {
expect(astroNotLayoutPaths).toHaveLength(0);
});
test('Pages Missing from Astro Paths', async () => {
expect(siteLayoutNotAstroPaths).toHaveLength(0);
});

View File

@@ -3,6 +3,7 @@ import {getViteConfig} from 'astro/config';
export default getViteConfig(
{
// @ts-ignore
test: {
exclude: [
"test-e2e/**",
@@ -13,8 +14,6 @@ export default getViteConfig(
'@': path.resolve(__dirname, './src')
},
},
/* for example, use global to avoid globals imports (describe, test, expect): */
// globals: true,
},
},
{