MCPanel/app/templates/dashboard.html

273 lines
11 KiB
HTML

{% extends "layout.html" %}
{% block content %}
<h2>Twój serwer Minecraft</h2>
<div class="tabs">
<button class="tab-button" onclick="showTab('controls')">Sterowanie 🎛️</button>
<button class="tab-button" onclick="showTab('console')">Konsola 📟</button>
<button class="tab-button" onclick="showTab('files')">Pliki 📁</button>
</div>
<div class="tabs">
<button class="tab-button" onclick="showTab('config')">Konfiguracja 🛠️</button>
<button class="tab-button" onclick="showTab('statistics')">Statystyki 📈</button>
<button class="tab-button" onclick="showTab('mods')">Mody/Pluginy 🧩</button>
</div>
<div class="tab-content">
<div class="tab-panel active" id="controls">
<div style="margin-bottom: 20px;">
<p><strong>IP:</strong> {{ ip }}</p>
<p><strong>Port (Serwer MC):</strong> {{ ports[0] }}</p>
<p><strong>Dodatkowe porty:</strong> {{ ports[1:] | join(", ") }}</p>
</div>
<p><strong>Status serwera:</strong> <span id="server-status">Sprawdzanie...</span></p><br>
<button class="btn btn-success" onclick="sendAction('start')">Start</button>
<button class="btn btn-warning" onclick="sendAction('restart')">Restart</button>
<button class="btn btn-danger" onclick="sendAction('stop')">Stop</button><br>
<button class="btn btn-danger" onclick="deleteServer()">Usuń Serwer</button>
</div>
<div class="tab-panel" id="console">
<div class="console-output" id="console-log">Ładowanie logów...</div>
<div class="console-input">
<input type="text" id="console-command" placeholder="Wpisz komendę..." onkeydown="if(event.key==='Enter') sendCommand()">
<button onclick="sendCommand()">Wyślij</button>
</div>
</div>
<div class="tab-panel" id="files">
<h4 id="current-path">/</h4>
<div id="drop-zone">
<p>Przeciągnij pliki tutaj lub kliknij, aby przesłać</p>
<input type="file" id="file-input" multiple style="display: none;">
<div id="upload-progress" class="hidden">
<div id="progress-bar"></div>
</div>
</div>
<br>
<h4>Lista plików:</h4>
<ul id="file-list"></ul>
</div>
<div class="tab-panel" id="config">
<form id="config-form">
<h4>Konfiguracja Serwera:</h4>
<div class="form-group">
<label for="server-type">Typ serwera</label>
<select id="server-type" class="form-control">
<option value="paper">Paper</option>
<option value="fabric">Fabric</option>
</select>
</div>
<div class="form-group">
<label for="server-version">Wersja</label>
<input type="text" id="server-version" class="form-control" placeholder="Np. 1.20.4">
</div>
<div class="form-group">
<label for="max-players">Maksymalna liczba graczy</label>
<input type="number" id="max-players" class="form-control" min="1" value="{{ config['max-players'] }}">
</div>
<div class="form-group">
<label for="pvp">PvP</label>
<input type="checkbox" id="pvp" class="form-check-input" {% if config['pvp'] %} checked {% endif %}>
</div>
<div class="form-group">
<label for="difficulty">Trudność</label>
<select id="difficulty" class="form-control">
<option value="peaceful" {% if config['difficulty'] == 'peaceful' %}selected{% endif %}>Spokojny</option>
<option value="easy" {% if config['difficulty'] == 'easy' %}selected{% endif %}>Łatwy</option>
<option value="normal" {% if config['difficulty'] == 'normal' %}selected{% endif %}>Normalny</option>
<option value="hard" {% if config['difficulty'] == 'hard' %}selected{% endif %}>Trudny</option>
</select>
</div>
<div class="form-group">
<label for="online-mode">Tryb online</label>
<h6>W tym trybie mogą dołączyć tylko gracze z kupionym kontem Minecraft. Jest owiele bezpieczniejszy.
<br>Jeżeli chcesz używać serwera z wyłączonym trybem online, zainstaluj AuthMe lub podobny plugin i włącz whitelistę</h6>
<input type="checkbox" id="online-mode" class="form-check-input" {% if config['online-mode'] %} checked {% endif %}>
</div>
<div class="form-group">
<label for="spawn-monsters">Spawnowanie potworów</label>
<input type="checkbox" id="spawn-monsters" class="form-check-input" {% if config['spawn-monsters'] %} checked {% endif %}>
</div>
<div class="form-group">
<label for="spawn-animals">Spawnowanie zwierząt</label>
<input type="checkbox" id="spawn-animals" class="form-check-input" {% if config['spawn-animals'] %} checked {% endif %}>
</div>
<div class="form-group">
<label for="allow-nether">Nether Włączony</label>
<input type="checkbox" id="allow-nether" class="form-check-input" {% if config['allow-nether'] %} checked {% endif %}>
</div>
<div class="form-group">
<label for="max-build-height">Maksymalna wysokość budowania</label>
<input type="number" id="max-build-height" class="form-control" min="1" value="{{ config['max-build-height'] }}">
</div>
<div class="form-group">
<label for="view-distance">Zasięg widzenia</label>
<input type="number" id="view-distance" class="form-control" min="1" value="{{ config['view-distance'] }}">
</div>
<button type="button" class="btn btn-primary" onclick="saveConfig()">Zapisz zmiany</button>
</form>
</div>
<div class="tab-panel" id="statistics">
<div class="charts-row">
<div class="chart-container"><canvas id="cpuChart"></canvas></div>
<div class="chart-container"><canvas id="ramChart"></canvas></div>
</div>
</div>
<div class="tab-panel" id="mods">
<h2>Zainstaluj mody/pluginy z Modrinth</h2>
<input type="text" id="mod-search" placeholder="Wyszukaj mod/plugin..." oninput="searchMods()">
<div id="mod-results"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="/static/js/controls.js"></script>
<script src="/static/js/console.js"></script>
<script src="/static/js/files.js"></script>
<script src="/static/js/config.js"></script>
<script src="/static/js/mods.js"></script>
<script>
const username = "{{ username }}";
const $ = id => document.getElementById(id);
let statsInterval = null;
let logsInterval = null;
let currentStatus = null;
function showTab(id) {
document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
$(id).classList.add('active');
}
let currentPath = '';
function checkServerStatus() {
fetch(`/api/status?username=${username}`)
.then(r => r.json())
.then(data => {
const statusEl = $("server-status");
if (data.running) {
statusEl.textContent = "Online";
statusEl.style.color = "#2ecc71";
if (currentStatus !== true) {
startStats();
currentStatus = true;
}
} else {
statusEl.textContent = "Offline";
statusEl.style.color = "#e74c3c";
if (currentStatus !== false) {
stopStats();
currentStatus = false;
}
}
});
}
function startStats() {
if (!statsInterval) {
statsInterval = setInterval(updateStats, 4000);
updateStats();
}
if (!logsInterval) {
logsInterval = setInterval(loadLogs, 5000);
loadLogs();
}
}
function stopStats() {
if (statsInterval) {
clearInterval(statsInterval);
statsInterval = null;
}
if (logsInterval) {
clearInterval(logsInterval);
logsInterval = null;
}
}
function updateStats() {
fetch(`/api/stats?username=${username}`)
.then(r => r.json())
.then(data => {
const now = new Date().toLocaleTimeString();
const charts = [cpuChart, ramChart];
const values = [data.cpu, data.ram];
charts.forEach((chart, i) => {
if (chart.data.labels.length > 20) {
chart.data.labels.shift();
chart.data.datasets[0].data.shift();
}
chart.data.labels.push(now);
chart.data.datasets[0].data.push(values[i]);
chart.update();
});
});
}
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { ticks: { color: '#aaa' }, grid: { color: '#222' } },
y: { ticks: { color: '#aaa' }, grid: { color: '#222' } }
},
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#1a1a2a',
titleColor: '#f0f0f0',
bodyColor: '#ccc'
}
}
};
const cpuChart = new Chart($("cpuChart"), {
type: 'line',
data: {
labels: ['CPU (%)'],
datasets: [{
label: 'CPU (%)',
data: [],
borderColor: '#6c7bff',
backgroundColor: 'rgba(108, 123, 255, 0.2)',
tension: 0.3,
pointRadius: 0
}]
},
options: {
...chartOptions,
scales: { ...chartOptions.scales, y: { min: 0, max: 100, ticks: { color: '#aaa' } } }
}
});
const ramChart = new Chart($("ramChart"), {
type: 'line',
data: {
labels: ['RAM (MB)'],
datasets: [{
label: 'RAM (MB)',
data: [],
borderColor: '#2ecc71',
backgroundColor: 'rgba(46, 204, 113, 0.2)',
tension: 0.3,
pointRadius: 0
}]
},
options: chartOptions
});
checkServerStatus();
setInterval(checkServerStatus, 5000);
</script>
{% endblock %}