145 lines
5.3 KiB
JavaScript
145 lines
5.3 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import GameDataManager from "../../../services/GameDataManager.js";
|
|
import "./styles/DungeonsTab.css";
|
|
|
|
const DungeonsTab = ({ startDungeon }) => {
|
|
const [dungeons, setDungeons] = useState([]);
|
|
const [selectedDungeon, setSelectedDungeon] = useState(null);
|
|
const [showSelector, setShowSelector] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const allKeys = Array.from(GameDataManager.dungeons.keys());
|
|
const uniqueDungeons = Array.from(new Set(allKeys))
|
|
.map((id) => GameDataManager.getDungeon(id))
|
|
.filter(
|
|
(d, index, self) => d && self.findIndex((t) => t.id === d.id) === index,
|
|
);
|
|
|
|
setDungeons(uniqueDungeons);
|
|
if (uniqueDungeons.length > 0 && !selectedDungeon) {
|
|
setSelectedDungeon(uniqueDungeons[0]);
|
|
}
|
|
}, []);
|
|
|
|
const handleSelectDungeon = (id) => {
|
|
const translatedDungeon = GameDataManager.getDungeon(id);
|
|
setSelectedDungeon(translatedDungeon);
|
|
if (window.innerWidth <= 768) {
|
|
setShowSelector(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="tab-content active" id="dungeons-tab">
|
|
<div
|
|
className={`dungeons-container ${!showSelector ? "view-active" : ""}`}
|
|
>
|
|
<div className="dungeon-selector">
|
|
<div className="selector-header">
|
|
<h2 className="terminal-text">AVAILABLE_MISSIONS</h2>
|
|
<div className="header-line-decor"></div>
|
|
</div>
|
|
|
|
<div className="dungeon-list custom-scroll">
|
|
{dungeons.map((dungeon) => (
|
|
<div
|
|
key={dungeon.id}
|
|
className={`dungeon-summary-card ${selectedDungeon?.id === dungeon.id ? "active" : ""}`}
|
|
onClick={() => handleSelectDungeon(dungeon.id)}
|
|
>
|
|
<div className="card-selection-indicator"></div>
|
|
<div className="dungeon-brief">
|
|
<span className="name">{dungeon.displayName}</span>
|
|
<span className="energy-cost">{dungeon.energyCost} EN</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="dungeon-view">
|
|
{selectedDungeon ? (
|
|
<div className="dungeon-details-v2">
|
|
<div className="details-header-scan">
|
|
<button
|
|
className="back-to-list"
|
|
onClick={() => setShowSelector(true)}
|
|
>
|
|
<i className="fas fa-arrow-left"></i>
|
|
</button>
|
|
<div className="mission-info-group">
|
|
<div className="mission-type-label">MISSION_BRIEFING</div>
|
|
<h3 className="mission-title">
|
|
{selectedDungeon.displayName}
|
|
</h3>
|
|
</div>
|
|
<div className="scanline-horizontal"></div>
|
|
</div>
|
|
|
|
<div className="details-body custom-scroll">
|
|
<div className="description-box">
|
|
<p className="description-text">
|
|
{selectedDungeon.description ||
|
|
"No tactical briefing available for this sector."}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="expected-rewards-section">
|
|
<div className="section-header">
|
|
<i className="fas fa-microchip"></i>
|
|
<h4>EXPECTED_REWARDS:</h4>
|
|
</div>
|
|
|
|
<div className="rewards-grid">
|
|
{selectedDungeon.lootTable?.map((loot, idx) => {
|
|
const item = GameDataManager.getItem(loot.itemId);
|
|
const rarity = item?.meta?.rarity || "common";
|
|
|
|
return (
|
|
<div key={idx} className={`reward-entry ${rarity}`}>
|
|
<div className="reward-icon-container">
|
|
{item?.texture ? (
|
|
<img src={item.texture} alt={item.displayName} />
|
|
) : (
|
|
<i className="fas fa-box-open"></i>
|
|
)}
|
|
</div>
|
|
<div className="reward-text">
|
|
<span className="reward-name">
|
|
{item?.displayName || loot.itemId}
|
|
</span>
|
|
<span className="reward-chance">
|
|
{loot.chance}% ACQUISITION
|
|
</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="action-area">
|
|
<button
|
|
className="initiate-deployment-btn"
|
|
onClick={() => startDungeon(selectedDungeon.id)}
|
|
>
|
|
<span className="glitch-text">INITIATE_DEPLOYMENT</span>
|
|
<i className="fas fa-chevron-right"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="dungeon-placeholder">
|
|
<div className="radar-scanner"></div>
|
|
<p className="blink-text">WAITING_FOR_COORDINATES...</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DungeonsTab;
|