data(*): Add final data changes

This commit is contained in:
Josh Creek
2026-01-17 23:30:40 +00:00
parent 479b3ae7a0
commit 46351c9af0
29 changed files with 12187 additions and 122 deletions
+4 -2
View File
@@ -71,11 +71,12 @@
<!-- Email Input -->
<div class="form-control">
<label class="label">
<label class="label" for="signin-email">
<span class="label-text font-medium">Email</span>
</label>
<div class="relative">
<input
id="signin-email"
type="email"
placeholder="your@email.com"
class="input input-bordered w-full pl-10"
@@ -101,11 +102,12 @@
<!-- Password Input -->
<div class="form-control">
<label class="label">
<label class="label" for="signin-password">
<span class="label-text font-medium">Password</span>
</label>
<div class="relative">
<input
id="signin-password"
type="password"
placeholder="••••••••"
class="input input-bordered w-full pl-10"
+4 -2
View File
@@ -38,10 +38,11 @@
<form class="card-body">
<div class="form-control">
<label class="label">
<label class="label" for="signup-email">
<span class="label-text">Email</span>
</label>
<input
id="signup-email"
type="email"
placeholder="email"
class="input input-bordered"
@@ -50,10 +51,11 @@
/>
</div>
<div class="form-control">
<label class="label">
<label class="label" for="signup-password">
<span class="label-text">Password</span>
</label>
<input
id="signup-password"
type="password"
placeholder="password"
class="input input-bordered"
+5 -3
View File
@@ -7,14 +7,16 @@
</script>
<div class="relative inline-block">
<div
class="tooltip-trigger cursor-pointer"
<button
type="button"
class="tooltip-trigger cursor-pointer bg-transparent border-0 p-0 appearance-none"
aria-expanded={show}
on:click={handleClick}
on:mouseenter={() => (show = true)}
on:mouseleave={() => (show = false)}
>
<slot name="hover-target" />
</div>
</button>
{#if show}
<div class="tooltip-content absolute z-10 mt-2 w-52">
@@ -36,6 +36,12 @@
<span class="font-semibold">Game:</span>
{pokedex.gameScope}
</div>
{#if pokedex.dexScopes?.length}
<div class="text-sm text-base-content/70">
<span class="font-semibold">Dexes:</span>
{pokedex.dexScopes.length}
</div>
{/if}
{:else}
<div class="text-sm text-base-content/70">
<span class="font-semibold">Scope:</span> All Games
@@ -1,6 +1,6 @@
<script lang="ts">
import type { CatchRecord } from '$lib/models/CatchRecord';
import type { PokedexEntry } from '$lib/models/PokedexEntry';
import type { CatchInformationItem, PokedexEntry } from '$lib/models/PokedexEntry';
import PokemonSprite from '../PokemonSprite.svelte';
import { createEventDispatcher } from 'svelte';
@@ -31,6 +31,10 @@
type UpdateCatchSource = 'toggle' | 'notes' | 'notes-blur';
const isCatchInformationItem = (
value: string | CatchInformationItem
): value is CatchInformationItem => typeof value !== 'string';
function updateCatchRecord(source: UpdateCatchSource) {
dispatch('updateCatch', { pokedexEntry, catchRecord, source });
}
@@ -193,11 +197,15 @@
<ul class="list-disc list-inside">
{#each pokedexEntry.catchInformation as info}
<li>
<ul>
<li><strong>Game:</strong> {info.game}</li>
<li><strong>Location:</strong> {info.location}</li>
<li><strong>Notes:</strong> {info.notes}</li>
</ul>
{#if isCatchInformationItem(info)}
<ul>
<li><strong>Game:</strong> {info.game}</li>
<li><strong>Location:</strong> {info.location}</li>
<li><strong>Notes:</strong> {info.notes}</li>
</ul>
{:else}
{info}
{/if}
</li>
{/each}
</ul>
+122 -39
View File
@@ -9,36 +9,83 @@
isShinyDex: false,
isOriginDex: false,
isFormDex: false,
gameScope: null
gameScope: null,
dexScopes: []
};
export let mode: 'create' | 'edit' = 'create';
export let onSubmit: () => void;
export let onCancel: () => void;
let games: string[] = [];
let loadingGames = true;
type GameDex = {
id: string;
displayName: string;
sortOrder: number;
isDlc: boolean;
parentDexId: string | null;
};
type GameSummary = {
displayName: string;
releaseYear: number;
};
// Fetch available games from the database
let gameDexes: Record<string, GameDex[]> = {};
let gameOrder: string[] = [];
let gameList: GameSummary[] = [];
let availableDexes: GameDex[] = [];
let loadingDexes = true;
let lastGameScope: string | null = null;
let dexScopesInitialized = false;
let hasSeenGameScope = false;
// Fetch available game dexes from the database
onMount(async () => {
try {
const response = await fetch('/api/games');
const response = await fetch('/api/game-dexes');
if (response.ok) {
const data = await response.json();
games = data.games || [];
gameDexes = data.gameDexes || {};
gameOrder = data.gameOrder || Object.keys(gameDexes);
gameList = data.games || [];
} else {
console.error('Failed to fetch games');
console.error('Failed to fetch game dexes');
}
} catch (error) {
console.error('Error fetching games:', error);
console.error('Error fetching game dexes:', error);
} finally {
loadingGames = false;
loadingDexes = false;
}
});
// Validation
$: hasAtLeastOneType =
pokedex.isLivingDex || pokedex.isShinyDex || pokedex.isOriginDex || pokedex.isFormDex;
$: canSubmit = pokedex.name && pokedex.name.trim() !== '' && hasAtLeastOneType;
$: hasDexScope =
!pokedex.gameScope || (pokedex.dexScopes && pokedex.dexScopes.length > 0);
$: canSubmit =
pokedex.name && pokedex.name.trim() !== '' && hasAtLeastOneType && hasDexScope;
$: if (pokedex.gameScope !== lastGameScope) {
const shouldResetDexes = mode === 'create' || hasSeenGameScope;
lastGameScope = pokedex.gameScope || null;
dexScopesInitialized = false;
if (shouldResetDexes) {
pokedex.dexScopes = [];
}
if (!pokedex.gameScope) {
availableDexes = [];
}
hasSeenGameScope = true;
}
$: if (!loadingDexes && pokedex.gameScope) {
availableDexes = gameDexes[pokedex.gameScope] || [];
if (!dexScopesInitialized) {
if (!pokedex.dexScopes || pokedex.dexScopes.length === 0) {
pokedex.dexScopes = availableDexes.map((dex) => dex.id);
}
dexScopesInitialized = true;
}
}
function handleSubmit() {
if (canSubmit) {
@@ -74,30 +121,32 @@
</div>
<div class="form-control w-full">
<label class="label">
<span class="label-text">Type(s)</span>
<span class="label-text-alt text-error"
>{!hasAtLeastOneType ? 'At least one type required' : ''}</span
>
</label>
<div class="flex flex-col gap-2">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isLivingDex} />
<span class="label-text">Living Dex (one of each Pokémon)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isShinyDex} />
<span class="label-text">Shiny Dex (shiny variants only)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isOriginDex} />
<span class="label-text">Origin Dex (caught in native regions)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isFormDex} />
<span class="label-text">Form Dex (all forms included)</span>
</label>
</div>
<fieldset class="w-full">
<legend class="label">
<span class="label-text">Type(s)</span>
<span class="label-text-alt text-error"
>{!hasAtLeastOneType ? 'At least one type required' : ''}</span
>
</legend>
<div class="flex flex-col gap-2">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isLivingDex} />
<span class="label-text">Living Dex (one of each Pokémon)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isShinyDex} />
<span class="label-text">Shiny Dex (shiny variants only)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isOriginDex} />
<span class="label-text">Origin Dex (caught in native regions)</span>
</label>
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" bind:checked={pokedex.isFormDex} />
<span class="label-text">Form Dex (all forms included)</span>
</label>
</div>
</fieldset>
</div>
<div class="form-control w-full">
@@ -108,19 +157,53 @@
id="game-scope"
class="select select-bordered"
bind:value={pokedex.gameScope}
disabled={loadingGames}
disabled={loadingDexes}
>
<option value={null}>All Games</option>
{#if loadingGames}
{#if loadingDexes}
<option disabled>Loading games...</option>
{:else}
{#each games as game}
<option value={game}>{game}</option>
{/each}
{#if gameList.length > 0}
{#each gameList as game}
<option value={game.displayName}>{game.displayName}</option>
{/each}
{:else}
{#each gameOrder.length > 0 ? gameOrder : Object.keys(gameDexes) as game}
<option value={game}>{game}</option>
{/each}
{/if}
{/if}
</select>
</div>
{#if pokedex.gameScope}
<div class="form-control w-full">
<fieldset class="w-full">
<legend class="label">
<span class="label-text">Dex Scope</span>
<span class="label-text-alt text-error">{!hasDexScope ? 'Select at least one dex' : ''}</span>
</legend>
{#if availableDexes.length === 0}
<p class="text-sm text-error">No dexes found for this game.</p>
{:else}
<div class="flex flex-col gap-2">
{#each availableDexes as dex}
<label class="label cursor-pointer justify-start gap-3">
<input
type="checkbox"
class="checkbox"
value={dex.id}
bind:group={pokedex.dexScopes}
/>
<span class="label-text">{dex.displayName}</span>
</label>
{/each}
</div>
{/if}
</fieldset>
</div>
{/if}
<div class="modal-action">
<button class="btn btn-ghost" type="button" on:click={onCancel}>Cancel</button>
<button class="btn btn-primary" type="button" on:click={handleSubmit} disabled={!canSubmit}>
@@ -31,11 +31,12 @@
<slot />
</div>
</div>
<div
<button
type="button"
class="modal-backdrop bg-black/50"
aria-label="Close modal"
on:click={handleBackdropClick}
on:keydown={() => {}}
></div>
></button>
</div>
{/if}
@@ -46,6 +47,8 @@
left: 0;
width: 100%;
height: 100%;
border: 0;
padding: 0;
}
.modal-box-custom {
@@ -353,7 +353,7 @@
<div class="mb-8">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4 relative z-20">
<h2 class="text-xl font-bold">Box {boxNumber}</h2>
<div class="relative" on:click|stopPropagation>
<div class="relative">
<button
type="button"
class="btn btn-sm btn-outline relative z-[210]"
@@ -376,12 +376,11 @@
<ul
id={bulkMenuId}
class="menu bg-base-100 rounded-box absolute right-0 mt-2 z-[220] w-56 p-2 shadow border border-base-300"
on:click|stopPropagation
>
<li>
<button
type="button"
on:click={() => {
on:click|stopPropagation={() => {
markBoxAsNotCaught(boxNumber);
openBulkMenuForBox = null;
}}
@@ -392,7 +391,7 @@
<li>
<button
type="button"
on:click={() => {
on:click|stopPropagation={() => {
markBoxAsCaught(boxNumber);
openBulkMenuForBox = null;
}}
@@ -403,7 +402,7 @@
<li>
<button
type="button"
on:click={() => {
on:click|stopPropagation={() => {
markBoxAsNeedsToEvolve(boxNumber);
openBulkMenuForBox = null;
}}
@@ -414,7 +413,7 @@
<li>
<button
type="button"
on:click={() => {
on:click|stopPropagation={() => {
markBoxAsInHome(boxNumber);
openBulkMenuForBox = null;
}}
@@ -425,7 +424,7 @@
<li>
<button
type="button"
on:click={() => {
on:click|stopPropagation={() => {
markBoxAsNotInHome(boxNumber);
openBulkMenuForBox = null;
}}