feat: build compact BO2 grind companion with cumulative ranks
Some checks failed
Test and deploy staging / staging (push) Failing after 2m50s
Some checks failed
Test and deploy staging / staging (push) Failing after 2m50s
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
prestigeCap = 1000,
|
||||
prestigeRequiresMaxLevel = false,
|
||||
compact = false,
|
||||
dense = false,
|
||||
disabled,
|
||||
onupdate,
|
||||
onedit
|
||||
@@ -24,6 +25,7 @@
|
||||
prestigeCap?: number;
|
||||
prestigeRequiresMaxLevel?: boolean;
|
||||
compact?: boolean;
|
||||
dense?: boolean;
|
||||
disabled: boolean;
|
||||
onupdate: (rank: { itemId: number; level: number; prestige: number }) => void;
|
||||
onedit: () => void;
|
||||
@@ -61,78 +63,117 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space-y-1">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<div
|
||||
class="flex items-center gap-1 rounded-lg border bg-background p-1"
|
||||
aria-label={`${name} level controls`}
|
||||
{#if dense}
|
||||
<div class="relative flex shrink-0 items-center gap-0.5">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded px-1 py-1 text-[11px] tabular-nums hover:bg-accent"
|
||||
aria-label={`Edit ${name} level and prestige`}
|
||||
disabled={disabled || saving}
|
||||
onclick={onedit}
|
||||
title="Edit level and prestige"
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Level down ${name}`}
|
||||
disabled={disabled || saving || level <= 1}
|
||||
onclick={() => adjust('level', -1)}
|
||||
><Minus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
class={compact
|
||||
? 'h-8 min-w-11 flex-col gap-0 px-1 tabular-nums'
|
||||
: 'h-10 min-w-16 flex-col gap-0 px-2 tabular-nums'}
|
||||
aria-label={`Edit ${name} level and prestige`}
|
||||
disabled={disabled || saving}
|
||||
onclick={onedit}
|
||||
><span
|
||||
class={compact ? 'text-[8px] text-muted-foreground' : 'text-[10px] text-muted-foreground'}
|
||||
>LEVEL</span
|
||||
><span class={compact ? 'text-sm font-semibold' : 'text-lg font-semibold'}>{level}{#if levelCap}<span class="text-muted-foreground">/{levelCap}</span>{/if}</span
|
||||
></Button
|
||||
>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Level up ${name}`}
|
||||
disabled={disabled || saving || level >= (levelCap ?? 10000)}
|
||||
onclick={() => adjust('level', 1)}
|
||||
><Plus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-1 rounded-lg border bg-background p-1"
|
||||
aria-label={`${name} prestige controls`}
|
||||
<span class="sr-only">LEVEL</span>{level}{#if levelCap}<span class="text-muted-foreground"
|
||||
>/{levelCap}</span
|
||||
>{/if}
|
||||
</button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class="size-6"
|
||||
aria-label={`Level up ${name}`}
|
||||
disabled={disabled || saving || level >= (levelCap ?? 10000)}
|
||||
onclick={() => adjust('level', 1)}><Plus class="size-3" /></Button
|
||||
>
|
||||
<span
|
||||
role="status"
|
||||
class={error
|
||||
? 'absolute right-0 top-full z-20 w-52 rounded border bg-destructive p-2 text-xs text-white'
|
||||
: 'sr-only'}>{saving ? 'Saving…' : error || (saved ? 'Saved' : '')}</span
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Prestige down ${name}`}
|
||||
disabled={disabled || saving || prestige <= 0}
|
||||
onclick={() => adjust('prestige', -1)}
|
||||
><Minus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
<span class="min-w-12 text-center tabular-nums"
|
||||
><span
|
||||
class={compact
|
||||
? 'block text-[8px] text-muted-foreground'
|
||||
: 'block text-[10px] text-muted-foreground'}>PRESTIGE</span
|
||||
><span class={compact ? 'text-sm font-semibold' : 'text-lg font-semibold'}>{prestige}{#if prestigeCap < 1000}<span class="text-muted-foreground">/{prestigeCap}</span>{/if}</span
|
||||
></span
|
||||
>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Prestige up ${name}`}
|
||||
disabled={disabled || saving || prestige >= prestigeCap || (prestigeRequiresMaxLevel && level < (levelCap ?? 10000))}
|
||||
onclick={() => adjust('prestige', 1)}
|
||||
><Plus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<p class="min-h-3 text-[9px] text-muted-foreground" role="status">
|
||||
{saving ? 'Saving…' : error || (saved ? 'Saved' : 'Tap the level to edit both values')}
|
||||
</p>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-1">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<div
|
||||
class="flex items-center gap-1 rounded-lg border bg-background p-1"
|
||||
aria-label={`${name} level controls`}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Level down ${name}`}
|
||||
disabled={disabled || saving || level <= 1}
|
||||
onclick={() => adjust('level', -1)}
|
||||
><Minus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
class={compact
|
||||
? 'h-8 min-w-11 flex-col gap-0 px-1 tabular-nums'
|
||||
: 'h-10 min-w-16 flex-col gap-0 px-2 tabular-nums'}
|
||||
aria-label={`Edit ${name} level and prestige`}
|
||||
disabled={disabled || saving}
|
||||
onclick={onedit}
|
||||
><span
|
||||
class={compact
|
||||
? 'text-[8px] text-muted-foreground'
|
||||
: 'text-[10px] text-muted-foreground'}>LEVEL</span
|
||||
><span class={compact ? 'text-sm font-semibold' : 'text-lg font-semibold'}
|
||||
>{level}{#if levelCap}<span class="text-muted-foreground">/{levelCap}</span>{/if}</span
|
||||
></Button
|
||||
>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Level up ${name}`}
|
||||
disabled={disabled || saving || level >= (levelCap ?? 10000)}
|
||||
onclick={() => adjust('level', 1)}
|
||||
><Plus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-1 rounded-lg border bg-background p-1"
|
||||
aria-label={`${name} prestige controls`}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Prestige down ${name}`}
|
||||
disabled={disabled || saving || prestige <= 0}
|
||||
onclick={() => adjust('prestige', -1)}
|
||||
><Minus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
<span class="min-w-12 text-center tabular-nums"
|
||||
><span
|
||||
class={compact
|
||||
? 'block text-[8px] text-muted-foreground'
|
||||
: 'block text-[10px] text-muted-foreground'}>PRESTIGE</span
|
||||
><span class={compact ? 'text-sm font-semibold' : 'text-lg font-semibold'}
|
||||
>{prestige}{#if prestigeCap < 1000}<span class="text-muted-foreground"
|
||||
>/{prestigeCap}</span
|
||||
>{/if}</span
|
||||
></span
|
||||
>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class={compact ? 'size-7' : 'size-10'}
|
||||
aria-label={`Prestige up ${name}`}
|
||||
disabled={disabled ||
|
||||
saving ||
|
||||
prestige >= prestigeCap ||
|
||||
(prestigeRequiresMaxLevel && level < (levelCap ?? 10000))}
|
||||
onclick={() => adjust('prestige', 1)}
|
||||
><Plus class={compact ? 'size-3' : 'size-4'} aria-hidden="true" /></Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<p class="min-h-3 text-[9px] text-muted-foreground" role="status">
|
||||
{saving ? 'Saving…' : error || (saved ? 'Saved' : 'Tap the level to edit both values')}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user