Initial commit: LuHost - Luanti Server Management Web Interface
A modern web interface for Luanti (Minetest) server management with ContentDB integration. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
305
views/contentdb/updates.ejs
Normal file
305
views/contentdb/updates.ejs
Normal file
@@ -0,0 +1,305 @@
|
||||
<%
|
||||
const body = `
|
||||
<div class="page-header">
|
||||
<h2>🔄 Package Updates</h2>
|
||||
<p>Check and install updates for your packages</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>📊 Update Status</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="stat-item">
|
||||
<strong>${installedCount || 0}</strong>
|
||||
<span>Total Packages</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<strong>${updateCount || 0}</strong>
|
||||
<span>Updates Available</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<strong>${installedCount - updateCount || 0}</strong>
|
||||
<span>Up to Date</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>⚡ Quick Actions</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
${updateCount > 0 ? `
|
||||
<button class="btn btn-success btn-block" onclick="updateAllPackages()">
|
||||
📦 Update All (${updateCount})
|
||||
</button>
|
||||
<button class="btn btn-outline-primary btn-block" onclick="window.location.reload()">
|
||||
🔄 Refresh Check
|
||||
</button>
|
||||
` : `
|
||||
<button class="btn btn-outline-primary btn-block" onclick="window.location.reload()">
|
||||
🔄 Check Again
|
||||
</button>
|
||||
`}
|
||||
<a href="/contentdb/installed" class="btn btn-outline-secondary btn-block">
|
||||
📦 View All Installed
|
||||
</a>
|
||||
<a href="/contentdb" class="btn btn-outline-secondary btn-block">
|
||||
🌐 Browse ContentDB
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
${updateCount === 0 ? `
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h3>✅ All Packages Up to Date!</h3>
|
||||
<p>All your installed packages are running the latest versions.</p>
|
||||
<div class="emoji-large">🎉</div>
|
||||
<p class="text-muted">
|
||||
${installedCount === 0 ?
|
||||
'You haven\\'t installed any packages yet.' :
|
||||
\`Checked \${installedCount} package\${installedCount !== 1 ? 's' : ''}.\`
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
` : `
|
||||
<div class="updates-list">
|
||||
${updates.map(update => `
|
||||
<div class="card update-card">
|
||||
<div class="card-header">
|
||||
<div class="update-title">
|
||||
<h4>${update.latest.package.title || update.installed.name}</h4>
|
||||
<small class="text-muted">by ${update.installed.author}</small>
|
||||
</div>
|
||||
<div class="update-badge">
|
||||
<span class="badge badge-warning">Update Available</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="version-comparison">
|
||||
<div class="version-item current">
|
||||
<div class="version-label">Current Version</div>
|
||||
<div class="version-value">${update.installed.version}</div>
|
||||
<div class="version-date">
|
||||
Installed: ${new Date(update.installed.installed_at).toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
<div class="version-arrow">➜</div>
|
||||
<div class="version-item latest">
|
||||
<div class="version-label">Latest Version</div>
|
||||
<div class="version-value">${update.latest.release.title}</div>
|
||||
<div class="version-date">
|
||||
Released: ${new Date(update.latest.release.created_at).toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="package-location">
|
||||
<strong>Location:</strong>
|
||||
<span class="location-badge ${update.installed.install_location === 'global' ? 'global' : 'world'}">
|
||||
${update.installed.install_location === 'global' ? 'Global' : update.installed.install_location.replace('world:', '')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="update-actions">
|
||||
<button class="btn btn-success"
|
||||
onclick="updatePackage('${update.installed.author}', '${update.installed.name}', '${update.installed.install_location}')">
|
||||
📦 Update Now
|
||||
</button>
|
||||
<a href="https://content.luanti.org/packages/${update.installed.author}/${update.installed.name}/"
|
||||
target="_blank"
|
||||
class="btn btn-outline-primary">
|
||||
View on ContentDB
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.stat-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.stat-item strong {
|
||||
display: block;
|
||||
font-size: 1.5rem;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.stat-item span {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.emoji-large {
|
||||
font-size: 3rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.updates-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.update-card {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.update-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.update-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.update-title h4 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.version-comparison {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
background: var(--bg-accent);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.version-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.version-label {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.version-value {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.version-date {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.version-arrow {
|
||||
font-size: 1.5rem;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.current .version-value {
|
||||
color: var(--warning-color);
|
||||
}
|
||||
|
||||
.latest .version-value {
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.package-location {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.location-badge {
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.location-badge.global {
|
||||
background: var(--success-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.location-badge.world {
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.update-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.badge-warning {
|
||||
background: var(--warning-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.version-comparison {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.version-arrow {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.update-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.update-actions .btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function updatePackage(author, name, location) {
|
||||
alert('Update functionality coming soon!');
|
||||
// TODO: Implement individual package update
|
||||
}
|
||||
|
||||
function updateAllPackages() {
|
||||
if (!confirm('Update all packages? This may take a while.')) {
|
||||
return;
|
||||
}
|
||||
alert('Bulk update functionality coming soon!');
|
||||
// TODO: Implement bulk package update
|
||||
}
|
||||
</script>
|
||||
`;
|
||||
%>
|
||||
|
||||
<%- include('../layout', { body: body, currentPage: 'contentdb', title: title }) %>
|
Reference in New Issue
Block a user