158 lines
5.3 KiB
JavaScript
158 lines
5.3 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import GameDataManager from "../../../services/GameDataManager";
|
|
import MeteorRegion from "../../../components/Meteor/MeteorRegion.jsx";
|
|
import { config } from "../../../config/api";
|
|
import DatapackDetailsModal from "./components/DatapackDetailsModal";
|
|
import "./styles/DatapackTab.css";
|
|
|
|
const DatapackTab = () => {
|
|
const [activeSection, setActiveSection] = useState("items");
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const [displayList, setDisplayList] = useState([]);
|
|
const [selectedItem, setSelectedItem] = useState(null);
|
|
|
|
const sections = [
|
|
{ id: "items", label: "Items", icon: "fa-box" },
|
|
{ id: "hostiles", label: "Hostiles", icon: "fa-biohazard" },
|
|
{ id: "dungeons", label: "Dungeons", icon: "fa-dungeon" },
|
|
{ id: "recipes", label: "Recipes", icon: "fa-scroll" },
|
|
];
|
|
|
|
useEffect(() => {
|
|
let data = [];
|
|
switch (activeSection) {
|
|
case "items":
|
|
data = Array.from(GameDataManager.items.values()).map((i) =>
|
|
GameDataManager.getItem(i.id),
|
|
);
|
|
break;
|
|
case "hostiles":
|
|
data = Array.from(GameDataManager.hostiles.values()).map((h) =>
|
|
GameDataManager.getHostile(h.id),
|
|
);
|
|
break;
|
|
case "dungeons":
|
|
data = Array.from(GameDataManager.dungeons.values()).map((d) =>
|
|
GameDataManager.getDungeon(d.id),
|
|
);
|
|
break;
|
|
case "recipes":
|
|
data = Array.from(GameDataManager.recipes.values()).map((r) =>
|
|
GameDataManager.getRecipe(r.id),
|
|
);
|
|
break;
|
|
default:
|
|
data = [];
|
|
}
|
|
|
|
if (searchQuery) {
|
|
const query = searchQuery.toLowerCase();
|
|
data = data.filter(
|
|
(item) =>
|
|
item.displayName?.toLowerCase().includes(query) ||
|
|
item.id?.toLowerCase().includes(query),
|
|
);
|
|
}
|
|
setDisplayList(data);
|
|
}, [activeSection, searchQuery]);
|
|
|
|
return (
|
|
<div className="tab-content active datapack-tab-wrapper">
|
|
<MeteorRegion>
|
|
<div className="datapack-controls">
|
|
<div className="section-selector">
|
|
{sections.map((s) => (
|
|
<button
|
|
key={s.id}
|
|
className={`section-btn ${activeSection === s.id ? "active" : ""}`}
|
|
onClick={() => setActiveSection(s.id)}
|
|
>
|
|
<i className={`fas ${s.icon}`}></i>
|
|
<span>{s.label}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<div className="search-bar">
|
|
<i className="fas fa-search"></i>
|
|
<input
|
|
type="text"
|
|
placeholder="Search ID or Name..."
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="datapack-content">
|
|
<div className="datapack-grid">
|
|
{displayList.map((item) => (
|
|
<div
|
|
key={item.id}
|
|
className={`datapack-card ${activeSection === "hostiles" ? "hostile-card" : ""}`}
|
|
onClick={() =>
|
|
setSelectedItem({ ...item, sectionType: activeSection })
|
|
}
|
|
>
|
|
<div className="card-icon">
|
|
{item.texture ? (
|
|
<img
|
|
src={`${config.serverUrl}/static/${item.texture}`}
|
|
alt=""
|
|
/>
|
|
) : (
|
|
<div className="fallback-icon">
|
|
{item.displayName?.[0] || "?"}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="card-info">
|
|
<span className="card-name">{item.displayName}</span>
|
|
<span className="card-id">{item.id}</span>
|
|
|
|
{activeSection === "hostiles" &&
|
|
item.loot &&
|
|
item.loot.length > 0 && (
|
|
<div className="card-loot-preview">
|
|
{item.loot.map((lootEntry, idx) => {
|
|
const lootData = GameDataManager.getItem(
|
|
lootEntry.id,
|
|
);
|
|
return (
|
|
<div
|
|
key={`${item.id}-loot-${idx}`}
|
|
className="loot-mini-slot-text"
|
|
title={`${lootData?.displayName || lootEntry.id} (${(lootEntry.chance * 100).toFixed(0)}%)`}
|
|
>
|
|
<i
|
|
className="fas fa-box-open"
|
|
style={{ fontSize: "10px", marginRight: "4px" }}
|
|
></i>
|
|
<span>
|
|
{lootData?.displayName ||
|
|
lootEntry.id.split(":").pop()}
|
|
</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</MeteorRegion>
|
|
{selectedItem && (
|
|
<DatapackDetailsModal
|
|
data={selectedItem}
|
|
onClose={() => setSelectedItem(null)}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DatapackTab;
|