diff options
| author | Adam Malczewski <[email protected]> | 2026-10-14 17:04:35 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-10-14 17:04:35 +0900 |
| commit | 10e78065201c8387494b8aafabb987da87183b3a (patch) | |
| tree | f038f368459acbd3b817974100fb4bd4817ecbff /src/features/account-usage/ui/UsageBar.svelte | |
| parent | 551a7a050e8cd25e795026a1060c9d5b5ea028bf (diff) | |
| download | dispatch-web-10e78065201c8387494b8aafabb987da87183b3a.tar.gz dispatch-web-10e78065201c8387494b8aafabb987da87183b3a.zip | |
feat(account-usage): sidebar Usage view with Claude/Codex quota bars + on-track pace markers
Consumes GET /usage (transport-contract 0.25.0). DaisyUI progress bars per quota
window with a dot at the elapsed fraction of the window (the 'on track' level),
ahead/under-pace labels, reset countdowns, stale/unavailable/not-configured states.
Diffstat (limited to 'src/features/account-usage/ui/UsageBar.svelte')
| -rw-r--r-- | src/features/account-usage/ui/UsageBar.svelte | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/features/account-usage/ui/UsageBar.svelte b/src/features/account-usage/ui/UsageBar.svelte new file mode 100644 index 0000000..f4298c1 --- /dev/null +++ b/src/features/account-usage/ui/UsageBar.svelte @@ -0,0 +1,49 @@ +<script lang="ts"> + import type { UsageBarView } from "../logic/view-model"; + + let { bar }: { bar: UsageBarView } = $props(); + + const progressClass = $derived( + { + success: "progress-success", + warning: "progress-warning", + error: "progress-error", + neutral: "", + }[bar.tone], + ); +</script> + +<div class="flex flex-col gap-0.5" data-testid="usage-bar" data-limit-id={bar.id}> + <div class="flex items-baseline justify-between gap-2 text-xs"> + <span class="truncate font-medium">{bar.label}</span> + <span class="shrink-0 font-mono tabular-nums">{bar.valueLabel}</span> + </div> + <div class="relative flex items-center"> + <progress + class="progress h-2 w-full {progressClass}" + value={bar.percent} + max="100" + aria-label="{bar.label} usage" + ></progress> + {#if bar.pacePercent !== null} + <!-- Pace marker: where usage would be if spread evenly to the reset. --> + <span + class="pointer-events-none absolute top-1/2 size-2.5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-base-100 bg-base-content" + style="left: {bar.pacePercent}%" + data-testid="pace-marker" + title="On-track pace: {Math.round(bar.pacePercent)}%" + aria-hidden="true" + ></span> + {/if} + </div> + {#if bar.resetLabel || bar.paceLabel} + <div class="flex justify-between gap-2 text-[11px] opacity-60"> + <span>{bar.resetLabel ?? ""}</span> + {#if bar.paceLabel} + <span class:text-warning={bar.aheadOfPace} class:opacity-100={bar.aheadOfPace} + >{bar.paceLabel}</span + > + {/if} + </div> + {/if} +</div> |
