Game-Server/client/src/views/GameInterface/tabs/DashboardTab.jsx

155 lines
5.1 KiB
JavaScript

import React, { useEffect, useState } from "react";
import Card from "../../../components/ui/Card";
import { useSocket } from "../../../hooks/useSocket";
import playerManager from "../../../services/PlayerManager";
import "./styles/DashboardTab.css";
const DashboardTab = () => {
const { socket, isConnected } = useSocket();
const [playerData, setPlayerData] = useState(null);
const [earnedPopup, setEarnedPopup] = useState(false);
const [credits, setCredits] = useState(0);
const [onlineCount, setOnlineCount] = useState(
playerManager.onlinePlayers.length,
);
const savedUser = JSON.parse(localStorage.getItem("user"));
const localUsername = savedUser?.username || "Unknown Pilot";
useEffect(() => {
const unsubscribe = playerManager.subscribe(({ online }) => {
setOnlineCount(online.length);
});
if (!socket) return;
socket.emit("player:get_dashboard");
const handleData = (data) => {
setPlayerData(data);
setCredits(data.credits);
};
const handleCreditsUpdate = ({ totalCredits }) => {
setCredits(totalCredits);
setEarnedPopup(true);
setTimeout(() => setEarnedPopup(false), 2000);
};
const handleOfflineReport = () => {
socket.emit("player:get_dashboard");
};
socket.on("player:dashboard_data", handleData);
socket.on("player:credits_update", handleCreditsUpdate);
socket.on("player:offline_report", handleOfflineReport);
return () => {
unsubscribe();
socket.off("player:dashboard_data", handleData);
socket.off("player:credits_update", handleCreditsUpdate);
socket.off("player:offline_report", handleOfflineReport);
};
}, [socket]);
const stats = playerData || { experience: 0, level: 1 };
const nextLevelExp = 1000;
const expProgress = Math.min((stats.experience / nextLevelExp) * 100, 100);
return (
<div className="dash-container">
<div className="dash-scanline"></div>
<div className="dashboard-grid">
<Card className="dash-card pilot-card">
<div className="card-tag">ID_RECOGNITION</div>
<div className="pilot-info">
<div className="pilot-avatar">
<i className="fas fa-user-astronaut"></i>
<div className="level-badge">{stats.level}</div>
</div>
<div className="pilot-details">
<h3>{localUsername}</h3>
<p className="status-online">RANK: VETERAN</p>
</div>
</div>
<div className="exp-bar-container">
<div className="exp-labels">
<span>EXP: {stats.experience}</span>
<span>NEXT: {nextLevelExp}</span>
</div>
<div className="exp-track">
<div
className="exp-fill"
style={{ width: `${expProgress}%` }}
></div>
</div>
</div>
</Card>
<Card className="dash-card resources-card">
<div className="card-tag">FINANCIAL_DATA</div>
<h3>VALUABLES</h3>
<div className="resource-list">
<div className="res-item gold">
<i className="fas fa-coins"></i>
<div className="res-content">
<span className="res-label">CREDITS</span>
<span className="res-val">
{credits.toLocaleString()}
{earnedPopup && <span className="credit-plus">+1</span>}
</span>
</div>
</div>
<div className="res-item crystal">
<i className="fas fa-microchip"></i>
<div className="res-content">
<span className="res-label">DATA_CORES</span>
<span className="res-val">
{Math.floor(stats.experience / 10)}
</span>
</div>
</div>
</div>
</Card>
<Card className="dash-card status-card">
<div className="card-tag">SYSTEM_DIAGNOSTICS</div>
<h3>SHIPS_LOG</h3>
<div className="diag-grid">
<div className="diag-item">
<span className="diag-label">ENGINE</span>
<span className="diag-status">OPTIMAL</span>
</div>
<div className="diag-item">
<span className="diag-label">SHIELDS</span>
<span className="diag-status">100%</span>
</div>
<div className="diag-item warning">
<span className="diag-label">CARGO</span>
<span className="diag-status">NEAR_FULL</span>
</div>
<div className="diag-item">
<span className="diag-label">NET</span>
<span
className={`diag-status ${isConnected ? "online" : "offline"}`}
>
{isConnected ? (
<span className="online-info">
<span className="online-dot"></span>
LIVE: {onlineCount}
</span>
) : (
"DISCONNECTED"
)}
</span>
</div>
</div>
</Card>
</div>
</div>
);
};
export default DashboardTab;