mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-13 02:53:45 +00:00
feat(*): Add ability to filter by game and region
This commit is contained in:
@@ -6,7 +6,9 @@ class CombinedDataRepository {
|
||||
async findCombinedData(
|
||||
page: number = 1,
|
||||
limit: number = 20,
|
||||
enableForms: boolean = true
|
||||
enableForms: boolean = true,
|
||||
region: string = '',
|
||||
game: string = ''
|
||||
): Promise<CombinedData[]> {
|
||||
const skip = (page - 1) * limit;
|
||||
const pipeline: any[] = [
|
||||
@@ -43,6 +45,22 @@ class CombinedDataRepository {
|
||||
});
|
||||
}
|
||||
|
||||
if (region.length > 0) {
|
||||
pipeline.unshift({
|
||||
$match: {
|
||||
regionToCatchIn: region
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (game.length > 0) {
|
||||
pipeline.unshift({
|
||||
$match: {
|
||||
gamesToCatchIn: { $in: [game] }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const combinedData: CombinedData[] = await PokedexEntryModel.aggregate(pipeline).exec();
|
||||
|
||||
// Filter out entries with no catch records
|
||||
@@ -54,13 +72,28 @@ class CombinedDataRepository {
|
||||
}));
|
||||
}
|
||||
|
||||
async countCombinedData(enableForms: boolean): Promise<number> {
|
||||
async countCombinedData(enableForms: boolean, region: string, game: string): Promise<number> {
|
||||
const filter: any = {};
|
||||
|
||||
if (!enableForms) {
|
||||
filter['boxPlacement.box'] = { $ne: null };
|
||||
}
|
||||
|
||||
if (region.length > 0) {
|
||||
filter['regionToCatchIn'] = region;
|
||||
}
|
||||
|
||||
if (game.length > 0) {
|
||||
// Check if gamesToCatchIn is not already defined in filter
|
||||
if (!filter['gamesToCatchIn']) {
|
||||
filter['gamesToCatchIn'] = [];
|
||||
}
|
||||
// Add the game to the filter if it's not already included
|
||||
if (!filter['gamesToCatchIn'].includes(game)) {
|
||||
filter['gamesToCatchIn'].push(game);
|
||||
}
|
||||
}
|
||||
|
||||
return PokedexEntryModel.countDocuments(filter).exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,18 @@ export const GET = async ({ url }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1', 10);
|
||||
const limit = parseInt(url.searchParams.get('limit') || '20', 10);
|
||||
const enableForms = url.searchParams.get('enableForms') === 'true';
|
||||
const region = url.searchParams.get('region');
|
||||
const game = url.searchParams.get('game');
|
||||
|
||||
try {
|
||||
await dbConnect();
|
||||
const repo = new CombinedDataRepository();
|
||||
const combinedData = await repo.findCombinedData(page, limit, enableForms);
|
||||
const combinedData = await repo.findCombinedData(page, limit, enableForms, region, game);
|
||||
|
||||
if (combinedData.length === 0) {
|
||||
return json({ error: 'No combined data found' }, { status: 404 });
|
||||
}
|
||||
const totalCount = await repo.countCombinedData(enableForms);
|
||||
const totalCount = await repo.countCombinedData(enableForms, region, game);
|
||||
const totalPages = Math.ceil(totalCount / limit);
|
||||
|
||||
return json({ combinedData, totalPages });
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
let creatingRecords = false;
|
||||
let totalRecordsCreated = 0;
|
||||
let failedToLoad = false;
|
||||
let catchRegion = '';
|
||||
let catchGame = '';
|
||||
|
||||
let localUser: User | null;
|
||||
const unsubscribe = user.subscribe((value) => {
|
||||
@@ -39,7 +41,7 @@
|
||||
combinedData = null;
|
||||
|
||||
const response = await fetch(
|
||||
`/api/combined-data?page=${currentPage}&limit=${itemsPerPage}&enableForms=${showForms}`
|
||||
`/api/combined-data?page=${currentPage}&limit=${itemsPerPage}&enableForms=${showForms}®ion=${catchRegion}&game=${catchGame}`
|
||||
);
|
||||
const data = await response.json();
|
||||
|
||||
@@ -150,17 +152,90 @@
|
||||
<div class="flex">
|
||||
<aside class="w-64 bg-gray-800 text-white p-4 fixed h-5/6">
|
||||
<h2 class="text-2xl font-semibold mb-4">Filters</h2>
|
||||
<!-- <ul>
|
||||
<li class="mb-2"><a href="#" class="block p-2 hover:bg-gray-700 rounded">Dashboard</a></li>
|
||||
<li class="mb-2"><a href="#" class="block p-2 hover:bg-gray-700 rounded">Profile</a></li>
|
||||
<li class="mb-2"><a href="#" class="block p-2 hover:bg-gray-700 rounded">Settings</a></li>
|
||||
<li class="mb-2"><a href="#" class="block p-2 hover:bg-gray-700 rounded">Logout</a></li>
|
||||
</ul> -->
|
||||
<ul>
|
||||
<li class="mb-2">
|
||||
<button class="block p-2 hover:bg-gray-700 rounded" on:click={() => toggleForms()}
|
||||
>Toggle Forms (Currently {showForms ? 'On' : 'Off'})</button
|
||||
>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<button class="block p-2 hover:bg-gray-700 rounded" on:click={() => toggleOrigins()}
|
||||
>Toggle Origins (Currently {showOrigins ? 'On' : 'Off'})</button
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="mb-4">
|
||||
<button class="btn btn-sm" on:click={() => toggleForms()}>Toggle Forms</button>
|
||||
{showForms ? 'On' : 'Off'}
|
||||
<button class="btn btn-sm" on:click={() => toggleOrigins()}>Toggle Origins</button>
|
||||
{showOrigins ? 'On' : 'Off'}
|
||||
<label for="catchRegionSelect">Region to catch in:</label>
|
||||
<select
|
||||
id="catchRegionSelect"
|
||||
class="select select-bordered w-full max-w-xs text-black"
|
||||
bind:value={catchRegion}
|
||||
on:change={getData}
|
||||
>
|
||||
<option value="">All</option>
|
||||
<option value="Kanto">Kanto (Red, Blue, Yellow, LG: Pikachu, LG: Eevee)</option>
|
||||
<option value="Johto">Johto (Gold, Silver, Crystal, HG, SS)</option>
|
||||
<option value="Hoenn">Hoenn (Ruby, Sapphire, Emerald, OR, AS)</option>
|
||||
<option value="Sinnoh">Sinnoh (Diamond, Pearl, Platinum, BD, SP)</option>
|
||||
<option value="Unova">Unova (Black, White, Black2, White2, Dream Radar)</option>
|
||||
<option value="Kalos">Kalos (X, Y)</option>
|
||||
<option value="Alola">Alola (Sun, Moon, Moon Demo, US, UM)</option>
|
||||
<option value="Galar">Galar (Sword, Shield)</option>
|
||||
<option value="Hisui">Hisui (PLA)</option>
|
||||
<option value="Paldea">Paldea (Scarlet, Violet)</option>
|
||||
<option value="Unknown">Unknown (Home, Go)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="catchGameSelect">Game to catch in: {catchGame}</label>
|
||||
<select
|
||||
id="catchGameSelect"
|
||||
class="select select-bordered w-full max-w-xs text-black"
|
||||
bind:value={catchGame}
|
||||
on:change={getData}
|
||||
>
|
||||
<option value="">All</option>
|
||||
<option value="Red">Red (Kanto)</option>
|
||||
<option value="Blue">Blue (Kanto)</option>
|
||||
<option value="Yellow">Yellow (Kanto)</option>
|
||||
<option value="LG: Pikachu">LG: Pikachu (Kanto)</option>
|
||||
<option value="LG: Eevee">LG: Eevee (Kanto)</option>
|
||||
<option value="Gold">Gold (Johto)</option>
|
||||
<option value="Silver">Silver (Johto)</option>
|
||||
<option value="Crystal">Crystal (Johto)</option>
|
||||
<option value="HG">HG (Johto)</option>
|
||||
<option value="SS">SS (Johto)</option>
|
||||
<option value="Ruby">Ruby (Hoenn)</option>
|
||||
<option value="Sapphire">Sapphire (Hoenn)</option>
|
||||
<option value="Emerald">Emerald (Hoenn)</option>
|
||||
<option value="OR">OR (Hoenn)</option>
|
||||
<option value="AS">AS (Hoenn)</option>
|
||||
<option value="Diamond">Diamond (Sinnoh)</option>
|
||||
<option value="Pearl">Pearl (Sinnoh)</option>
|
||||
<option value="Platinum">Platinum (Sinnoh)</option>
|
||||
<option value="BD">BD (Sinnoh)</option>
|
||||
<option value="SP">SP (Sinnoh)</option>
|
||||
<option value="Black">Black (Unova)</option>
|
||||
<option value="White">White (Unova)</option>
|
||||
<option value="Black2">Black2 (Unova)</option>
|
||||
<option value="White2">White2 (Unova)</option>
|
||||
<option value="Dream Radar">Dream Radar (Unova)</option>
|
||||
<option value="X">X (Kalos)</option>
|
||||
<option value="Y">Y (Kalos)</option>
|
||||
<option value="Sun">Sun (Alola)</option>
|
||||
<option value="Moon">Moon (Alola)</option>
|
||||
<option value="Moon Demo">Moon Demo (Alola)</option>
|
||||
<option value="US">US (Alola)</option>
|
||||
<option value="UM">UM (Alola)</option>
|
||||
<option value="Sword">Sword (Galar)</option>
|
||||
<option value="Shield">Shield (Galar)</option>
|
||||
<option value="PLA">PLA (Hisui)</option>
|
||||
<option value="Scarlet">Scarlet (Paldea)</option>
|
||||
<option value="Violet">Violet (Paldea)</option>
|
||||
<option value="Home">Home (Unknown)</option>
|
||||
<option value="Go">Go (Unknown)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">Paging</h2>
|
||||
@@ -171,7 +246,7 @@
|
||||
|
||||
<main class="flex-1 p-4 ml-64">
|
||||
<div class="max-w-min mx-auto">
|
||||
{#if combinedData}
|
||||
{#if combinedData && combinedData.length > 0}
|
||||
{#each combinedData as { pokedexEntry, catchRecord }}
|
||||
<PokedexEntryCatchRecord
|
||||
{pokedexEntry}
|
||||
|
||||
Reference in New Issue
Block a user