Standardize UI typography, charts and empty states

This commit is contained in:
2026-10-07 19:40:02 -04:00
parent 05bdeaf624
commit 0ed3cd6b47
57 changed files with 417 additions and 382 deletions
+10 -5
View File
@@ -5,6 +5,7 @@
import { pollVisible } from '$ui/poll.js';
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
import Button from '$ui/components/primitives/Button.svelte';
import EmptyState from '$ui/components/primitives/EmptyState.svelte';
import PolicyCard from '$ui/components/autoscaling/PolicyCard.svelte';
import { zombieMaps, zombieMapBySlug } from '$lib/map-aliases.js';
import type { ScalingSettings, ScalingPolicy, ScalingReport } from '$lib/autoscaling.js';
@@ -85,7 +86,7 @@
<svelte:head><title>Autoscaling | Electric Cherry</title></svelte:head>
<div class="page">
<SectionHeader title="Autoscaling" subtitle="Keep empty lobbies available for new groups, within the limits you choose.">
{#snippet actions()}<Button onclick={() => refresh()}>Refresh</Button>{#if canOperate}<Button disabled={busy} onclick={pauseAll}>{report.globalPaused ? 'Resume autoscaling' : 'Pause all'}</Button><Button variant="primary" disabled={busy} onclick={() => edit(null)}>Add policy</Button>{/if}{/snippet}
{#snippet actions()}<Button onclick={() => refresh()}>Refresh</Button>{#if canOperate && report.policies.length}<Button disabled={busy} onclick={pauseAll}>{report.globalPaused ? 'Resume autoscaling' : 'Pause all'}</Button><Button variant="primary" disabled={busy} onclick={() => edit(null)}>Add policy</Button>{/if}{/snippet}
</SectionHeader>
{#if report.globalPaused}<p class="banner">Autoscaling is paused globally. Outstanding jobs are still tracked and may finish.</p>{/if}
{#if refreshError}<p role="alert">{refreshError}</p>{/if}
@@ -112,15 +113,19 @@
</form>
</section>
{/if}
{#if !report.policies.length}<p class="panel">No autoscaling policies. Add a policy to manage empty lobbies for a map or a whole game.</p>{/if}
{#if !report.policies.length && !editorOpen}
<EmptyState title="No autoscaling policies" description={canOperate ? 'Policies keep empty lobbies available for a map or a whole game. Add one to choose its limits and spare lobby target.' : 'Policies keep empty lobbies available for a map or a whole game. An operator can add a policy.'}>
{#snippet actions()}{#if canOperate}<Button variant="primary" disabled={busy} onclick={() => edit(null)}>Add policy</Button>{/if}{/snippet}
</EmptyState>
{/if}
{#each report.policies as view (view.policy.id)}
<PolicyCard {view} globallyPaused={report.globalPaused} {canOperate} {busy} onedit={edit} ontoggle={togglePolicy} ondelete={remove} />
{/each}
</div>
<style>
.page { max-width: 1200px; margin: 0 auto; padding: 24px; }
.panel { margin: 20px 0; padding: 20px; border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); background: var(--surface); overflow-wrap: anywhere; }
.page { display: grid; gap: var(--space-5); min-width: 0; }
.panel { padding: 20px; border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); background: var(--surface); overflow-wrap: anywhere; }
.actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
h2 { font-size: var(--text-lg); margin: 0; }
p { line-height: 1.6; }
@@ -129,5 +134,5 @@
input, select { padding: 10px; min-width: 0; color: var(--text-primary); background: var(--surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); font: inherit; }
fieldset { border: 0; padding: 0; margin: 16px 0; min-width: 0; }
.banner { padding: 16px; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); }
@media (max-width: 500px) { .page { padding: 16px; } .panel { padding: 16px; } }
@media (max-width: 500px) { .panel { padding: 16px; } }
</style>