Skip to content

Commit 7c8fa16

Browse files
committed
add intervals and footer
1 parent 59a4980 commit 7c8fa16

File tree

3 files changed

+111
-20
lines changed

3 files changed

+111
-20
lines changed

pages/lex/timescales/+Page.client.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ export function Page() {
5656
return matchesName && matchesAgeRange;
5757
});
5858

59-
const width = window.screen.width;
60-
const timescaleWidth = width * 0.6 - 40;
6159
const handleClick = (timescale) => {
6260
const parent = timescale.target.parentElement;
6361
let selected;
@@ -99,7 +97,7 @@ export function Page() {
9997
h(
10098
"div.timescale",
10199
h(Timescale, {
102-
length: timescaleWidth,
100+
length: 970 - 40,
103101
levels: [1, 5],
104102
ageRange: [age[0], age[1]],
105103
absoluteAgeScale: true,

pages/lex/timescales/@id/+Page.client.ts

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ import { usePageContext } from "vike-react/usePageContext";
1313
import { Timescale } from "@macrostrat/timescale";
1414
import { titleCase } from "~/components/lex";
1515
import { useState, useEffect } from "react";
16-
import { Loading } from "~/components/general";
17-
16+
import { Footer, Loading } from "~/components/general";
17+
import { asChromaColor } from "@macrostrat/color-utils";
18+
import { Popover } from "@blueprintjs/core";
1819
export function Page() {
1920
const pageContext = usePageContext();
2021
const id = parseInt(pageContext.urlParsed.pathname.split("/")[3]);
2122
const res = useAPIResult(SETTINGS.apiV2Prefix + "/defs/timescales?all")
2223
?.success.data;
24+
const intervals = useAPIResult(SETTINGS.apiV2Prefix + "/defs/intervals?timescale_id=" + id)
25+
?.success.data;
2326
const [clickedInterval, setClickedInterval] = useState(null);
2427

25-
console.log("clicked", clickedInterval);
26-
2728
useEffect(() => {
2829
if (!clickedInterval) return;
2930

@@ -46,10 +47,11 @@ export function Page() {
4647
fetchInterval();
4748
}, [clickedInterval]);
4849

49-
if (res == null) return h(Loading);
50+
if (!res || !intervals) return h(Loading);
5051

5152
// temporary till api is fixed
5253
const timeRes = res.find((d) => d.timescale_id === id);
54+
const grouped = groupByIntType(intervals);
5355

5456
if (timeRes == null) return h("div", "Timescale not found");
5557

@@ -73,18 +75,86 @@ export function Page() {
7375
setClickedInterval(selected);
7476
};
7577

76-
return h(ContentPage, [
77-
h(PageBreadcrumbs, { title: "#" + id }),
78-
h("div.timescale-content", [
79-
h("h1", titleCase(timescale)),
80-
h("h3", max_age + " - " + min_age + " Ma"),
81-
h(Timescale, {
82-
levels: [0, 5],
83-
ageRange: [min_age, max_age],
84-
orientation: "vertical",
85-
absoluteAgeScale: true,
86-
onClick: handleClick,
87-
}),
78+
return h("div", [
79+
h(ContentPage, [
80+
h(PageBreadcrumbs, { title: "#" + id }),
81+
h("div.timescale-content", [
82+
h("h1", titleCase(timescale)),
83+
h("h3", max_age + " - " + min_age + " Ma"),
84+
h(Timescale, {
85+
length: 970,
86+
levels: [0, 5],
87+
ageRange: [min_age, max_age],
88+
orientation: "horizontal",
89+
absoluteAgeScale: true,
90+
onClick: handleClick,
91+
}),
92+
h(
93+
"div.int-list",
94+
Object.entries(grouped).map(([intType, group]) =>
95+
h("div.int-group", [
96+
h("h2", UpperCase(intType)),
97+
h(
98+
"div.int-items",
99+
group.map((d) => h(EconItem, { data: d, key: d.environ_id }))
100+
),
101+
])
102+
)
103+
),
104+
]),
88105
]),
106+
h(Footer)
89107
]);
90108
}
109+
110+
function groupByIntType(items) {
111+
return items.reduce((acc, item) => {
112+
const intType = item.int_type?.trim?.();
113+
if (!intType) return acc; // Skip items with no int_type
114+
115+
if (!acc[intType]) {
116+
acc[intType] = [];
117+
}
118+
119+
acc[intType].push(item);
120+
return acc;
121+
}, {});
122+
}
123+
124+
function UpperCase(str) {
125+
return str.charAt(0).toUpperCase() + str.slice(1);
126+
}
127+
128+
function EconItem({ data }) {
129+
const { name, color, abbrev, b_age, int_id, t_age, timescales } = data;
130+
const chromaColor = color ? asChromaColor(color) : null;
131+
const luminance = 0.9;
132+
data.id = int_id;
133+
134+
// return IntervalTag({ showAgeRange: true, interval: data });
135+
136+
return h(
137+
Popover,
138+
{
139+
className: "int-item-popover",
140+
content: h("div.int-tooltip", [
141+
h("div.int-tooltip-id", "ID: #" + int_id),
142+
h("div.int-tooltip-ages", b_age + " - " + t_age + " Ma"),
143+
abbrev ? h("div.int-tooltip-abbrev", "Abbreviation - " + abbrev) : null,
144+
h(Link, { href: "/lex/intervals/" + int_id }, "View details"),
145+
]),
146+
},
147+
h("div.int-item", [
148+
h(
149+
"div.int-name",
150+
{
151+
style: {
152+
backgroundColor: chromaColor?.luminance(1 - luminance).hex(),
153+
color: chromaColor?.luminance(luminance).hex(),
154+
},
155+
},
156+
name
157+
),
158+
])
159+
);
160+
}

pages/lex/timescales/@id/main.module.scss

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,26 @@ tspan {
2121
.visx-line {
2222
stroke: var(--text-color);
2323
}
24+
25+
.int-list {
26+
display: flex;
27+
flex-direction: column;
28+
gap: 1.3em;
29+
30+
h2 {
31+
margin: 0.5em 0;
32+
}
33+
34+
.int-items {
35+
display: flex;
36+
gap: 5px;
37+
flex-wrap: wrap;
38+
align-items: center;
39+
40+
.int-name {
41+
padding: 2px 6px;
42+
margin: 0.2em 0;
43+
border-radius: 0.2em;
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)