Compare commits

..

12 Commits

Author SHA1 Message Date
67b969d26b Merge pull request 'Round two, trying local gitea actions' (#16) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 3m58s
Build and Test - Production / build_and_push (push) Successful in 2m52s
Build and Test - Production / deploy_production (push) Successful in 2s
Reviewed-on: #16
2025-12-11 20:28:33 +00:00
25d7193fff Merge pull request 'Avionics test engineering internship content and about the site' (#15) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 4m42s
Build and Test - Production / build_and_push (push) Successful in 5m7s
Build and Test - Production / deploy_production (push) Successful in 2s
Reviewed-on: #15
2025-12-11 01:15:53 +00:00
bce5004708 Merge pull request 'Fix trailing slashes breaking pathname in prod, keep flex for main page div so footer sits properly, misspelling fix' (#14) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 4m40s
Build and Test - Production / build_and_push (push) Successful in 5m4s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #14
2025-12-06 20:07:23 +00:00
c580665963 Merge pull request 'Finished ross content, added skill matrix, li, and ul, and improved many existing components, created and refactored to unified layouts and grid, visual improvements with proper column to row collapsing' (#13) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 5m3s
Build and Test - Production / build_and_push (push) Successful in 5m1s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #13
2025-12-06 18:07:53 +00:00
6952b77980 Merge pull request 'Removed unused build, refactored H1-3 to use slot based setup, added visual and aria page highlighting for navbar links, switched all pages to use custom H1-3, better new page/tab handling for inline links' (#12) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 4m29s
Build and Test - Production / build_and_push (push) Successful in 5m1s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #12
2025-12-05 22:39:08 +00:00
134790aa25 Merge pull request 'Fix production build, bad reference in staging build' (#11) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 4m27s
Build and Test - Production / build_and_push (push) Successful in 4m59s
Build and Test - Production / deploy_production (push) Successful in 2s
Reviewed-on: #11
2025-12-05 20:15:03 +00:00
817c6076dc Merge pull request 'More website content updates' (#10) from website-content-updates into main
Some checks failed
Build and Test - Production / test (push) Failing after 3m2s
Build and Test - Production / build_and_push (push) Has been skipped
Build and Test - Production / deploy_production (push) Has been skipped
Reviewed-on: #10
2025-12-05 10:00:13 +00:00
6305482fc1 Merge pull request 'Need reference changed to test' (#9) from website-content-updates into main
All checks were successful
Build and Test - Production / test (push) Successful in 3m43s
Build and Test - Production / build_and_push (push) Successful in 3m32s
Build and Test - Production / deploy_production (push) Successful in 2s
Reviewed-on: #9
2025-11-10 09:33:04 +00:00
3ddd9b3640 Merge pull request 'Fixed extra repo_version that wasn't removed in prod build' (#8) from website-content-updates into main
Some checks failed
Build and Test - Production / test (push) Successful in 3m26s
Build and Test - Production / build_and_push (push) Failing after 47s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #8
2025-11-10 09:25:06 +00:00
43d0724345 Merge pull request 'website-content-updates' (#7) from website-content-updates into main
Some checks failed
Build and Test - Production / test (push) Successful in 3m39s
Build and Test - Production / build_and_push (push) Failing after 48s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #7
2025-11-10 09:18:10 +00:00
aeffd1545f Merge pull request 'Favicon, better screen responsive, starting experience layouts' (#6) from website-content-updates into main
All checks were successful
Build and Test - Production / determine_version (push) Successful in 6s
Build and Test - Production / build_and_push (push) Successful in 47s
Build and Test - Production / test (push) Successful in 1s
Build and Test - Production / deploy_production (push) Successful in 3s
Reviewed-on: #6
2025-07-09 11:48:33 +00:00
e9dd38ca6a Merge pull request 'Footer with environment, build, and hash' (#5) from website-content-updates into main
All checks were successful
Build and Test - Production / determine_version (push) Successful in 5s
Build and Test - Production / build_and_push (push) Successful in 47s
Build and Test - Production / test (push) Successful in 2s
Build and Test - Production / deploy_production (push) Successful in 2s
Reviewed-on: #5
2025-07-09 11:03:25 +00:00
120 changed files with 443 additions and 1801 deletions

View File

@@ -15,8 +15,7 @@
cleanup-check \
cleanup-code \
convert_video \
convert_video_times \
generate_asset_imports
convert_video_times
default: dev
@@ -84,17 +83,9 @@ convert_video_times:
-init_hw_device vaapi=va:/dev/dri/renderD128 \
-filter_hw_device va \
-i $(input) \
-ss $(start) \
-to $(end) \
-vf 'format=nv12,hwupload,scale_vaapi=-2:720' \
-vf 'format=nv12,hwupload,scale_vaapi=-2:720,trim=start=$(start):end=$(end)' \
-c:v h264_vaapi \
-rc_mode CQP \
-qp 28 \
-an \
$(output)
generate_asset_imports:
@for assets_path in `find "src/assets/${assets_relative_path}" -maxdepth 1 -type f -printf "%f\n"`; do \
without_extension=$${assets_path/%.*}; \
echo "import $${without_extension//-/_} from \"@assets/${assets_relative_path}/$$assets_path\";"; \
done;

View File

@@ -3,10 +3,7 @@ Altium
ASSEM
astrojs
Atmel
automations
barebones
beaglebone
Bitwarden
Candian
caperren
CEOAS
@@ -15,19 +12,10 @@ Concours
CONSERV
Corwin
dangerousthings
dechorionation
Dechorionator
dechorionators
dockerization
dockerizing
drumheller
ebox
ELMI
fhhs
flowbite
flowrate
gcode
gerbers
Gitea
HDFS
headshot
@@ -37,60 +25,36 @@ iceops
ITAR
Jetson
KFSK
Labjack
leconte
Loctite
luxon
MGMT
microcontroller
microcontroller's
Micropumps
Millis
modbus
Mokai
Multimeters
nixos
nvme
offroad
Onshape
OSSM
OSURC
panelized
Passthroughs
pcbs
Perren
Perren's
Pixhawk
Protocase
pubpath
RFID
Rito
RSSI
SARL
SCARA
showerheads
Shuttlebox
simplemotion
sinnhuber
sitemapindex
Smartsheet
solderable
ssds
Starlink
steller
Steller
Tanguay
Teamcenter
timelapse
touchoff
triaging
trivago
Truong
Ubiquiti
Unstow
uuidv
vaapi
vitest
Waterjet
Zebrafish
zscan

View File

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

View File

@@ -1,5 +0,0 @@
---
---
<h4 class="md:text-md text-xs sm:text-sm"><slot /></h4>

View File

@@ -1,21 +1,15 @@
---
import { Image } from "astro:assets";
import type { ComponentPropsBase } from "@interfaces/components.ts";
import type { carouselGroup } from "@interfaces/image-carousel.ts";
interface Props extends ComponentPropsBase {
carouselGroup: carouselGroup;
showBorder?: boolean;
}
const { class: className, carouselGroup, showBorder = true } = Astro.props;
const groupToShow: carouselGroup = Astro.props.carouselGroup;
---
<custom-carousel
class="relative flex w-full flex-col"
data-custom-carousel={carouselGroup.animation ?? "slide"}
data-custom-carousel-interval={carouselGroup.interval}
data-custom-carousel={groupToShow.animation}
data-custom-carousel-interval={groupToShow.interval}
>
<!-- Modal for fullscreen viewing -->
<div
@@ -63,18 +57,11 @@ const { class: className, carouselGroup, showBorder = true } = Astro.props;
</div>
<!-- Carousel wrapper -->
<div
class:list={[
"relative h-56 w-full overflow-hidden rounded-lg md:h-120",
showBorder ? "border" : false,
className ? className : "border-caperren-green-dark",
]}
>
<div class="relative h-56 w-full overflow-hidden md:h-120">
{
carouselGroup.images &&
carouselGroup.images.map((image, index) => (
groupToShow.images.map((image, index) => (
<div
class="hidden bg-black duration-1500 ease-in-out"
class="hidden duration-1500 ease-in-out"
data-custom-carousel-item={index}
>
<Image
@@ -91,14 +78,13 @@ const { class: className, carouselGroup, showBorder = true } = Astro.props;
<!-- Slider indicators -->
{
carouselGroup.images && carouselGroup.images.length > 1 && (
groupToShow.images.length > 1 && (
<div>
<div class="absolute bottom-2 left-1/2 z-30 flex -translate-x-1/2 space-x-3 rounded-full">
{carouselGroup.images &&
carouselGroup.images.map((_, index) => (
{groupToShow.images.map((_, index) => (
<button
type="button"
class="hover:bg-caperren-green-light h-3 w-3 rounded-full"
class="hover:bg-caperren-green-light h-3 w-3 rounded-full bg-black"
aria-current={index ? "false" : "true"}
aria-label={index.toString()}
data-custom-carousel-slide-to={index}
@@ -110,16 +96,15 @@ const { class: className, carouselGroup, showBorder = true } = Astro.props;
class="group absolute start-0 top-0 z-30 flex h-full cursor-pointer items-center justify-center px-4 focus:outline-none"
data-custom-carousel-prev
>
<span class="ring-caperren-green/35 group-hover:ring-caperren-green inline-flex h-10 w-10 items-center justify-center rounded-full bg-black/35 ring-2 group-hover:bg-black/75">
<span class="ring-caperren-green/25 inline-flex h-10 w-10 items-center justify-center rounded-full bg-black/25 ring-2 group-hover:bg-black/75">
<svg
class="text-caperren-green stroke-caperren-green group-hover:text-caperren-green-light h-4 w-4"
class="text-caperren-green group-hover:text-caperren-green-light h-4 w-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 8 10"
viewBox="0 0 6 10"
>
<path
stroke="currentColor"
fill-opacity="0%"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
@@ -134,16 +119,15 @@ const { class: className, carouselGroup, showBorder = true } = Astro.props;
class="group absolute end-0 top-0 z-30 flex h-full cursor-pointer items-center justify-center px-4 focus:outline-none"
data-custom-carousel-next
>
<span class="ring-caperren-green/25 group-hover:ring-caperren-green inline-flex h-10 w-10 items-center justify-center rounded-full bg-black/25 ring-2 group-hover:bg-black/75">
<span class="ring-caperren-green/25 inline-flex h-10 w-10 items-center justify-center rounded-full bg-black/25 ring-2 group-hover:bg-black/75">
<svg
class="text-caperren-green stroke-caperren-green group-hover:text-caperren-green-light h-4 w-4"
class="text-caperren-green group-hover:text-caperren-green-light h-4 w-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 4 10"
viewBox="0 0 6 10"
>
<path
stroke="currentColor"
fill-opacity="0%"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"

View File

@@ -22,7 +22,7 @@ const {
<div class="mx-auto my-auto">
<video
class="border-caperren-green-dark h-auto w-full rounded-lg border"
class="h-auto w-full"
controls={controls}
autoplay={autoPlay}
loop={loop}

View File

@@ -1,26 +1,13 @@
---
import type { videoConfig } from "@interfaces/video.ts";
interface Props extends videoConfig {}
const {
videoPath,
videoTitle,
width = "1920",
height = "1080",
autoPlay = false,
} = Astro.props;
const aspect = `${width} / ${height}`;
const config: videoConfig = Astro.props.videoConfig;
---
<div class="mx-auto my-auto w-full" style={`aspect-ratio: ${aspect};`}>
<iframe
src={videoPath}
title={videoTitle}
class="border-caperren-green-dark h-full w-full rounded-lg border"
allow={"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; " +
(autoPlay ? "autoplay;" : "")}
<iframe
class="h-128 w-full max-w-1/2"
src={config.videoPath}
title={config.videoTitle ?? ""}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen></iframe>
</div>

View File

@@ -36,8 +36,7 @@ const { pathname } = Astro.url;
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(paths, entry)) &&
!(entry.placeholderEntry ?? false)
pathname.startsWith(getHrefPath(paths, entry))
? "border-caperren-green border-b-2"
: false,
]}
@@ -72,32 +71,20 @@ const { pathname } = Astro.url;
) : (
<div>
<a
href={
!(entry.placeholderEntry ?? false)
? getHrefPath(paths, entry)
: undefined
}
href={getHrefPath(paths, entry)}
target={
getHrefPath(paths, entry).startsWith("/") ? "" : "_blank"
}
class:list={[
"ring-caperren-green-dark block bg-transparent lg:p-0",
"hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent lg:p-0",
pathname === getHrefPath(paths, entry)
? "border-caperren-green border-b-2"
: false,
entry.isSubItem ? "ms-3" : false,
entry.placeholderEntry
? false
: "hover:text-caperren-green-light",
]}
aria-current={
pathname === getHrefPath(paths, entry) &&
!(entry.placeholderEntry ?? false)
? "page"
: undefined
pathname === getHrefPath(paths, entry) ? "page" : undefined
}
>
{entry.isSubItem && "∟ "}
{entry.navText}
</a>
</div>

View File

@@ -3,7 +3,7 @@ const hasHeader = Astro.slots.has("header");
const hasDefault = Astro.slots.has("default");
---
<div class="grid grid-cols-1 gap-0.5">
<div class="grid grid-cols-1 gap-3">
{
Astro.slots.has("header") && (
<div>

View File

@@ -11,7 +11,6 @@ const keys: { [key: string]: string } = {
GUI: "Graphical user interface",
NUC: "A small and low-power computer made by Intel",
PCBs: "Printed circuit boards",
SCARA: "Selective Compliance Assembly Robot Arm",
TDD: "Test driven development",
UPS: "Uninterruptible power supply",
VISA: "Virtual instrument software architecture",

View File

@@ -1,58 +0,0 @@
---
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import Ul from "@components/Ul.astro";
import H3 from "@components/H3.astro";
import H4 from "@components/H4.astro";
import PageGroup from "@components/PageGroup.astro";
import type {
printedCircuitBoard,
printedCircuitBoardRevision,
} from "@interfaces/printed-circuit-board.ts";
interface Props {
pcb: printedCircuitBoard;
}
const { pcb } = Astro.props;
const semanticPcbRevisionSort = (
a: printedCircuitBoardRevision,
b: printedCircuitBoardRevision,
): number =>
-((a.major - b.major) * 100 + (a.minor - b.minor) * 10 + (a.patch - b.patch));
---
<PageGroup>
<Fragment slot="header"
><H3>{pcb.name}</H3><H4>{pcb.description}</H4></Fragment
>
<div class="mt-1 grid grid-cols-1 gap-4 md:grid-cols-2">
{
pcb.revisions?.sort(semanticPcbRevisionSort).map((revision) => (
<div class="border-caperren-green block space-y-2 rounded-lg border bg-black py-2">
<div class="border-caperren-green flex flex-wrap items-center justify-between rounded-none border-b px-4 pb-2">
<div>
<span class="font-black">Revision:</span>
<span>
{revision.major}.{revision.minor}.{revision.patch}
</span>
</div>
<div class="text-sm italic">{revision.date.toISODate()}</div>
</div>
<div class="px-4">
<Carousel
class=""
carouselGroup={{ images: revision.images }}
showBorder={false}
/>
</div>
{revision.notes && revision.notes.length > 0 && (
<div class="border-caperren-green border-t px-4 pt-4 pb-2 text-sm">
<Ul lineItems={revision.notes} />
</div>
)}
</div>
))
}
</div>
</PageGroup>

View File

@@ -1,11 +1,7 @@
---
import type { timelineEntry } from "@interfaces/timeline.ts";
interface Props {
timeline: timelineEntry[];
}
const { timeline = [] } = Astro.props;
const timeline: timelineEntry[] = Astro.props.timeline || [];
---
<custom-timeline>
@@ -15,11 +11,7 @@ const { timeline = [] } = Astro.props;
data-timeline
>
{
timeline
.sort((a: timelineEntry, b: timelineEntry) =>
a.date.diff(b.date).toMillis(),
)
.map((entry, index) => (
timeline.map((entry, index) => (
<div
class="border-caperren-green min-w-s max-w-s rounded-lg border bg-black px-2 pt-1 pb-2"
data-timeline-node-index={index}
@@ -27,7 +19,7 @@ const { timeline = [] } = Astro.props;
<h3 class="text-lg font-bold">{entry.event}</h3>
<h4 class="leading-none font-semibold">{entry.eventDetail}</h4>
<time class="mt-1 mb-2 text-sm leading-none italic">
{entry.date.toFormat("LLLL kkkk")}
{entry.date}
</time>
{entry.description && (
<p class="text-sm font-normal">{entry.description}</p>

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" },
{
@@ -12,6 +13,7 @@ export const siteLayout: navLink[] = [
path: "spacex",
children: [
{
enabled: false,
navText: "Hardware Test Engineer I/II",
path: "hardware-test-engineer-i-ii",
},
@@ -25,65 +27,60 @@ export const siteLayout: navLink[] = [
navText: "OSU CEOAS Ocean Mixing Group",
path: "osu-ceoas-ocean-mixing-group",
children: [
{
navText: "Student Software/Electrical Engineer",
placeholderEntry: true,
},
{
navText: "Robotic Oceanographic Surface Sampler",
isSubItem: true,
path: "robotic-oceanographic-surface-sampler",
},
{
navText: "LeConte Glacier Deployments",
isSubItem: true,
path: "leconte-glacier-deployments",
},
],
},
{
navText: "OSU Sinnhuber Aquatic Research Lab",
enabled: false,
navText: "OSU SARL",
path: "osu-sinnhuber-aquatic-research-laboratory",
children: [
{
navText: "Student Automation Engineer",
placeholderEntry: true,
enabled: false,
navText: "Team Lead",
path: "team-lead",
},
{
enabled: false,
navText: "Zebrafish Embryo Pick and Plate",
isSubItem: true,
path: "zebrafish-embryo-pick-and-plate",
},
{
enabled: false,
navText: "Shuttlebox Behavior System",
isSubItem: true,
path: "shuttlebox-behavior-system",
},
{
enabled: false,
navText: "Dechorionator",
isSubItem: true,
path: "dechorionator",
},
{
enabled: false,
navText: "Denso Embryo Pick and Plate",
isSubItem: true,
path: "denso-embryo-pick-and-plate",
},
{
enabled: false,
navText: "ZScan Processor",
isSubItem: true,
path: "zscan-processor",
},
],
},
{
enabled: false,
navText: "OSU Robotics Club",
path: "osu-robotics-club",
children: [
{
enabled: false,
navText: "Mars Rover Software Team Lead",
path: "mars-rover-software-team-lead",
},
@@ -266,10 +263,7 @@ export const getPaths = (
];
} else {
let enabled = currentEntry.enabled ?? true;
if (
(disabledOnly ? !enabled : enabled) &&
!currentEntry.placeholderEntry
) {
if (disabledOnly ? !enabled : enabled) {
foundPaths.push("/" + [...paths, currentEntry.path || ""].join("/"));
}
}

View File

@@ -1,5 +1,5 @@
export interface carouselGroup {
animation?: "static" | "slide";
animation: "static" | "slide";
interval?: number;
images?: ImageMetadata[];
images: ImageMetadata[];
}

View File

@@ -1,32 +0,0 @@
import type { ImageMetadata } from "astro";
import { DateTime } from "luxon";
import type { timelineEntry } from "@interfaces/timeline.ts";
import type { lineItem } from "@interfaces/ul-li.ts";
export interface printedCircuitBoardRevision {
major: number;
minor: number;
patch: number;
date: DateTime;
images?: ImageMetadata[];
notes?: lineItem[];
}
export interface printedCircuitBoard {
name: string;
description: string;
revisions: printedCircuitBoardRevision[];
}
export const timelineFromPrintedCircuitBoard = (
pcb: printedCircuitBoard,
): timelineEntry[] =>
pcb.revisions?.map((revision) => ({
event: `PCB Released: ${pcb.name} `,
eventDetail: `Revision: ${revision.major}.${revision.minor}.${revision.patch}`,
date: revision.date,
}));

View File

@@ -1,13 +1,8 @@
export interface navLink {
enabled?: boolean;
hidden?: boolean;
placeholderEntry?: boolean;
navText: string;
isSubItem?: boolean; // For visual distinction only
path?: string;
pubpath?: string;
children?: navLink[];
}

View File

@@ -1,8 +1,6 @@
import { DateTime } from "luxon";
export interface timelineEntry {
event: string;
eventDetail?: string;
date: DateTime;
date: string;
description?: string;
}

View File

@@ -1,9 +1,5 @@
export interface videoConfig {
videoPath: string;
videoTitle?: string;
width?: number; // “design” width
height?: number; // “design” height
autoPlay?: boolean;
videoPath: string;
videoType?: string;
}

Some files were not shown because too many files have changed in this diff Show More