11import React from "react" ;
22import SortDropdown from "./SortDropdown" ;
3- import { TRACKED_MONSTER_IDS } from "../shared/constants" ;
3+ import { BOSS_MONSTER_IDS , MAGICAL_CREATURE_IDS } from "../shared/constants" ;
44import { formatStat } from "../shared/utils/formatters" ;
55import { getNextSpawnTime , formatTimeUntilSpawn } from "./bossSpawnTimes" ;
66import { monsterRespawnTracker } from "./monsterRespawnTracker" ;
@@ -18,8 +18,8 @@ interface MonsterEntry {
1818
1919interface MonsterListProps {
2020 monsters : Record < string , MonsterEntry > ;
21- bossOnlyMode : boolean ;
22- setBossOnlyMode : ( value : boolean | ( ( prev : boolean ) => boolean ) ) => void ;
21+ filterMode : "all" | "bosses" | "magical" ;
22+ setFilterMode : ( value : "all" | "bosses" | "magical" ) => void ;
2323 sortKey : "id" | "name" | "hp" | "distance" ;
2424 setSortKey : ( value : "id" | "name" | "hp" | "distance" ) => void ;
2525 sortDesc : boolean ;
@@ -29,35 +29,69 @@ interface MonsterListProps {
2929
3030export default function MonsterList ( {
3131 monsters,
32- bossOnlyMode ,
33- setBossOnlyMode ,
32+ filterMode ,
33+ setFilterMode ,
3434 sortKey,
3535 setSortKey,
3636 sortDesc,
3737 setSortDesc,
3838 t
3939} : MonsterListProps ) : React . JSX . Element {
40+ const getFilteredCount = ( ) => {
41+ if ( filterMode === "all" ) return Object . keys ( monsters ) . length ;
42+ if ( filterMode === "bosses" ) {
43+ return Object . values ( monsters ) . filter ( m => m . monster_id && BOSS_MONSTER_IDS . has ( String ( m . monster_id ) ) ) . length ;
44+ }
45+ if ( filterMode === "magical" ) {
46+ return Object . values ( monsters ) . filter ( m => m . monster_id && MAGICAL_CREATURE_IDS . has ( String ( m . monster_id ) ) ) . length ;
47+ }
48+ return 0 ;
49+ } ;
50+
51+ const MERGED_MONSTER_IDS = new Set ( [
52+ ...BOSS_MONSTER_IDS ,
53+ ...MAGICAL_CREATURE_IDS
54+ ] ) ;
55+
4056 return (
4157 < div className = "monsters-container" >
4258 < div className = "flex justify-between items-center mb-2 gap-2" >
4359 < div className = "flex items-center gap-2" >
4460 < div className = "text-sm font-semibold" >
45- { t ( "ui.messages.monsters" ) } ({
46- bossOnlyMode
47- ? Object . values ( monsters ) . filter ( m => m . monster_id && TRACKED_MONSTER_IDS . has ( String ( m . monster_id ) ) ) . length
48- : Object . keys ( monsters ) . length
49- } )
61+ { t ( "ui.messages.monsters" ) } ({ getFilteredCount ( ) } )
62+ </ div >
63+ < div className = "flex gap-1" >
64+ < button
65+ onClick = { ( ) => setFilterMode ( "all" ) }
66+ className = "text-xs px-2 py-1 rounded"
67+ style = { {
68+ background : filterMode === "all" ? "#3498db" : "rgba(255,255,255,0.1)" ,
69+ color : filterMode === "all" ? "#fff" : "rgba(255,255,255,0.7)"
70+ } }
71+ >
72+ { t ( "ui.buttons.allMonsters" ) }
73+ </ button >
74+ < button
75+ onClick = { ( ) => setFilterMode ( "bosses" ) }
76+ className = "text-xs px-2 py-1 rounded"
77+ style = { {
78+ background : filterMode === "bosses" ? "#e74c3c" : "rgba(255,255,255,0.1)" ,
79+ color : filterMode === "bosses" ? "#fff" : "rgba(255,255,255,0.7)"
80+ } }
81+ >
82+ { t ( "ui.buttons.bossesOnly" ) }
83+ </ button >
84+ < button
85+ onClick = { ( ) => setFilterMode ( "magical" ) }
86+ className = "text-xs px-2 py-1 rounded"
87+ style = { {
88+ background : filterMode === "magical" ? "#9b59b6" : "rgba(255,255,255,0.1)" ,
89+ color : filterMode === "magical" ? "#fff" : "rgba(255,255,255,0.7)"
90+ } }
91+ >
92+ { t ( "ui.buttons.magicalOnly" , "Magical" ) }
93+ </ button >
5094 </ div >
51- < button
52- onClick = { ( ) => setBossOnlyMode ( ( prev ) => ! prev ) }
53- className = "text-xs px-2 py-1 rounded"
54- style = { {
55- background : bossOnlyMode ? "#3498db" : "rgba(255,255,255,0.1)" ,
56- color : bossOnlyMode ? "#fff" : "rgba(255,255,255,0.7)"
57- } }
58- >
59- { bossOnlyMode ? t ( "ui.buttons.bossesOnly" ) : t ( "ui.buttons.allMonsters" ) }
60- </ button >
6195 </ div >
6296 < div className = "flex items-center gap-2" >
6397 < label className = "text-xs" > { t ( "ui.buttons.sort" ) } :</ label >
@@ -80,19 +114,25 @@ export default function MonsterList({
80114 < table className = "monsters-table w-full border-collapse" >
81115 < thead >
82116 < tr >
83- < th className = "text-left p-1" > { t ( "ui.messages.name" ) } </ th >
84- < th className = "text-center p-1" > { t ( "ui.messages.hp" ) } </ th >
85- < th className = "text-center p-1" > { t ( "ui.messages.direction" ) } </ th >
86- < th className = "text-right p-1 pl-5" > { t ( "ui.messages.distance" ) } </ th >
87- < th className = "text-center p-1 pl-5" > { t ( "ui.messages.nextSpawn" ) } </ th >
117+ < th className = "text-sm text- left p-1" > { t ( "ui.messages.name" ) } </ th >
118+ < th className = "text-sm text- center p-1" > { t ( "ui.messages.hp" ) } </ th >
119+ < th className = "text-sm text- center p-1" > { t ( "ui.messages.direction" ) } </ th >
120+ < th className = "text-sm text- right p-1 pl-5" > { t ( "ui.messages.distance" ) } </ th >
121+ < th className = "text-sm text- center p-1 pl-5" > { t ( "ui.messages.nextSpawn" ) } </ th >
88122 </ tr >
89123 </ thead >
90124 < tbody >
91125 { Object . entries ( monsters )
92126 . map ( ( [ id , m ] ) => ( { id, ...m } ) )
93127 . filter ( ( m ) => {
94- if ( ! bossOnlyMode ) return true ;
95- return m . monster_id && TRACKED_MONSTER_IDS . has ( String ( m . monster_id ) ) ;
128+ if ( filterMode === "all" ) return true ;
129+ if ( filterMode === "bosses" ) {
130+ return m . monster_id && BOSS_MONSTER_IDS . has ( String ( m . monster_id ) ) ;
131+ }
132+ if ( filterMode === "magical" ) {
133+ return m . monster_id && MAGICAL_CREATURE_IDS . has ( String ( m . monster_id ) ) ;
134+ }
135+ return true ;
96136 } )
97137 . sort ( ( a , b ) => {
98138 if ( sortKey === "hp" ) {
@@ -122,7 +162,7 @@ export default function MonsterList({
122162 : "-" ;
123163 const direction = m . direction ?? "-" ;
124164
125- let spawnInfo = m . monster_id && TRACKED_MONSTER_IDS . has ( String ( m . monster_id ) )
165+ let spawnInfo = m . monster_id && MERGED_MONSTER_IDS . has ( String ( m . monster_id ) )
126166 ? getNextSpawnTime ( String ( m . monster_id ) )
127167 : null ;
128168
0 commit comments