Fixes: - VideoPlayer.vue: restore allTags, filteredMarks, marksByTag (removed by mistake) - PeopleView.vue: fix frameTime scope in playFaceDetailVideo catch block - Both errors caused white screen on build failure Root cause: 1. visibleTags duplicate declaration (old + new logic) 2. frameTime undefined in catch block (scope issue) Solution: 1. Keep allTags/filteredMarks/marksByTag (needed in template) 2. Keep visibleTags (new logic for processor toggles) 3. Move frameTime calculation to correct scope in catch block
86 lines
3.7 KiB
Plaintext
86 lines
3.7 KiB
Plaintext
<template>
|
|
<div id="ms-view-admin">
|
|
<div class="admin-header">
|
|
<h1>Admin Panel</h1>
|
|
<div class="admin-tabs">
|
|
<button class="admin-tab" :class="{ active: activeTab === 'dashboard' }" @click="activeTab = 'dashboard'">Dashboard</button>
|
|
<button class="admin-tab" :class="{ active: activeTab === 'users' }" @click="activeTab = 'users'">Users</button>
|
|
<button class="admin-tab" :class="{ active: activeTab === 'shares' }" @click="activeTab = 'shares'">Shares</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="admin-content">
|
|
<div v-if="activeTab === 'dashboard'" class="dashboard-panel">
|
|
<div class="stats-grid">
|
|
<div class="stat-card"><div class="stat-label">CPU</div><div class="stat-value">{{ stats.cpu }}%</div></div>
|
|
<div class="stat-card"><div class="stat-label">Memory</div><div class="stat-value">{{ stats.memory }}%</div></div>
|
|
<div class="stat-card"><div class="stat-label">Disk</div><div class="stat-value">{{ stats.disk }}%</div></div>
|
|
<div class="stat-card"><div class="stat-label">Users</div><div class="stat-value">{{ users.length }}</div></div>
|
|
<div class="stat-card"><div class="stat-label">Shares</div><div class="stat-value">{{ shares.length }}</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="activeTab === 'users'" class="users-panel">
|
|
<table class="admin-table">
|
|
<thead><tr><th>Username</th><th>Home Dir</th><th>Status</th></tr></thead>
|
|
<tbody>
|
|
<tr v-for="u in users" :key="u.username">
|
|
<td>{{ u.username }}</td><td>{{ u.homeDir }}</td><td>{{ u.status === 1 ? 'Active' : 'Disabled' }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div v-if="activeTab === 'shares'" class="shares-panel">
|
|
<table class="admin-table">
|
|
<thead><tr><th>Name</th><th>Port</th><th>Status</th></tr></thead>
|
|
<tbody>
|
|
<tr v-for="s in shares" :key="s.name">
|
|
<td>{{ s.name }}</td><td>{{ s.port }}</td><td>{{ s.status }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { apiCall } from '../api'
|
|
|
|
const activeTab = ref('dashboard')
|
|
const stats = ref({ cpu: 0, memory: 0, disk: 0 })
|
|
const users = ref<any[]>([])
|
|
const shares = ref<any[]>([])
|
|
|
|
async function loadDashboard() {
|
|
try { stats.value = await apiCall('get_system_stats', {}) || { cpu: 0, memory: 0, disk: 0 } } catch (e) { console.error(e) }
|
|
}
|
|
|
|
async function loadUsers() {
|
|
try { users.value = await apiCall('list_admin_users', {}) || [] } catch (e) { console.error(e) }
|
|
}
|
|
|
|
async function loadShares() {
|
|
try { shares.value = await apiCall('list_shares', {}) || [] } catch (e) { console.error(e) }
|
|
}
|
|
|
|
onMounted(async () => { await loadDashboard(); await loadUsers(); await loadShares() })
|
|
</script>
|
|
|
|
<style scoped>
|
|
#ms-view-admin { padding: 20px; }
|
|
.admin-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
|
|
.admin-tabs { display: flex; gap: 10px; }
|
|
.admin-tab { padding: 8px 16px; border: none; background: #f0f0f0; cursor: pointer; border-radius: 4px; }
|
|
.admin-tab.active { background: #2563eb; color: white; }
|
|
.admin-content { background: white; border-radius: 8px; padding: 20px; }
|
|
.stats-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px; }
|
|
.stat-card { background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center; }
|
|
.stat-label { font-size: 12px; color: #666; }
|
|
.stat-value { font-size: 24px; font-weight: bold; }
|
|
.admin-table { width: 100%; border-collapse: collapse; }
|
|
.admin-table th, .admin-table td { padding: 10px; border: 1px solid #ddd; text-align: left; }
|
|
</style>
|