Overhaul portal calculator frontend

This commit is contained in:
Dominic Ferrando
2026-07-08 15:45:03 -04:00
parent 2804f2cbf9
commit c474c16a1d
3 changed files with 341 additions and 228 deletions
@@ -0,0 +1,45 @@
<script lang="ts">
interface Props {
label: string;
value: number;
onchange: (value: number) => void;
scale?: number;
min?: number;
max?: number;
step?: number;
placeholder?: string;
disabled?: boolean;
}
let {
label,
value,
onchange,
scale = 100,
min,
max,
step,
placeholder,
disabled,
}: Props = $props();
function onInput(e: Event & { currentTarget: HTMLInputElement }) {
const pct = e.currentTarget.valueAsNumber;
if (!Number.isNaN(pct)) onchange(pct / scale);
}
</script>
<label class="flex flex-col gap-1">
<span class="label text-xs">{label}</span>
<input
class="input input-sm w-20"
type="number"
{min}
{max}
{step}
{placeholder}
value={Math.round(value * scale)}
oninput={onInput}
{disabled}
/>
</label>
@@ -31,9 +31,15 @@
const rawValue = standard.levels[lvl];
const unit = allStandards.byActivity(activity).getMetadata().unit;
switch (unit) {
case "ms":
const seconds = (rawValue / 1000).toFixed(1);
return `${seconds}`;
case "ms": {
if (activity === Activity.Run) {
const totalSeconds = Math.round(rawValue / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}
return (rawValue / 1000).toFixed(1);
}
case "cm": {
const totalInches = cmToIn(rawValue);
const feet = Math.floor(totalInches / 12);
@@ -51,19 +57,9 @@
<section class="w-full">
<div>
<div class="flex items-center">
<p class="text-xs label">
{#if selected.standardsConfig.params.activity[selected.activity].enableGeneration && allStandards
.byActivity(selected.activity)
.getMetadata().generators.length}
(Generated data: {allStandards
.byActivity(selected.activity)
.getMetadata()
.generators.map((g) => g.metric)
.join(", ")})
{:else}
(Generated data: NONE)
{/if}
</p>
<h2 class="text-xl font-semibold">
{allStandards.byActivity(selected.activity).getMetadata().name}
</h2>
</div>
</div>