Client/client/src/views/GameInterface/tabs/DungeonsTab.jsx
2026-04-18 15:30:52 +03:00

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;