Fix doubled encounters in encounter modals by filtering on gameId

EncounterModal and ShinyEncounterModal were calling useRoutePokemon
without a gameId, returning encounters for all games in the version
group. Now both receive and pass the run's gameId to scope results
to the current game only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 12:18:12 +01:00
parent 3e88ba50fa
commit da9cf0acd2
4 changed files with 22 additions and 3 deletions

View File

@@ -0,0 +1,11 @@
---
# nuzlocke-tracker-jrbc
title: Fix doubled encounters in EncounterModal
status: completed
type: bug
priority: normal
created_at: 2026-02-08T11:16:35Z
updated_at: 2026-02-08T11:17:25Z
---
EncounterModal calls useRoutePokemon without gameId, so route encounters for all games in the version group are returned. Pass gameId through from RunEncounters.

View File

@@ -14,6 +14,7 @@ import type {
interface EncounterModalProps { interface EncounterModalProps {
route: Route route: Route
gameId: number
existing?: EncounterDetail existing?: EncounterDetail
dupedPokemonIds?: Set<number> dupedPokemonIds?: Set<number>
onSubmit: (data: { onSubmit: (data: {
@@ -78,6 +79,7 @@ function groupByMethod(pokemon: RouteEncounterDetail[]): { method: string; pokem
export function EncounterModal({ export function EncounterModal({
route, route,
gameId,
existing, existing,
dupedPokemonIds, dupedPokemonIds,
onSubmit, onSubmit,
@@ -87,6 +89,7 @@ export function EncounterModal({
}: EncounterModalProps) { }: EncounterModalProps) {
const { data: routePokemon, isLoading: loadingPokemon } = useRoutePokemon( const { data: routePokemon, isLoading: loadingPokemon } = useRoutePokemon(
route.id, route.id,
gameId,
) )
const [selectedPokemon, setSelectedPokemon] = const [selectedPokemon, setSelectedPokemon] =
@@ -190,7 +193,7 @@ export function EncounterModal({
</label> </label>
{loadingPokemon ? ( {loadingPokemon ? (
<div className="flex items-center justify-center py-4"> <div className="flex items-center justify-center py-4">
<div className="w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" /> <div className="w-10 h-10 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
</div> </div>
) : filteredPokemon && filteredPokemon.length > 0 ? ( ) : filteredPokemon && filteredPokemon.length > 0 ? (
<> <>

View File

@@ -9,6 +9,7 @@ import type { Route, RouteEncounterDetail } from '../types'
interface ShinyEncounterModalProps { interface ShinyEncounterModalProps {
routes: Route[] routes: Route[]
gameId: number
onSubmit: (data: { onSubmit: (data: {
routeId: number routeId: number
pokemonId: number pokemonId: number
@@ -41,6 +42,7 @@ function groupByMethod(pokemon: RouteEncounterDetail[]): { method: string; pokem
export function ShinyEncounterModal({ export function ShinyEncounterModal({
routes, routes,
gameId,
onSubmit, onSubmit,
onClose, onClose,
isPending, isPending,
@@ -48,6 +50,7 @@ export function ShinyEncounterModal({
const [selectedRouteId, setSelectedRouteId] = useState<number | null>(null) const [selectedRouteId, setSelectedRouteId] = useState<number | null>(null)
const { data: routePokemon, isLoading: loadingPokemon } = useRoutePokemon( const { data: routePokemon, isLoading: loadingPokemon } = useRoutePokemon(
selectedRouteId, selectedRouteId,
gameId,
) )
const [selectedPokemon, setSelectedPokemon] = const [selectedPokemon, setSelectedPokemon] =

View File

@@ -218,7 +218,7 @@ function RouteGroup({
<img <img
src={groupEncounter.pokemon.spriteUrl} src={groupEncounter.pokemon.spriteUrl}
alt={groupEncounter.pokemon.name} alt={groupEncounter.pokemon.name}
className="w-5 h-5" className="w-10 h-10"
/> />
)} )}
<span className="text-xs text-gray-500 dark:text-gray-400 capitalize"> <span className="text-xs text-gray-500 dark:text-gray-400 capitalize">
@@ -972,7 +972,7 @@ export function RunEncounters() {
<img <img
src={encounter.pokemon.spriteUrl} src={encounter.pokemon.spriteUrl}
alt={encounter.pokemon.name} alt={encounter.pokemon.name}
className="w-5 h-5" className="w-10 h-10"
/> />
)} )}
<span className="text-xs text-gray-500 dark:text-gray-400 capitalize"> <span className="text-xs text-gray-500 dark:text-gray-400 capitalize">
@@ -1116,6 +1116,7 @@ export function RunEncounters() {
{selectedRoute && ( {selectedRoute && (
<EncounterModal <EncounterModal
route={selectedRoute} route={selectedRoute}
gameId={run!.gameId}
existing={editingEncounter ?? undefined} existing={editingEncounter ?? undefined}
dupedPokemonIds={dupedPokemonIds} dupedPokemonIds={dupedPokemonIds}
onSubmit={handleCreate} onSubmit={handleCreate}
@@ -1132,6 +1133,7 @@ export function RunEncounters() {
{showShinyModal && routes && ( {showShinyModal && routes && (
<ShinyEncounterModal <ShinyEncounterModal
routes={routes} routes={routes}
gameId={run!.gameId}
onSubmit={handleCreate} onSubmit={handleCreate}
onClose={() => setShowShinyModal(false)} onClose={() => setShowShinyModal(false)}
isPending={createEncounter.isPending} isPending={createEncounter.isPending}