feat: Implement server endpoints, store, and live dashboard
Backend: Server connection/config/admins DB queries, server API routes with auth-gated endpoints (overview, config CRUD, admin management). Frontend: Server store wired to API, dashboard fetches server data on mount with live status indicators, uptime formatting, and server config display. Logout now redirects to /login. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useServerStore } from '@/stores/server'
|
||||
|
||||
const auth = useAuthStore()
|
||||
const server = useServerStore()
|
||||
|
||||
onMounted(() => {
|
||||
server.fetchServer()
|
||||
})
|
||||
|
||||
function statusColor(status: string | undefined): string {
|
||||
switch (status) {
|
||||
case 'connected': return 'bg-green-500'
|
||||
case 'degraded': return 'bg-yellow-500'
|
||||
default: return 'bg-red-500'
|
||||
}
|
||||
}
|
||||
|
||||
function statusLabel(status: string | undefined): string {
|
||||
switch (status) {
|
||||
case 'connected': return 'Online'
|
||||
case 'degraded': return 'Degraded'
|
||||
default: return 'Offline'
|
||||
}
|
||||
}
|
||||
|
||||
function formatUptime(seconds: number | undefined): string {
|
||||
if (!seconds) return '\u2014'
|
||||
const h = Math.floor(seconds / 3600)
|
||||
const m = Math.floor((seconds % 3600) / 60)
|
||||
if (h > 0) return `${h}h ${m}m`
|
||||
return `${m}m`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -20,15 +51,17 @@ const auth = useAuthStore()
|
||||
<div class="bg-neutral-900 border border-neutral-800 rounded-lg p-5">
|
||||
<p class="text-sm text-neutral-400 mb-2">Server Status</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-red-500"></span>
|
||||
<span class="text-2xl font-bold text-neutral-100">Offline</span>
|
||||
<span class="h-2.5 w-2.5 rounded-full" :class="statusColor(server.connection?.connection_status)"></span>
|
||||
<span class="text-2xl font-bold text-neutral-100">{{ statusLabel(server.connection?.connection_status) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Players Online -->
|
||||
<div class="bg-neutral-900 border border-neutral-800 rounded-lg p-5">
|
||||
<p class="text-sm text-neutral-400 mb-2">Players Online</p>
|
||||
<p class="text-2xl font-bold text-neutral-100">0/0</p>
|
||||
<p class="text-2xl font-bold text-neutral-100">
|
||||
{{ server.stats?.player_count ?? 0 }}/{{ server.stats?.max_players ?? server.config?.max_players ?? 0 }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Next Wipe -->
|
||||
@@ -40,7 +73,7 @@ const auth = useAuthStore()
|
||||
<!-- Uptime -->
|
||||
<div class="bg-neutral-900 border border-neutral-800 rounded-lg p-5">
|
||||
<p class="text-sm text-neutral-400 mb-2">Uptime</p>
|
||||
<p class="text-2xl font-bold text-neutral-100">—</p>
|
||||
<p class="text-2xl font-bold text-neutral-100">{{ formatUptime(server.stats?.uptime_seconds) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -49,24 +82,46 @@ const auth = useAuthStore()
|
||||
<h2 class="text-lg font-semibold text-neutral-200 mb-4">Quick Actions</h2>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button
|
||||
disabled
|
||||
class="px-4 py-2.5 bg-neutral-800 hover:bg-neutral-700 disabled:opacity-50 disabled:cursor-not-allowed text-neutral-300 rounded-lg text-sm font-medium transition-colors"
|
||||
:disabled="server.connection?.connection_status === 'connected'"
|
||||
class="px-4 py-2.5 bg-green-600/20 hover:bg-green-600/30 disabled:opacity-30 disabled:cursor-not-allowed text-green-400 border border-green-600/30 rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
Start Server
|
||||
</button>
|
||||
<button
|
||||
disabled
|
||||
class="px-4 py-2.5 bg-neutral-800 hover:bg-neutral-700 disabled:opacity-50 disabled:cursor-not-allowed text-neutral-300 rounded-lg text-sm font-medium transition-colors"
|
||||
:disabled="server.connection?.connection_status !== 'connected'"
|
||||
class="px-4 py-2.5 bg-red-600/20 hover:bg-red-600/30 disabled:opacity-30 disabled:cursor-not-allowed text-red-400 border border-red-600/30 rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
Stop Server
|
||||
</button>
|
||||
<button
|
||||
disabled
|
||||
class="px-4 py-2.5 bg-neutral-800 hover:bg-neutral-700 disabled:opacity-50 disabled:cursor-not-allowed text-neutral-300 rounded-lg text-sm font-medium transition-colors"
|
||||
class="px-4 py-2.5 bg-neutral-800 hover:bg-neutral-700 text-neutral-300 rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
Trigger Wipe
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Server Info (if configured) -->
|
||||
<div v-if="server.config" class="bg-neutral-900 border border-neutral-800 rounded-lg p-5">
|
||||
<h2 class="text-lg font-semibold text-neutral-200 mb-3">Server Configuration</h2>
|
||||
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 text-sm">
|
||||
<div>
|
||||
<span class="text-neutral-500">Server Name</span>
|
||||
<p class="text-neutral-200 mt-0.5">{{ server.config.server_name || 'Not set' }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-neutral-500">Max Players</span>
|
||||
<p class="text-neutral-200 mt-0.5">{{ server.config.max_players ?? 'Not set' }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-neutral-500">World Size</span>
|
||||
<p class="text-neutral-200 mt-0.5">{{ server.config.world_size ?? 'Not set' }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-neutral-500">Current Seed</span>
|
||||
<p class="text-neutral-200 mt-0.5">{{ server.config.current_seed ?? 'Not set' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user