ui changes and cs prices
All checks were successful
Test and deploy staging / staging (push) Successful in 11m52s
All checks were successful
Test and deploy staging / staging (push) Successful in 11m52s
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import ProgressBar from '$lib/components/ProgressBar.svelte';
|
||||
import * as Card from '$lib/components/ui/card/index.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
@@ -24,33 +26,33 @@
|
||||
|
||||
<section class="mt-10">
|
||||
<h2 class="text-2xl font-semibold">Pokémon</h2>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon')}
|
||||
class="mt-4 block rounded-lg border border-[var(--site-border)] p-5 hover:bg-[var(--site-hover)]"
|
||||
<Card.Root class="mt-4 py-0 transition-colors hover:bg-muted/50"
|
||||
><Card.Content class="p-0"
|
||||
><a href={resolve('/projects/game-tracker/pokemon')} class="block p-5">
|
||||
<div class="grid grid-cols-[minmax(0,1fr)_8rem_auto] items-center gap-3">
|
||||
<p class="text-xl font-semibold">catchemall</p>
|
||||
<div class="w-32">
|
||||
<ProgressBar
|
||||
value={data.pokemon.caught.entries}
|
||||
max={data.pokemon.totals.entries}
|
||||
label="Pokémon caught"
|
||||
small
|
||||
/>
|
||||
</div>
|
||||
<p class="text-xl font-semibold tabular-nums">
|
||||
{percent(data.pokemon.caught.entries, data.pokemon.totals.entries)}%
|
||||
</p>
|
||||
</div>
|
||||
<p class="mt-2 text-[var(--site-muted)]">
|
||||
{data.pokemon.caught.entries} of {data.pokemon.totals.entries} obtainable entries ·
|
||||
{data.pokemon.caught.species} of {data.pokemon.totals.species} species · {data.pokemon
|
||||
.totals.games} games
|
||||
</p>
|
||||
</a></Card.Content
|
||||
></Card.Root
|
||||
>
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-3">
|
||||
<p class="text-xl font-semibold">catchemall</p>
|
||||
<p class="text-xl font-semibold tabular-nums">
|
||||
{percent(data.pokemon.caught.entries, data.pokemon.totals.entries)}%
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<ProgressBar
|
||||
value={data.pokemon.caught.entries}
|
||||
max={data.pokemon.totals.entries}
|
||||
label="Pokémon caught"
|
||||
small
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-2 text-[var(--site-muted)]">
|
||||
{data.pokemon.caught.entries} of {data.pokemon.totals.entries} obtainable entries ·
|
||||
{data.pokemon.caught.species} of {data.pokemon.totals.species} species · {data.pokemon
|
||||
.totals.games} games
|
||||
</p>
|
||||
</a>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon/locations')}
|
||||
class="mt-3 inline-block underline underline-offset-4">browse Pokémon locations</a
|
||||
<Button variant="link" href={resolve('/projects/game-tracker/pokemon/locations')} class="mt-3"
|
||||
>browse Pokémon locations</Button
|
||||
>
|
||||
</section>
|
||||
|
||||
@@ -59,39 +61,43 @@
|
||||
<ul class="mt-4 grid gap-4 md:grid-cols-2">
|
||||
{#each data.callOfDuty as game (game.slug)}
|
||||
<li>
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/call-of-duty/[slug]', { slug: game.slug })}
|
||||
class="block h-full rounded-lg border border-[var(--site-border)] p-5 hover:bg-[var(--site-hover)]"
|
||||
>
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-3">
|
||||
<p class="text-xl font-semibold">{game.name}</p>
|
||||
<p class="text-[var(--site-muted)]">{game.releaseYear}</p>
|
||||
</div>
|
||||
<dl class="mt-4 grid gap-3">
|
||||
{#each [{ key: 'achievements', label: 'achievements', ...game.achievements }, ...game.milestones] as row (row.key)}
|
||||
<div>
|
||||
<div class="flex justify-between gap-3 text-[var(--site-muted)]">
|
||||
<dt>{row.label}</dt>
|
||||
<dd class="tabular-nums">{row.value}/{row.total}</dd>
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
<ProgressBar value={row.value} max={row.total} label={row.label} small />
|
||||
</div>
|
||||
<Card.Root class="h-full py-0 transition-colors hover:bg-muted/50"
|
||||
><Card.Content class="p-0"
|
||||
><a
|
||||
href={resolve('/projects/game-tracker/call-of-duty/[slug]', { slug: game.slug })}
|
||||
class="block h-full p-5"
|
||||
>
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-3">
|
||||
<p class="text-xl font-semibold">{game.name}</p>
|
||||
<p class="text-[var(--site-muted)]">{game.releaseYear}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</dl>
|
||||
{#if game.tiers.length}
|
||||
<p class="mt-4 text-[var(--site-muted)]">
|
||||
{game.tiers
|
||||
.map((tier) =>
|
||||
tier.scope === 'class'
|
||||
? `${tier.label} ${tier.value}/${tier.total} classes`
|
||||
: `${tier.label} ${tier.achieved ? '✓' : `${percent(tier.value, tier.total)}%`}`
|
||||
)
|
||||
.join(' · ')}
|
||||
</p>
|
||||
{/if}
|
||||
</a>
|
||||
<dl class="mt-4 grid gap-3">
|
||||
{#each [{ key: 'achievements', label: 'achievements', ...game.achievements }, ...game.milestones] as row (row.key)}
|
||||
<div
|
||||
class="grid grid-cols-[minmax(0,1fr)_8rem_auto] items-center gap-3 text-sm text-[var(--site-muted)]"
|
||||
>
|
||||
<dt class="truncate">{row.label}</dt>
|
||||
<div class="w-32">
|
||||
<ProgressBar value={row.value} max={row.total} label={row.label} small />
|
||||
</div>
|
||||
<dd class="min-w-12 text-right tabular-nums">{row.value}/{row.total}</dd>
|
||||
</div>
|
||||
{/each}
|
||||
</dl>
|
||||
{#if game.tiers.length}
|
||||
<p class="mt-4 text-[var(--site-muted)]">
|
||||
{game.tiers
|
||||
.map((tier) =>
|
||||
tier.scope === 'class'
|
||||
? `${tier.label} ${tier.value}/${tier.total} classes`
|
||||
: `${tier.label} ${tier.achieved ? '✓' : `${percent(tier.value, tier.total)}%`}`
|
||||
)
|
||||
.join(' · ')}
|
||||
</p>
|
||||
{/if}
|
||||
</a></Card.Content
|
||||
></Card.Root
|
||||
>
|
||||
</li>
|
||||
{:else}
|
||||
<li class="text-[var(--site-muted)]">the Call of Duty catalog has not been loaded yet.</li>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { deserialize } from '$app/forms';
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
import ProgressBar from '$lib/components/ProgressBar.svelte';
|
||||
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||
import { appliesTo, summarizeGame } from '$lib/game-tracker/mastery';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
@@ -131,19 +132,12 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center justify-between gap-4">
|
||||
<div role="tablist" class="flex gap-6 text-lg">
|
||||
{#each tabs as name (name)}
|
||||
<button
|
||||
role="tab"
|
||||
type="button"
|
||||
aria-selected={tab === name}
|
||||
onclick={() => (tab = name)}
|
||||
class={tab === name
|
||||
? 'underline underline-offset-8'
|
||||
: 'text-[var(--site-muted)] hover:text-[var(--site-text)]'}>{name}</button
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
<Tabs.Root bind:value={tab}
|
||||
><Tabs.List
|
||||
>{#each tabs as name (name)}<Tabs.Trigger value={name}>{name}</Tabs.Trigger
|
||||
>{/each}</Tabs.List
|
||||
></Tabs.Root
|
||||
>
|
||||
<label class="flex cursor-pointer items-center gap-3">
|
||||
<input type="checkbox" bind:checked={hideDone} class="h-5 w-5 accent-[var(--site-text)]" />
|
||||
hide finished
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
import type { PageProps } from './$types';
|
||||
import ProgressBar from '$lib/components/ProgressBar.svelte';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import PokemonDetails from '$lib/catch-em-all/PokemonDetails.svelte';
|
||||
import { summarizeProgress } from '$lib/catch-em-all/progress';
|
||||
|
||||
@@ -171,12 +173,7 @@
|
||||
{data.pokemon.length} Pokémon · {data.games.length} games
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onclick={openRules}
|
||||
class="rounded border border-[var(--site-border)] px-4 py-2 hover:bg-[var(--site-hover)]"
|
||||
>set rules</button
|
||||
>
|
||||
<Button variant="outline" type="button" onclick={openRules}>set rules</Button>
|
||||
</div>
|
||||
|
||||
{#if !data.user}<p class="mt-6">
|
||||
@@ -232,12 +229,12 @@
|
||||
<div class="mt-8 grid gap-4 sm:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
|
||||
<label class="block"
|
||||
>search Pokémon
|
||||
<input
|
||||
<Input
|
||||
type="search"
|
||||
bind:value={search}
|
||||
oninput={() => (pageNumber = 1)}
|
||||
placeholder="name or number"
|
||||
class="mt-2 block w-full rounded border border-[var(--site-border)] bg-[var(--site-bg)] px-3 py-3"
|
||||
class="mt-2 h-11"
|
||||
/>
|
||||
</label>
|
||||
<label class="block"
|
||||
@@ -348,18 +345,20 @@
|
||||
)} of {filteredPokemon.length}
|
||||
</p>
|
||||
<div class="flex items-center gap-4">
|
||||
<button
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
type="button"
|
||||
disabled={pageNumber === 1}
|
||||
onclick={() => (pageNumber -= 1)}
|
||||
class="disabled:opacity-40">previous</button
|
||||
onclick={() => (pageNumber -= 1)}>previous</Button
|
||||
>
|
||||
<span class="text-[var(--site-muted)]">{pageNumber}/{pageCount}</span>
|
||||
<button
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
type="button"
|
||||
disabled={pageNumber === pageCount}
|
||||
onclick={() => (pageNumber += 1)}
|
||||
class="disabled:opacity-40">next</button
|
||||
onclick={() => (pageNumber += 1)}>next</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import * as Card from '$lib/components/ui/card/index.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
@@ -33,12 +35,7 @@
|
||||
<div class="mt-8 grid gap-4 sm:grid-cols-[minmax(0,1fr)_minmax(0,16rem)]">
|
||||
<label class="block"
|
||||
>search
|
||||
<input
|
||||
type="search"
|
||||
bind:value={search}
|
||||
placeholder="route, city, cave…"
|
||||
class="mt-2 block w-full rounded border border-[var(--site-border)] bg-[var(--site-bg)] px-3 py-3"
|
||||
/>
|
||||
<Input type="search" bind:value={search} placeholder="route, city, cave…" class="mt-2 h-11" />
|
||||
</label>
|
||||
<label class="block"
|
||||
>region
|
||||
@@ -65,20 +62,24 @@
|
||||
<h2 class="text-2xl font-semibold">{name}</h2>
|
||||
<ul class="mt-3 grid gap-x-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{#each locations as location (location.id)}
|
||||
<li class="border-t border-[var(--site-border)]">
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon/locations/[id=integer]', {
|
||||
id: String(location.id)
|
||||
})}
|
||||
class="flex items-baseline justify-between gap-3 py-3 hover:text-[var(--site-muted)]"
|
||||
<li>
|
||||
<Card.Root class="transition-colors hover:bg-muted/50"
|
||||
><Card.Content class="p-0">
|
||||
<a
|
||||
href={resolve('/projects/game-tracker/pokemon/locations/[id=integer]', {
|
||||
id: String(location.id)
|
||||
})}
|
||||
class="flex items-baseline justify-between gap-3 p-4"
|
||||
>
|
||||
<span>{location.name}</span>
|
||||
<span class="shrink-0 text-sm text-[var(--site-muted)]"
|
||||
>{location.pokemon ? `${location.pokemon} Pokémon` : ''}{location.hasPicture
|
||||
? ' · picture'
|
||||
: ''}</span
|
||||
>
|
||||
</a>
|
||||
</Card.Content></Card.Root
|
||||
>
|
||||
<span>{location.name}</span>
|
||||
<span class="shrink-0 text-sm text-[var(--site-muted)]"
|
||||
>{location.pokemon ? `${location.pokemon} Pokémon` : ''}{location.hasPicture
|
||||
? ' · picture'
|
||||
: ''}</span
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import { resolve } from '$app/paths';
|
||||
import { enhance } from '$app/forms';
|
||||
import { page } from '$app/state';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
import { Textarea } from '$lib/components/ui/textarea/index.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data, form }: PageProps = $props();
|
||||
@@ -78,12 +81,13 @@
|
||||
{#if form?.message}<p role="alert" class="mt-3 text-red-500">{form.message}</p>{/if}
|
||||
<label class="mt-4 block"
|
||||
>notes
|
||||
<textarea
|
||||
<Textarea
|
||||
name="description"
|
||||
rows="4"
|
||||
maxlength="5000"
|
||||
class="mt-2 block w-full rounded border border-[var(--site-border)] bg-[var(--site-bg)] px-3 py-2"
|
||||
>{data.location.description ?? ''}</textarea
|
||||
rows={4}
|
||||
maxlength={5000}
|
||||
value={data.location.description ?? ''}
|
||||
class="mt-2"
|
||||
/>
|
||||
>
|
||||
</label>
|
||||
<div class="mt-4 grid gap-4 sm:grid-cols-2">
|
||||
@@ -98,23 +102,19 @@
|
||||
</label>
|
||||
<label class="block"
|
||||
>picture credit
|
||||
<input
|
||||
<Input
|
||||
name="imageCredit"
|
||||
value={data.location.imageCredit ?? ''}
|
||||
maxlength="300"
|
||||
maxlength={300}
|
||||
placeholder="e.g. my own screenshot"
|
||||
class="mt-2 block w-full rounded border border-[var(--site-border)] bg-[var(--site-bg)] px-3 py-2"
|
||||
class="mt-2"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
{#if data.location.imageUrl}<label class="mt-3 flex items-center gap-2"
|
||||
><input type="checkbox" name="removePicture" /> remove the current picture</label
|
||||
>{/if}
|
||||
<button
|
||||
disabled={saving}
|
||||
class="mt-5 rounded bg-[var(--site-text)] px-4 py-2 font-semibold text-[var(--site-bg)] disabled:opacity-40"
|
||||
>{saving ? 'saving…' : 'save'}</button
|
||||
>
|
||||
<Button type="submit" disabled={saving} class="mt-5">{saving ? 'saving…' : 'save'}</Button>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user