Compartmentalized Timeline and Carousel, applied www-data permissions to all files in built docker container, for deploys to work
All checks were successful
Build and Test - Staging / determine_version (pull_request) Successful in 30s
Build and Test - Staging / build_and_push (pull_request) Successful in 2m21s
Build and Test - Staging / test (pull_request) Successful in 2s
Build and Test - Staging / deploy_staging (pull_request) Successful in 5s

This commit is contained in:
2025-11-07 21:36:08 -08:00
parent 9a4ecdd073
commit 40a673a418
19 changed files with 19 additions and 24 deletions

View File

@@ -0,0 +1,34 @@
---
import type {timelineEntry} from "@interfaces/timeline.ts";
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) => (
<div class="pt-1 border bg-black border-caperren-green rounded-lg min-w-s max-w-s px-2 pb-2"
data-timeline-node-index={index}
>
<h3 class="text-lg font-bold">
{entry.event}
</h3>
<h4 class="font-semibold leading-none">
{entry.eventDetail}
</h4>
<time class="mb-2 mt-1 text-sm italic leading-none">
{entry.date}
</time>
{entry.description && (
<p class="text-sm font-normal">
{entry.description}
</p>
)}
</div>
))}
</div>
</custom-timeline>
<script src="./timeline.ts"/>

View File

@@ -0,0 +1,44 @@
import LeaderLine from "leader-line-new";
class CustomTimeline extends HTMLElement {
_eventElements: Element[];
constructor() {
super();
this._eventElements = this._getNodeElements();
window.addEventListener("load", this._paintLeaderLines);
}
_getNodeElements = (): Element[] =>
Array.from(this.querySelectorAll('[data-timeline-node-index]')).sort(
(elementA, elementB) =>
Number(elementA.getAttribute('data-timeline-node-index')) - Number(elementB.getAttribute('data-timeline-node-index'))
);
_paintLeaderLines = () => {
let pairs = this._eventElements.map((entry, index) => {
if (index < this._eventElements.length - 1) {
return [entry, this._eventElements[index + 1]];
}
}).filter(pair => pair !== undefined)
pairs.forEach(pair => {
new LeaderLine({
start: pair[0],
end: pair[1],
color: '#10ac25',
size: 3,
startSocket: "right",
endSocket: "left",
startPlug: "square",
endPlug: "arrow3"
});
});
}
}
customElements.define('custom-timeline', CustomTimeline)