Statusy, Wersja Mobilna, Logo PaperMC

- Dodano statusy serwerów dla wszystkich (#13)
- Mobilna Wersja Panelu (#18)
- Zamieniono logo PaperMC na ich nowy link
This commit is contained in:
Andus 2025-05-09 23:02:30 +02:00
parent 60e2f73008
commit 07c9522444
8 changed files with 245 additions and 168 deletions

View file

@ -21,7 +21,7 @@ def home():
username = oidc.user_getfield("preferred_username") username = oidc.user_getfield("preferred_username")
server_path = f"./servers/mc-{username}" server_path = f"./servers/mc-{username}"
has_server = os.path.exists(server_path) has_server = os.path.exists(server_path)
return render_template("home.html", has_server=has_server) return render_template("home.html", has_server=has_server, is_logged_in=is_logged_in)
@main.route('/setup') @main.route('/setup')
@ -61,8 +61,8 @@ def list_ads():
return jsonify(files) return jsonify(files)
@main.route("/servers") @main.route("/status")
def server_list(): def servers_status():
servers_dir = "./servers" servers_dir = "./servers"
server_dirs = [ server_dirs = [
d for d in os.listdir(servers_dir) d for d in os.listdir(servers_dir)
@ -73,18 +73,18 @@ def server_list():
for server_dir in server_dirs: for server_dir in server_dirs:
server_name = server_dir server_name = server_dir
server_status = "stopped" server_status = "Offline"
try: try:
container = client.containers.get(server_name) container = client.containers.get(server_name)
if container.status == "running": if container.status == "running":
server_status = "running" server_status = "Online"
except NotFound: except NotFound:
pass pass
server_data.append({"name": server_name, "status": server_status}) server_data.append({"name": server_name, "status": server_status})
return render_template('server_list.html', servers=server_data) return render_template('servers_list.html', servers=server_data)
@main.app_errorhandler(404) @main.app_errorhandler(404)

View file

@ -1,3 +1,6 @@
/* Imports */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
/* Reset & Base Styles */ /* Reset & Base Styles */
* { * {
margin: 0; margin: 0;
@ -103,7 +106,7 @@ h2 {
/* Tabs */ /* Tabs */
.tabs { .tabs {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); grid-template-columns: repeat(3, 1fr);
gap: 14px; gap: 14px;
margin-bottom: 26px; margin-bottom: 26px;
} }
@ -209,6 +212,7 @@ h2 {
.btn-primary { background: #4a5aef; color: white; box-shadow: 0 0 10px #4a5aef99; } .btn-primary { background: #4a5aef; color: white; box-shadow: 0 0 10px #4a5aef99; }
.btn-success { background: #2ecc71; color: white; box-shadow: 0 0 10px #2ecc7199; } .btn-success { background: #2ecc71; color: white; box-shadow: 0 0 10px #2ecc7199; }
.btn-danger { background: #e74c3c; color: white; box-shadow: 0 0 10px #e74c3c99; } .btn-danger { background: #e74c3c; color: white; box-shadow: 0 0 10px #e74c3c99; }
.btn-worsedanger { background: #8b0000; color: white; box-shadow: 0 0 10px #8b000099; }
.btn-warning { background: #f39c12; color: black; box-shadow: 0 0 10px #f39c1288; } .btn-warning { background: #f39c12; color: black; box-shadow: 0 0 10px #f39c1288; }
.btn-info { background: #3498db; color: white; box-shadow: 0 0 10px #3498db99; } .btn-info { background: #3498db; color: white; box-shadow: 0 0 10px #3498db99; }
@ -256,18 +260,7 @@ h2 {
background-color: #666; background-color: #666;
} }
/* Chart Container */ body > *:not(.cursor-glow) {
.chart-container {
background: #12121c;
padding: 20px;
border-radius: 14px;
margin-top: 30px;
border: 1px solid #232334;
box-shadow: 0 0 12px #1a1a2a;
overflow-x: auto;
}
body > *:not(script):not(style):not(.cursor-glow) {
animation: growIn 0.6s ease-out; animation: growIn 0.6s ease-out;
} }
@ -577,117 +570,187 @@ a.non-link:hover {
color: #000; color: #000;
} }
/* Mobile Tweaks */ /* Servers Status */
@media (max-width: 480px) { .server-table-container {
html {
font-size: clamp(14px, 2.5vw, 16px);
}
/* Heading adjustment */
h2 {
font-size: 1.5rem;
}
/* Dashboard Card */
.dashboard-card {
padding: 16px;
max-width: 100%;
}
/* Tab buttons */
.tab-button {
padding: 10px;
font-size: 0.85rem;
}
/* Square button adjustments */
.square-button {
width: 100%;
aspect-ratio: unset;
flex-direction: row;
justify-content: flex-start;
gap: 12px;
padding: 10px;
font-size: 0.9rem;
}
.square-button img {
width: 32px;
margin: 0;
}
/* Navigation Bar */
.top-nav {
padding: 12px;
font-size: 0.9rem;
flex-direction: column;
align-items: flex-start;
}
.nav-links a {
margin-left: 10px;
font-size: 0.9rem;
}
/* Console Output */
.console-output {
font-size: 0.8rem;
height: 160px;
}
/* Chart container */
.chart-container {
width: 100%;
height: auto;
padding: 12px;
}
/* Buttons */
.btn {
font-size: 0.9rem;
padding: 12px;
width: 100%;
}
/* Form layout */
form {
padding: 0 8px;
}
/* Tab content spacing */
.tab-content {
margin-top: 8px;
}
/* Particle background on small screens */
#particle-background {
display: none; /* Improves performance */
}
/* Charts Row - Allow horizontal scroll */
.charts-row {
overflow-x: auto; overflow-x: auto;
padding-bottom: 10px; padding: 1rem;
} border-radius: 16px;
background: rgba(14, 14, 26, 0.6);
backdrop-filter: blur(12px);
border: 1px solid #1a1a2a;
box-shadow: 0 0 24px rgba(74, 90, 239, 0.15);
}
/* Input Fields */ .server-table {
input[type="text"], input[type="number"], select {
width: 100%; width: 100%;
} border-collapse: collapse;
color: #f0f0f0;
/* Adjust drop zone */ font-size: 0.95rem;
#drop-zone { border-radius: 12px;
padding: 20px; overflow: hidden;
}
/* Adjust text area height */
.console-output {
height: 160px;
}
} }
/* Additional general fixes for small screens */ .server-table thead {
background: linear-gradient(145deg, #1a1a2f, #23233a);
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.85rem;
color: #b9c5ff;
}
.server-table th,
.server-table td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.server-table tbody tr:hover {
background: rgba(255, 255, 255, 0.03);
transition: background 0.3s ease;
}
.server-table th:first-child,
.server-table td:first-child {
border-left: none;
}
.server-table th:last-child,
.server-table td:last-child {
border-right: none;
}
.server-table tbody tr {
box-shadow: inset 0 0 0 rgba(0, 0, 0, 0);
transition: box-shadow 0.2s ease;
}
.server-table tbody tr:hover {
box-shadow: inset 0 0 12px rgba(255, 255, 255, 0.03);
}
.status-label {
display: inline-block;
padding: 0.4em 0.75em;
border-radius: 999px;
font-weight: 600;
font-size: 0.875rem;
text-transform: capitalize;
color: white;
}
.status-label.online {
background-color: #2ecc71;
}
.status-label.offline {
background-color: #e74c3c;
}
/* Mobile Tweaks */
@media (max-width: 768px) {
html {
font-size: clamp(15px, 4vw, 16px);
}
body {
padding: 0 8px;
}
h1, h2, h3 {
line-height: 1.2;
}
.dashboard-card {
padding: 16px;
max-width: 100%;
box-sizing: border-box;
}
.tabs {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-bottom: 12px;
}
.tab-button {
padding: 12px;
font-size: 0.95rem;
width: 100%;
box-sizing: border-box;
}
.square-button {
display: flex;
align-items: center;
width: 100%;
flex-direction: row;
justify-content: flex-start;
gap: 12px;
padding: 12px;
font-size: 0.95rem;
}
.square-button img {
width: 32px;
height: auto;
margin: 0;
}
.top-nav {
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.nav-links {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 12px;
}
.chart-container {
width: 100%;
height: auto;
padding: 12px;
}
.btn {
font-size: 0.95rem;
padding: 14px;
width: 100%;
}
form {
padding: 0 8px;
}
.tab-content {
margin-top: 12px;
}
.charts-row {
overflow-x: auto;
padding-bottom: 10px;
}
input[type="text"], input[type="number"], select, textarea {
width: 100%;
font-size: 1rem;
padding: 10px;
box-sizing: border-box;
}
#drop-zone {
padding: 20px;
}
}
/* Universal Fixes */
* { * {
max-width: 100%; max-width: 100%;
word-wrap: break-word; word-wrap: break-word;
box-sizing: border-box;
} }

View file

@ -6,9 +6,6 @@
<button class="tab-button" onclick="showTab('controls')">Sterowanie 🎛️</button> <button class="tab-button" onclick="showTab('controls')">Sterowanie 🎛️</button>
<button class="tab-button" onclick="showTab('console')">Konsola 📟</button> <button class="tab-button" onclick="showTab('console')">Konsola 📟</button>
<button class="tab-button" onclick="showTab('files')">Pliki 📁</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('config')">Konfiguracja 🛠️</button>
<button class="tab-button" onclick="showTab('mods')">Mody/Pluginy 🧩</button> <button class="tab-button" onclick="showTab('mods')">Mody/Pluginy 🧩</button>
<button class="tab-button" onclick="showTab('statistics')">Statystyki 📈</button> <button class="tab-button" onclick="showTab('statistics')">Statystyki 📈</button>
@ -25,7 +22,7 @@
<button class="btn btn-success" onclick="sendAction('start')">Start</button> <button class="btn btn-success" onclick="sendAction('start')">Start</button>
<button class="btn btn-warning" onclick="sendAction('restart')">Restart</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="sendAction('stop')">Stop</button><br>
<button class="btn btn-danger" onclick="deleteServer()">Usuń Serwer</button> <button class="btn btn-worsedanger" onclick="deleteServer()">Usuń Serwer</button>
</div> </div>
<div class="tab-panel" id="console"> <div class="tab-panel" id="console">
@ -113,7 +110,7 @@
</div> </div>
<div class="tab-panel" id="mods"> <div class="tab-panel" id="mods">
<h2>Zainstaluj mody/pluginy z Modrinth</h2> <h4>Zainstaluj mody/pluginy z <span style="color: #2ecc71;">Modrinth</span></h4>
<input type="text" id="mod-search" placeholder="Wyszukaj mod/plugin..." oninput="searchMods()"> <input type="text" id="mod-search" placeholder="Wyszukaj mod/plugin..." oninput="searchMods()">
<div id="mod-results"></div> <div id="mod-results"></div>
</div> </div>

View file

@ -2,20 +2,30 @@
{% block content %} {% block content %}
<div class="logo-wrapper"> <div class="logo-wrapper">
<h2 class="logo-text">MCPanel</h2> <h2 class="logo-text">MCPanel</h2>
<p id="quote" class="splash-text">Jesteśmy 1.5x lepsi od Aternosa!</p> <p id="quote" class="splash-text"></p>
</div> </div>
<div class="tabs"> <div class="tabs">
{% if has_server %} {% if is_logged_in %}
<a class="tab-button" href="{{ url_for('main.dashboard') }}">Idź do panelu</a> {% if has_server %}
<a class="tab-button" href="{{ url_for('main.dashboard') }}">Idź do panelu</a>
{% else %}
<a class="tab-button" href="{{ url_for('main.setup') }}">Ustaw własny serwer</a>
{% endif %}
{% else %} {% else %}
<a class="tab-button" href="{{ url_for('main.setup') }}">Ustaw własny serwer</a> <a class="tab-button" href="{{ url_for('main.dashboard') }}">Zaloguj się</a>
{% endif %} {% endif %}
<a class="tab-button" href="#news">Wiadomości</a>
</div>
<div id="news">
<!-- Z Tagami jak: WERSJA PANELU, PROBLEM -->
<h3>Wiadomości:</h3>
<p>Soon&trade;</p>
</div> </div>
<script> <script>
const quotes = [ const quotes = [
"Jesteśmy 2x lepsi od Aternosa!",
"Twój serwer, Twoje zasady!", "Twój serwer, Twoje zasady!",
"Stabilność? Nie znam takiego słowa!", "Stabilność? Nie znam takiego słowa!",
"Zero kolejki, tylko gra!", "Zero kolejki, tylko gra!",

View file

@ -3,6 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>MCPanel</title> <title>MCPanel</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
</head> </head>
@ -22,8 +23,9 @@
<div class="nav-logo"><a href="/">MCPanel <h6>BETA</h6></a></div> <div class="nav-logo"><a href="/">MCPanel <h6>BETA</h6></a></div>
<div class="nav-links"> <div class="nav-links">
<a href="/dashboard">Panel</a> <a href="/dashboard">Panel</a>
<a href="/status">Statusy</a>
<a style="color: cornflowerblue;" href="/donate">Donate</a> <a style="color: cornflowerblue;" href="/donate">Donate</a>
<a href="/logout">Wyloguj</a> <a style="color: red;" href="/logout">Wyloguj</a>
</div> </div>
</nav> </nav>
@ -31,7 +33,7 @@
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<div id="ad-banner" class="ad-banner"></div> <div id="ad-banner" class="ad-banner"></div>
<p>Wersja: v0.2</p> <p>Wersja: v0.3</p>
<script> <script>
window.addEventListener('dragover', e => e.preventDefault()); window.addEventListener('dragover', e => e.preventDefault());
window.addEventListener('drop', e => e.preventDefault()); window.addEventListener('drop', e => e.preventDefault());

View file

@ -1,27 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Wszystkie Serwery</h1>
<div class="server-table">
<table border="1">
<thead>
<tr>
<th>Nazwa</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for server in servers %}
<tr>
<td>{{ server.name }}</td>
<td>{{ server.status }}</td>
</tr>
{% else %}
<tr>
<td colspan="2">Nie znaleziono serwerów</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends "layout.html" %}
{% block content %}
<h1 class="page-title">Wszystkie Serwery</h1>
<div class="server-table-container">
<table class="server-table">
<thead>
<tr>
<th>Nazwa</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for server in servers %}
<tr>
<td>{{ server.name }}</td>
<td>
<span class="status-label {{ 'online' if server.status == 'Online' else 'offline' }}">
{{ server.status }}
</span>
</td>
</tr>
{% else %}
<tr>
<td colspan="2" class="empty-row">Nie znaleziono serwerów</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View file

@ -4,7 +4,7 @@
<div style="display: flex; justify-content: center; gap: 2rem; margin-bottom: 2rem;"> <div style="display: flex; justify-content: center; gap: 2rem; margin-bottom: 2rem;">
<button class="square-button" onclick="selectType(this, 'paper')"> <button class="square-button" onclick="selectType(this, 'paper')">
<img src="https://docs.papermc.io/assets/images/papermc-logomark-512-f125384f3367cd4d9291ca983fcb7334.png" alt="Paper"> <img src="https://assets.papermc.io/brand/papermc_logo.min.svg" alt="Paper">
<b>Paper</b> <b>Paper</b>
<br> <br>
<p>Zoptymalizowany serwer Minecraft oferujący lepszą wydajność.</p> <p>Zoptymalizowany serwer Minecraft oferujący lepszą wydajność.</p>