API/client/src/views/GameInterface/tabs/SkillsTab.jsx

116 lines
3.5 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { useSocket } from "../../../hooks/useSocket";
import GameDataManager from "../../../services/GameDataManager";
import "./styles/SkillsTab.css";
import CategorySelector from "../components/CategorySelector";
import MeteorRegion from "../../../components/Meteor/MeteorRegion.jsx";
import { SkillCard } from "./components/SkillsCard.jsx";
const SkillsTab = () => {
const { socket } = useSocket();
const [categories, setCategories] = useState([]);
const [activeCategory, setActiveCategory] = useState("");
const [skills, setSkills] = useState([]);
const [playerSkills, setPlayerSkills] = useState({});
const [skillPoints, setSkillPoints] = useState(0);
useEffect(() => {
const manifestCategories = GameDataManager.getSkillCategories();
setCategories(manifestCategories);
if (manifestCategories.length > 0) {
setActiveCategory(manifestCategories[0].id);
}
}, []);
useEffect(() => {
if (activeCategory) {
const filtered = GameDataManager.getSkillsByCategory(activeCategory);
setSkills(filtered);
}
}, [activeCategory]);
useEffect(() => {
if (!socket) return;
socket.emit("player:get_skill_points");
socket.emit("player:get_skills");
const handleSkillPoints = (data) => setSkillPoints(data.points || 0);
const handleSkillsData = (data) => setPlayerSkills(data.skills || {});
socket.on("player:skill_points_data", handleSkillPoints);
socket.on("player:skills_data", handleSkillsData);
return () => {
socket.off("player:skill_points_data", handleSkillPoints);
socket.off("player:skills_data", handleSkillsData);
};
}, [socket]);
const handleUpgrade = (skillId) => {
socket.emit("player:upgrade_skill", { skillId });
};
return (
<div
className="tab-content active"
style={{ height: "100%", display: "flex", flexDirection: "column" }}
>
<MeteorRegion className="skills-container">
<div className="skills-header">
<div className="header-main">
<h2>
<i className="fas fa-microchip"></i> Neural Core
</h2>
<div className="skill-points-badge">
<span className="label">Uplink Points:</span>
<span className="value">{skillPoints}</span>
</div>
</div>
</div>
<CategorySelector
categories={categories}
activeCategory={activeCategory}
onCategoryChange={setActiveCategory}
/>
<div className="skills-grid custom-scroll">
{skills.length > 0 ? (
skills.map((skill) => {
const progress = playerSkills[skill.id] || {
level: 0,
experience: 0,
};
const maxLv = skill.meta?.topLevel || 10;
const cost = progress.level === 0 ? 2 : 1;
return (
<SkillCard
key={skill.id}
skill={skill}
level={progress.level}
maxLevel={maxLv}
experience={progress.experience}
canAfford={skillPoints >= cost}
onUpgrade={() => handleUpgrade(skill.id)}
/>
);
})
) : (
<div className="empty-category">
<i className="fas fa-xs fa-terminal"></i>
<p>No active modules found in this sector.</p>
</div>
)}
</div>
</MeteorRegion>
</div>
);
};
export default SkillsTab;