214 lines
8.6 KiB
Plaintext
214 lines
8.6 KiB
Plaintext
<div class="layout">
|
||
|
||
<%- include("../partials/admin-sidebar", { user, active: "database", lang }) %>
|
||
|
||
<div class="main">
|
||
|
||
<%- include("../partials/page-header", {
|
||
user,
|
||
title: t.adminSidebar.database,
|
||
subtitle: "",
|
||
showUserName: true,
|
||
hideDashboardButton: true
|
||
}) %>
|
||
|
||
<div class="content p-4">
|
||
|
||
<%- include("../partials/flash") %>
|
||
|
||
<div class="container-fluid p-0">
|
||
<div class="row g-3">
|
||
|
||
<!-- DB Konfiguration -->
|
||
<div class="col-12">
|
||
<div class="card shadow mb-3">
|
||
<div class="card-body">
|
||
|
||
<h4 class="mb-3">
|
||
<i class="bi bi-sliders"></i> <%= t.databaseoverview.title %>
|
||
</h4>
|
||
|
||
<p class="text-muted mb-4"><%= t.databaseoverview.text %></p>
|
||
|
||
<form method="POST" action="/admin/database/test"
|
||
class="row g-3 mb-3" autocomplete="off">
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label"><%= t.databaseoverview.host %> / IP</label>
|
||
<input type="text" name="host" class="form-control"
|
||
value="<%= (typeof dbConfig !== 'undefined' && dbConfig && dbConfig.host) ? dbConfig.host : '' %>"
|
||
autocomplete="off" required>
|
||
</div>
|
||
|
||
<div class="col-md-3">
|
||
<label class="form-label"><%= t.databaseoverview.port %></label>
|
||
<input type="number" name="port" class="form-control"
|
||
value="<%= (typeof dbConfig !== 'undefined' && dbConfig && dbConfig.port) ? dbConfig.port : 3306 %>"
|
||
autocomplete="off" required>
|
||
</div>
|
||
|
||
<div class="col-md-3">
|
||
<label class="form-label"><%= t.databaseoverview.database %></label>
|
||
<input type="text" name="name" class="form-control"
|
||
value="<%= (typeof dbConfig !== 'undefined' && dbConfig && dbConfig.name) ? dbConfig.name : '' %>"
|
||
autocomplete="off" required>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label"><%= t.global.username %></label>
|
||
<input type="text" name="user" class="form-control"
|
||
value="<%= (typeof dbConfig !== 'undefined' && dbConfig && dbConfig.user) ? dbConfig.user : '' %>"
|
||
autocomplete="off" required>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label"><%= t.databaseoverview.password %></label>
|
||
<input type="password" name="password" class="form-control"
|
||
value="<%= (typeof dbConfig !== 'undefined' && dbConfig && dbConfig.password) ? dbConfig.password : '' %>"
|
||
autocomplete="off" required>
|
||
</div>
|
||
|
||
<div class="col-12 d-flex flex-wrap gap-2">
|
||
<button type="submit" class="btn btn-outline-primary">
|
||
<i class="bi bi-plug"></i> <%= t.databaseoverview.connectiontest %>
|
||
</button>
|
||
<button type="submit" class="btn btn-success" formaction="/admin/database">
|
||
<i class="bi bi-save"></i> <%= t.global.save %>
|
||
</button>
|
||
</div>
|
||
|
||
</form>
|
||
|
||
<% if (typeof testResult !== "undefined" && testResult) { %>
|
||
<div class="alert <%= testResult.ok ? 'alert-success' : 'alert-danger' %> mb-0">
|
||
<%= testResult.message %>
|
||
</div>
|
||
<% } %>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- System Info -->
|
||
<div class="col-12">
|
||
<div class="card shadow mb-3">
|
||
<div class="card-body">
|
||
|
||
<h4 class="mb-3">
|
||
<i class="bi bi-info-circle"></i> <%= t.global.systeminfo %>
|
||
</h4>
|
||
|
||
<% if (typeof systemInfo !== "undefined" && systemInfo && systemInfo.error) { %>
|
||
<div class="alert alert-danger mb-0">
|
||
❌ <%= t.global.errordatabase %>
|
||
<div class="mt-2"><code><%= systemInfo.error %></code></div>
|
||
</div>
|
||
|
||
<% } else if (typeof systemInfo !== "undefined" && systemInfo) { %>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<div class="border rounded p-3 h-100">
|
||
<div class="text-muted small"><%= t.databaseoverview.mysqlversion %></div>
|
||
<div class="fw-bold"><%= systemInfo.version %></div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="border rounded p-3 h-100">
|
||
<div class="text-muted small"><%= t.databaseoverview.tablecount %></div>
|
||
<div class="fw-bold"><%= systemInfo.tableCount %></div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="border rounded p-3 h-100">
|
||
<div class="text-muted small"><%= t.databaseoverview.databasesize %></div>
|
||
<div class="fw-bold"><%= systemInfo.dbSizeMB %> MB</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<% if (systemInfo.tables && systemInfo.tables.length > 0) { %>
|
||
<hr>
|
||
<h6 class="mb-2"><%= t.databaseoverview.tableoverview %></h6>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-bordered table-hover align-middle">
|
||
<thead class="table-dark">
|
||
<tr>
|
||
<th><%= t.global.table %></th>
|
||
<th class="text-end"><%= t.global.lines %></th>
|
||
<th class="text-end"><%= t.global.size %> (MB)</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% systemInfo.tables.forEach(tbl => { %>
|
||
<tr>
|
||
<td><%= tbl.name %></td>
|
||
<td class="text-end"><%= tbl.row_count %></td>
|
||
<td class="text-end"><%= tbl.size_mb %></td>
|
||
</tr>
|
||
<% }) %>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<% } %>
|
||
|
||
<% } else { %>
|
||
<div class="alert alert-warning mb-0">
|
||
⚠️ <%= t.databaseoverview.nodbinfo %>
|
||
</div>
|
||
<% } %>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Backup & Restore -->
|
||
<div class="col-12">
|
||
<div class="card shadow">
|
||
<div class="card-body">
|
||
|
||
<h4 class="mb-3">
|
||
<i class="bi bi-hdd-stack"></i> Backup & Restore
|
||
</h4>
|
||
|
||
<div class="d-flex flex-wrap gap-3">
|
||
|
||
<form action="/admin/database/backup" method="POST">
|
||
<button type="submit" class="btn btn-primary">
|
||
<i class="bi bi-download"></i> Backup erstellen
|
||
</button>
|
||
</form>
|
||
|
||
<form action="/admin/database/restore" method="POST">
|
||
<div class="input-group">
|
||
<select name="backupFile" class="form-select" required>
|
||
<option value="">Backup auswählen...</option>
|
||
<% (typeof backupFiles !== "undefined" && backupFiles ? backupFiles : []).forEach(file => { %>
|
||
<option value="<%= file %>"><%= file %></option>
|
||
<% }) %>
|
||
</select>
|
||
<button type="submit" class="btn btn-warning">
|
||
<i class="bi bi-upload"></i> Restore starten
|
||
</button>
|
||
</div>
|
||
</form>
|
||
|
||
</div>
|
||
|
||
<% if (typeof backupFiles === "undefined" || !backupFiles || backupFiles.length === 0) { %>
|
||
<div class="alert alert-secondary mt-3 mb-0">
|
||
ℹ️ Noch keine Backups vorhanden.
|
||
</div>
|
||
<% } %>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|