feat(#46): Merge boxes view into my dex page

This commit is contained in:
Josh Creek
2024-07-17 22:07:07 +01:00
parent 02a2160f08
commit bfde0c49f5
5 changed files with 142 additions and 223 deletions
@@ -1,4 +1,10 @@
<script lang="ts">
import Pagination from '$lib/components/Pagination.svelte';
export let viewAsBoxes = false;
export let currentPage = 1;
export let itemsPerPage = 20;
export let totalPages = 0;
export let showForms = true;
export let showOrigins = true;
export let showShiny = false;
@@ -104,4 +110,11 @@
<option value="Go">Go (Unknown)</option>
</select>
</div>
{#if !viewAsBoxes}
<h2 class="text-2xl font-semibold mb-4">Paging</h2>
<div>
<Pagination bind:currentPage bind:itemsPerPage bind:totalPages />
</div>
{/if}
</aside>
@@ -33,7 +33,7 @@
if (catchRecord.caught || catchRecord.haveToEvolve) {
return '';
} else {
if (pokedexEntry.boxPlacementForms.column % 2 === 0) {
if (pokedexEntry[currentPlacement].column % 2 === 0) {
return 'background-color: #ffffff';
} else {
return 'background-color: #f9f9f9;';
-3
View File
@@ -151,9 +151,6 @@
<li>
<a href="/mydex"> My Dex </a>
</li>
<li>
<a href="/mydex/boxes"> My Boxes </a>
</li>
<li>
<a href="/profile"> Profile </a>
</li>
+117 -23
View File
@@ -2,14 +2,12 @@
import { onMount, onDestroy } from 'svelte';
import { user } from '$lib/stores/user.js';
import { type User } from '@supabase/auth-js';
import { type CatchRecord } from '$lib/models/CatchRecord';
import { type CombinedData } from '$lib/models/CombinedData';
import PokedexEntryCatchRecord from '$lib/components/pokedex/PokedexEntryCatchRecord.svelte';
import Pagination from '$lib/components/Pagination.svelte';
import { browser } from '$app/environment';
import type { PokedexEntry } from '$lib/models/PokedexEntry';
import PokedexSidebar from '$lib/components/pokedex/PokedexSidebar.svelte';
import PokedexViewList from '$lib/components/pokedex/PokedexViewList.svelte';
import PokedexViewBoxes from '$lib/components/pokedex/PokedexViewBoxes.svelte';
let combinedData = null as CombinedData[] | null;
let currentPage = 1 as number;
@@ -20,17 +18,19 @@
let failedToLoad = false;
let catchRegion = '';
let catchGame = '';
let localUser: User | null;
const unsubscribe = user.subscribe((value) => {
localUser = value;
});
onDestroy(unsubscribe);
let showOrigins = true;
let showForms = true;
let showShiny = false;
let drawerOpen = false;
let viewAsBoxes = false;
let currentPlacement = 'boxPlacementForms';
let boxNumbers = Array<any>;
const unsubscribe = user.subscribe((value) => {
localUser = value;
});
onDestroy(unsubscribe);
function toggleOrigins() {
showOrigins = !showOrigins;
@@ -50,26 +50,30 @@
await getData();
}
async function getData() {
async function toggleViewAsBoxes() {
viewAsBoxes = !viewAsBoxes;
await getData();
}
async function getData(setCombinedDataToNull = true) {
if (setCombinedDataToNull) {
combinedData = null;
const response = await fetch(
`/api/combined-data?page=${currentPage}&limit=${itemsPerPage}&enableForms=${showForms}&region=${catchRegion}&game=${catchGame}`
);
}
let endpoint = viewAsBoxes
? `/api/combined-data/all?enableForms=${showForms}&region=${catchRegion}&game=${catchGame}`
: `/api/combined-data?page=${currentPage}&limit=${itemsPerPage}&enableForms=${showForms}&region=${catchRegion}&game=${catchGame}`;
const response = await fetch(endpoint);
const data = await response.json();
if (data.error) {
failedToLoad = true;
return;
}
combinedData = data.combinedData;
totalPages = data.totalPages;
}
$: {
if (browser) {
currentPage, itemsPerPage, getData();
combinedData = viewAsBoxes ? data : data.combinedData;
totalPages = data.totalPages || 0;
if (viewAsBoxes) {
boxNumbers = [
...new Set(combinedData.map(({ pokedexEntry }) => pokedexEntry[currentPlacement].box))
].filter(Boolean);
}
}
@@ -97,6 +101,61 @@
}
}
async function updateCatchRecords(
boxNumber: number,
caught: boolean,
needsToEvolve: boolean,
inHome: boolean | null = null
) {
let catchRecordsToUpdate = combinedData
.filter(({ pokedexEntry }) => pokedexEntry[currentPlacement].box === boxNumber)
.map(({ catchRecord }) => {
let updatedRecord = { ...catchRecord };
if (inHome !== null) {
updatedRecord = {
...updatedRecord,
inHome
};
} else {
updatedRecord = {
...updatedRecord,
caught,
haveToEvolve: needsToEvolve
};
}
return updatedRecord;
});
await fetch('/api/catch-records', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(catchRecordsToUpdate)
}).then(async () => {
await getData(false);
});
}
async function markBoxAsNotCaught(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false);
}
async function markBoxAsCaught(boxNumber: number) {
await updateCatchRecords(boxNumber, true, false);
}
async function markBoxAsNeedsToEvolve(boxNumber: number) {
await updateCatchRecords(boxNumber, false, true);
}
async function markBoxAsInHome(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false, true);
}
async function markBoxAsNotInHome(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false, false);
}
async function getPokedexEntries() {
const response = await fetch('/api/pokedexentries');
if (!response.ok) {
@@ -156,6 +215,18 @@
await getData();
});
}
onMount(async () => {
await getData();
});
$: {
if (browser) {
currentPage, itemsPerPage, getData();
}
}
$: currentPlacement = showForms ? 'boxPlacementForms' : 'boxPlacement';
</script>
<svelte:head>
@@ -174,6 +245,24 @@
>
{drawerOpen ? 'Close Filters' : 'Open Filters'}
</label>
<button class="btn btn-primary" on:click={toggleViewAsBoxes}>
{viewAsBoxes ? 'Switch to List View' : 'Switch to Box View'}
</button>
{#if viewAsBoxes}
<PokedexViewBoxes
bind:showShiny
bind:combinedData
bind:boxNumbers
bind:currentPlacement
bind:creatingRecords
bind:failedToLoad
{markBoxAsNotCaught}
{markBoxAsCaught}
{markBoxAsNeedsToEvolve}
{markBoxAsInHome}
{markBoxAsNotInHome}
/>
{:else}
<PokedexViewList
bind:showOrigins
bind:showForms
@@ -185,10 +274,15 @@
{updateACatch}
{createCatchRecords}
/>
{/if}
</div>
<div class="drawer-side lg:relative">
<label for="my-drawer" class="drawer-overlay lg:hidden"></label>
<PokedexSidebar
bind:viewAsBoxes
bind:currentPage
bind:itemsPerPage
bind:totalPages
bind:showForms
bind:showOrigins
bind:showShiny
-185
View File
@@ -1,185 +0,0 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { user } from '$lib/stores/user.js';
import { type User } from '@supabase/auth-js';
import { type CatchRecord } from '$lib/models/CatchRecord';
import { type CombinedData } from '$lib/models/CombinedData';
import type { PokedexEntry } from '$lib/models/PokedexEntry';
import PokedexSidebar from '$lib/components/pokedex/PokedexSidebar.svelte';
import PokedexViewBoxes from '$lib/components/pokedex/PokedexViewBoxes.svelte';
let combinedData = null as CombinedData[] | null;
let failedToLoad = false;
let localUser: User | null;
const unsubscribe = user.subscribe((value) => {
localUser = value;
});
onDestroy(unsubscribe);
let showOrigins = true;
let showForms = true;
let drawerOpen = false;
let catchRegion = '';
let catchGame = '';
let creatingRecords = false;
function toggleOrigins() {
showOrigins = !showOrigins;
}
async function toggleForms() {
showForms = !showForms;
await getData();
}
let showShiny = false;
let currentPlacement = 'boxPlacementForms';
let boxNumbers = Array<any>;
async function toggleShiny() {
showShiny = !showShiny;
if (showShiny) {
showForms = false;
}
await getData();
}
async function getData(setCombinedDataToNull = true) {
if (setCombinedDataToNull) {
combinedData = null;
}
const response = await fetch(
`/api/combined-data/all?enableForms=${showForms}&region=${catchRegion}&game=${catchGame}`
);
const data = await response.json();
if (data.error) {
failedToLoad = true;
return;
}
combinedData = data;
boxNumbers = [
...new Set(combinedData.map(({ pokedexEntry }) => pokedexEntry[currentPlacement].box))
].filter(Boolean);
}
onMount(async () => {
await getData();
});
$: currentPlacement = showForms ? 'boxPlacementForms' : 'boxPlacement';
async function updateCatchRecords(
boxNumber: number,
caught: boolean,
needsToEvolve: boolean,
inHome: boolean | null = null
) {
let catchRecordsToUpdate = combinedData
.filter(({ pokedexEntry }) => pokedexEntry[currentPlacement].box === boxNumber)
.map(({ catchRecord }) => {
// Create the base object with existing properties
let updatedRecord = { ...catchRecord };
if (inHome !== null) {
updatedRecord = {
...updatedRecord,
inHome
};
} else {
updatedRecord = {
...updatedRecord,
caught,
haveToEvolve: needsToEvolve
};
}
return updatedRecord;
});
await fetch('/api/catch-records', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(catchRecordsToUpdate)
}).then(async () => {
// TODO - Notify the user that data is being updated
await getData(false);
// TODO - Remove the notification
});
}
async function markBoxAsNotCaught(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false);
}
async function markBoxAsCaught(boxNumber: number) {
await updateCatchRecords(boxNumber, true, false);
}
async function markBoxAsNeedsToEvolve(boxNumber: number) {
await updateCatchRecords(boxNumber, false, true);
}
async function markBoxAsInHome(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false, true);
}
async function markBoxAsNotInHome(boxNumber: number) {
await updateCatchRecords(boxNumber, false, false, false);
}
</script>
<svelte:head>
<title>Living Dex Tracker - My Boxes</title>
</svelte:head>
<!-- <PokemonSprite pokemonName={'Raichu'} pokedexNumber={26} form={'Alolan'} /> -->
{#if !localUser}
<p>Please <a href="/signin" class="underline text-primary hover:text-secondary">sign in</a></p>
{:else}
<div class="drawer lg:drawer-open">
<input id="my-drawer" type="checkbox" class="drawer-toggle" bind:checked={drawerOpen} />
<div class="drawer-content flex flex-col items-center justify-center md:ml-64">
<label
for="my-drawer"
class="btn btn-secondary drawer-button lg:hidden fixed -left-10 top-1/2 -rotate-90"
>
{drawerOpen ? 'Close Filters' : 'Open Filters'}
</label>
<PokedexViewBoxes
bind:showShiny
bind:combinedData
bind:boxNumbers
bind:currentPlacement
bind:creatingRecords
bind:failedToLoad
{markBoxAsNotCaught}
{markBoxAsCaught}
{markBoxAsNeedsToEvolve}
{markBoxAsInHome}
{markBoxAsNotInHome}
/>
</div>
<div class="drawer-side lg:relative">
<label for="my-drawer" class="drawer-overlay lg:hidden"></label>
<PokedexSidebar
bind:showForms
bind:showOrigins
bind:showShiny
bind:catchRegion
bind:catchGame
{getData}
{toggleForms}
{toggleOrigins}
{toggleShiny}
/>
</div>
</div>
{/if}