153 lines
4.5 KiB
JavaScript
153 lines
4.5 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import axios from "axios";
|
|
import Button from "../../../components/ui/Button";
|
|
import "./ServerSection.css";
|
|
|
|
const ServerSection = ({ onBack, onSelect }) => {
|
|
const [servers, setServers] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [joiningId, setJoiningId] = useState(null);
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
|
|
const fetchServers = async () => {
|
|
setLoading(true);
|
|
const startTime = Date.now();
|
|
const API_URL = import.meta.env.VITE_API_URL;
|
|
try {
|
|
const response = await axios.get(`${API_URL}/api/servers/list`);
|
|
|
|
const elapsedTime = Date.now() - startTime;
|
|
const remainingTime = Math.max(0, 2000 - elapsedTime);
|
|
await new Promise((resolve) => setTimeout(resolve, remainingTime));
|
|
setServers(response.data);
|
|
} catch (error) {
|
|
console.error("Error fetching servers:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleJoinServer = async (server) => {
|
|
setJoiningId(server._id);
|
|
const API_URL = import.meta.env.VITE_API_URL;
|
|
try {
|
|
const token = JSON.parse(localStorage.getItem("user")).token;
|
|
|
|
const response = await axios.post(
|
|
`${API_URL}/api/servers/join`,
|
|
|
|
{ serverId: server._id },
|
|
|
|
{ headers: { Authorization: `Bearer ${token}` } },
|
|
);
|
|
|
|
if (response.data.success) {
|
|
console.log(response.data);
|
|
|
|
onSelect(response.data);
|
|
}
|
|
} catch (error) {
|
|
console.error("Join request failed:", error);
|
|
} finally {
|
|
setJoiningId(null);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchServers();
|
|
}, []);
|
|
|
|
const filteredServers = servers.filter((server) =>
|
|
searchTerm.length > 0
|
|
? server.name?.toLowerCase().includes(searchTerm.toLowerCase())
|
|
: true,
|
|
);
|
|
|
|
return (
|
|
<div id="serverSection" className="menu-section">
|
|
<h2 className="server-section-title">Galaxy Browser</h2>
|
|
|
|
<div className="server-controls">
|
|
<div className="search-wrapper">
|
|
<i className="fas fa-search search-icon"></i>
|
|
<input
|
|
type="text"
|
|
className="server-search-input"
|
|
placeholder="Search sector..."
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="control-group">
|
|
<Button
|
|
variant="secondary"
|
|
icon="fa-sync"
|
|
onClick={fetchServers}
|
|
disabled={loading}
|
|
>
|
|
{loading ? "Scanning..." : "Refresh"}
|
|
</Button>
|
|
|
|
<div className="server-filters">
|
|
<select className="filter-select">
|
|
<option value="">All Regions</option>
|
|
<option value="europe">Europe</option>
|
|
<option value="ukraine">Ukraine</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="server-list">
|
|
{loading ? (
|
|
<div className="server-loading">
|
|
<i className="fas fa-spinner fa-spin"></i>
|
|
<p>Synchronizing with Star-Net...</p>
|
|
</div>
|
|
) : filteredServers.length > 0 ? (
|
|
filteredServers.map((server) => (
|
|
<div key={server._id || server.serverName} className="server-card">
|
|
<div className="server-info">
|
|
<div
|
|
className={`status-indicator ${server.status === "online" ? "online" : "offline"}`}
|
|
></div>
|
|
<div className="server-details-text">
|
|
<span className="server-name">{server.name}</span>
|
|
<span className="server-players">
|
|
{server.playersOnline || 0} / {server.maxPlayers || 100}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
variant="primary"
|
|
size="small"
|
|
onClick={() => handleJoinServer(server)}
|
|
>
|
|
SELECT
|
|
</Button>
|
|
</div>
|
|
))
|
|
) : (
|
|
<div className="server-empty">
|
|
<i className="fas fa-satellite-dish"></i>
|
|
<p>
|
|
{searchTerm
|
|
? "No sectors match your search."
|
|
: "No active universes found."}
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="server-actions">
|
|
<Button variant="secondary" icon="fa-arrow-left" onClick={onBack}>
|
|
Back to Login
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ServerSection;
|