mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-13 11:03:44 +00:00
feat(*): Add support for catch records to My Dex page
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { dbConnect, dbDisconnect } from '$lib/utils/db';
|
||||
import { type CatchRecord } from '$lib/models/CatchRecord';
|
||||
import CatchRecordRepository from '$lib/repositories/CatchRecordRepository';
|
||||
|
||||
export const GET = async () => {
|
||||
let catchData = null as CatchRecord[] | null;
|
||||
|
||||
try {
|
||||
await dbConnect();
|
||||
const repo = new CatchRecordRepository();
|
||||
catchData = await repo.findAll();
|
||||
// order by pokedexEntryId property, ascending
|
||||
catchData = catchData.sort((a, b) => a.pokedexEntryId - b.pokedexEntryId);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
dbDisconnect();
|
||||
}
|
||||
|
||||
return json(catchData);
|
||||
};
|
||||
|
||||
export const PUT = async ({ request }) => {
|
||||
try {
|
||||
const data: Partial<CatchRecord> = await request.json();
|
||||
await dbConnect();
|
||||
const repo = new CatchRecordRepository();
|
||||
const upsertedRecord = await repo.upsert(data);
|
||||
return json(upsertedRecord);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw error(500, 'Internal Server Error');
|
||||
} finally {
|
||||
await dbDisconnect();
|
||||
}
|
||||
};
|
||||
|
||||
export const POST = async ({ request }) => {
|
||||
try {
|
||||
const records: Partial<CatchRecord>[] = await request.json();
|
||||
await dbConnect();
|
||||
const repo = new CatchRecordRepository();
|
||||
|
||||
const insertedRecords = [];
|
||||
for (const record of records) {
|
||||
const upsertedRecord = await repo.upsert(record);
|
||||
insertedRecords.push(upsertedRecord);
|
||||
}
|
||||
|
||||
return json(insertedRecords);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw error(500, 'Internal Server Error');
|
||||
} finally {
|
||||
await dbDisconnect();
|
||||
}
|
||||
};
|
||||
+171
-31
@@ -1,49 +1,189 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { user } from '$lib/stores/user.js';
|
||||
import { type User } from '@supabase/auth-js';
|
||||
import mongoose, { Types } from 'mongoose';
|
||||
import { type PokedexEntry } from '$lib/models/PokedexEntry';
|
||||
import PokemonSprite from '$lib/components/PokemonSprite.svelte';
|
||||
import CatchRecordModel, { type CatchRecord } from '$lib/models/CatchRecord';
|
||||
import { type CombinedData } from '$lib/models/CombinedData';
|
||||
import PokedexEntryCatchRecord from '$lib/components/pokedex/PokedexEntryCatchRecord.svelte';
|
||||
|
||||
let pokemonData = null as PokedexEntry[] | null;
|
||||
let localUser: User | null;
|
||||
const unsubscribe = user.subscribe((value) => {
|
||||
localUser = value;
|
||||
});
|
||||
onDestroy(unsubscribe);
|
||||
|
||||
let pokedexEntries = null as PokedexEntry[] | null;
|
||||
let catchRecords = null as CatchRecord[] | null;
|
||||
let combinedData = null as CombinedData[] | null;
|
||||
|
||||
let creatingRecords = false;
|
||||
let totalRecordsCreated = 0;
|
||||
|
||||
async function fetchPokeDexEntries() {
|
||||
console.log('Fetching updated Pokedex entry data');
|
||||
const response = await fetch('/api/pokedexentries');
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch Pokémon data');
|
||||
}
|
||||
|
||||
pokemonData = await response.json();
|
||||
pokedexEntries = await response.json();
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const cachedData = localStorage.getItem('pokeDexEntries');
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
pokemonData = JSON.parse(cachedData);
|
||||
} else {
|
||||
await fetchPokeDexEntries();
|
||||
// Cache data in local storage
|
||||
localStorage.setItem('pokeDexEntries', JSON.stringify(pokemonData));
|
||||
async function fetchCatchRecords() {
|
||||
console.log('Fetching catch record data');
|
||||
const response = await fetch('/api/catch-records');
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch catch record data');
|
||||
}
|
||||
|
||||
catchRecords = await response.json();
|
||||
|
||||
// If there are no catch records, make one for each pokedex entry
|
||||
if (catchRecords?.length === 0 && localUser?.id) {
|
||||
creatingRecords = true;
|
||||
const newCatchRecords = pokedexEntries.map((entry) => ({
|
||||
userId: localUser?.id,
|
||||
pokedexEntryId: entry._id,
|
||||
haveToEvolve: false,
|
||||
caught: false,
|
||||
inHome: false,
|
||||
hasGigantamaxed: false,
|
||||
personalNotes: ''
|
||||
}));
|
||||
|
||||
const batchSize = 500;
|
||||
for (let i = 0; i < newCatchRecords.length; i += batchSize) {
|
||||
const batch = newCatchRecords.slice(i, i + batchSize);
|
||||
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(batch)
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/catch-records', requestOptions);
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to create catch records');
|
||||
}
|
||||
|
||||
const createdRecords = await response.json();
|
||||
totalRecordsCreated += createdRecords.length;
|
||||
console.log(`Created ${createdRecords.length} catch records`);
|
||||
} catch (error) {
|
||||
console.error('Error creating catch records:', error);
|
||||
}
|
||||
}
|
||||
|
||||
await fetchCatchRecords();
|
||||
console.log('Created catch records for each pokedex entry');
|
||||
creatingRecords = false;
|
||||
}
|
||||
}
|
||||
|
||||
const fetchLastModifiedDate = async () => {
|
||||
const response = await fetch('/api/pokedex-metadata');
|
||||
const { lastModified } = await response.json();
|
||||
return new Date(lastModified);
|
||||
};
|
||||
|
||||
const cacheData = () => {
|
||||
localStorage.setItem('pokeDexEntries', JSON.stringify(pokedexEntries));
|
||||
localStorage.setItem('pokeDexLastUpdated', new Date().toISOString());
|
||||
};
|
||||
|
||||
const checkForUpdates = async () => {
|
||||
const cachedData = localStorage.getItem('pokeDexEntries');
|
||||
const cachedDate = localStorage.getItem('pokeDexLastUpdated');
|
||||
|
||||
if (cachedData && cachedDate) {
|
||||
const lastModified = await fetchLastModifiedDate();
|
||||
const lastUpdated = new Date(cachedDate);
|
||||
|
||||
if (lastModified <= lastUpdated) {
|
||||
pokedexEntries = JSON.parse(cachedData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await fetchPokeDexEntries();
|
||||
cacheData();
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
await checkForUpdates()
|
||||
.then(async () => {
|
||||
await fetchCatchRecords();
|
||||
})
|
||||
.then(async () => {
|
||||
combinedData = [];
|
||||
|
||||
// Combine pokedex entries with their corresponding catch records
|
||||
pokedexEntries.forEach((entry) => {
|
||||
let catchRecord = catchRecords.find((record) => record.pokedexEntryId === entry._id);
|
||||
if (catchRecord) {
|
||||
combinedData.push({ pokedexEntry: entry, catchRecord });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function updateACatch(catchRecord: CatchRecord) {
|
||||
alert('here');
|
||||
// if (!localUser?.id) {
|
||||
// alert('User not signed in');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const requestOptions = {
|
||||
// method: 'PUT',
|
||||
// headers: { 'Content-Type': 'application/json' },
|
||||
// body: JSON.stringify(catchRecord)
|
||||
// };
|
||||
|
||||
// try {
|
||||
// const response = await fetch('/api/catch-records', requestOptions);
|
||||
// if (!response.ok) {
|
||||
// throw new Error('Failed to update catch record');
|
||||
// }
|
||||
|
||||
// const updatedRecord = await response.json();
|
||||
// console.log('Updated catch record:', updatedRecord);
|
||||
// } catch (error) {
|
||||
// console.error('Error updating catch record:', error);
|
||||
// }
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if pokemonData}
|
||||
{#each pokemonData as pokemon}
|
||||
<div class="container mx-auto">
|
||||
{#if combinedData}
|
||||
<div>
|
||||
<PokemonSprite
|
||||
pokedexNumber={pokemon.pokedexNumber.toString().padStart(3, '0')}
|
||||
form={pokemon.form
|
||||
.replace(/[^a-zA-Z ]/g, '')
|
||||
.trim()
|
||||
.replace(/ /g, '-')}
|
||||
/>
|
||||
<p>
|
||||
{pokemon.pokedexNumber.toString().padStart(3, '0')}
|
||||
{pokemon.pokemon}
|
||||
{pokemon.form}
|
||||
</p>
|
||||
<button>Toggle Forms</button>
|
||||
<button>Toggle Origins</button>
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<span class="loading loading-spinner loading-xl"></span>
|
||||
{/if}
|
||||
|
||||
<!-- <p>
|
||||
<button on:click={() => updateACatch(catchRecord)}>Save</button>
|
||||
</p> -->
|
||||
{#each combinedData as { pokedexEntry, catchRecord }}
|
||||
<div>
|
||||
<PokedexEntryCatchRecord
|
||||
{pokedexEntry}
|
||||
bind:catchRecord
|
||||
on:updateCatch={() => updateACatch(catchRecord)}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<span class="loading loading-spinner loading-xl"></span>
|
||||
<h1>Loading Pokédex</h1>
|
||||
<p>Please be patient, this can take some time on the first load.</p>
|
||||
{#if totalRecordsCreated > 0}
|
||||
<p>Processing {totalRecordsCreated}/{pokedexEntries?.length}</p>
|
||||
{:else if creatingRecords}
|
||||
<p>Processing...</p>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user