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
This commit is contained in:
@@ -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"]
|
||||
EXPOSE 80
|
||||
@@ -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()
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -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;'
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 => (
|
||||
|
||||
@@ -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) => (
|
||||
|
||||
@@ -7,7 +7,6 @@ class CustomTimeline extends HTMLElement {
|
||||
super();
|
||||
this._eventElements = this._getNodeElements();
|
||||
|
||||
|
||||
window.addEventListener("load", this._paintLeaderLines);
|
||||
|
||||
}
|
||||
@@ -26,17 +25,20 @@ class CustomTimeline extends HTMLElement {
|
||||
}
|
||||
}).filter(pair => pair !== undefined)
|
||||
|
||||
let contentBodyScrolling = document.getElementById("content-body-scrolling")
|
||||
|
||||
pairs.forEach(pair => {
|
||||
new LeaderLine({
|
||||
start: pair[0],
|
||||
end: pair[1],
|
||||
color: '#10ac25',
|
||||
size: 3,
|
||||
startSocket: "right",
|
||||
endSocket: "left",
|
||||
startPlug: "square",
|
||||
endPlug: "arrow3"
|
||||
});
|
||||
let line = new LeaderLine({
|
||||
start: pair[0],
|
||||
end: pair[1],
|
||||
color: '#10ac25',
|
||||
size: 3,
|
||||
startSocket: "right",
|
||||
endSocket: "left",
|
||||
startPlug: "square",
|
||||
endPlug: "arrow3"
|
||||
});
|
||||
contentBodyScrolling?.addEventListener("scroll", () => line.position())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"},
|
||||
|
||||
@@ -16,20 +16,23 @@ 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">
|
||||
<Navbar/>
|
||||
<main class="mx-6 mt-6 mb-14">
|
||||
{(Astro.props.title && showTitle && pageEnabled) && (
|
||||
<h1 class="font-extrabold md:text-3xl md:mb-6">{Astro.props.title}</h1>
|
||||
)}
|
||||
{pageEnabled && (
|
||||
<slot/>
|
||||
)}
|
||||
</main>
|
||||
<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 my-6">
|
||||
{(Astro.props.title && showTitle && pageEnabled) && (
|
||||
<h1 class="font-extrabold md:text-3xl md:mb-6">{Astro.props.title}</h1>
|
||||
)}
|
||||
{pageEnabled && (
|
||||
<slot/>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
<Footer/>
|
||||
<script src="../scripts/main.ts"></script>
|
||||
</body>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
5
src/pages/sitemap-index.xml
Normal file
5
src/pages/sitemap-index.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<sitemapindex>
|
||||
<sitemap>
|
||||
<loc>https://caperren.com/sitemap-0.xml</loc>
|
||||
</sitemap>
|
||||
</sitemapindex>
|
||||
@@ -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")
|
||||
});
|
||||
}
|
||||
@@ -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
32
test/endpoints.spec.ts
Normal 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);
|
||||
});
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user