206 lines
8.6 KiB
PHP
206 lines
8.6 KiB
PHP
@extends('admin::layouts.admin')
|
|
@section('title', 'Admin Dashboard')
|
|
|
|
@push('scripts')
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
@endpush
|
|
|
|
@section('content')
|
|
<main class="flex-1">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h1 class="text-2xl font-bold">Admin Dashboard</h1>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
|
|
<!-- System Statistics -->
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<h2 class="text-xl font-semibold mb-4">System Statistics</h2>
|
|
<div class="space-y-4">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Users</span>
|
|
<span class="font-semibold">{{ $systemStats['users_count'] }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Roles</span>
|
|
<span class="font-semibold">{{ $systemStats['roles_count'] }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">User Roles</span>
|
|
<span class="font-semibold">{{ $systemStats['user_roles_count'] }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Resource Types</span>
|
|
<span class="font-semibold">{{ $systemStats['resources_count'] }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Resource Type Mappings</span>
|
|
<span class="font-semibold">{{ $systemStats['resource_mappings_count'] }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Database Statistics -->
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<h2 class="text-xl font-semibold mb-4">Database Statistics</h2>
|
|
<div class="space-y-4">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Database Size</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->db_size }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Schemas</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->schema_count }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Tables</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->table_count }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Views</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->view_count }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Materialized Views</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->materialized_view_count }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-gray-600">Indexes</span>
|
|
<span class="font-semibold">{{ $dbStats[0]->index_count }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Database I/O Monitor -->
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<h2 class="text-xl font-semibold mb-4">Database I/O Activity</h2>
|
|
<div class="h-64">
|
|
<canvas id="ioChart"></canvas>
|
|
</div>
|
|
</div>
|
|
<!-- Database Operations Monitor -->
|
|
<div class="bg-white rounded-lg shadow p-6 mt-6">
|
|
<h2 class="text-xl font-semibold mb-4">Database Operations</h2>
|
|
<div class="h-64">
|
|
<canvas id="operationsChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize the I/O chart
|
|
const ctx = document.getElementById('ioChart').getContext('2d');
|
|
const ioChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: [],
|
|
datasets: [{
|
|
label: 'Blocks Read/sec',
|
|
borderColor: '#EF4444',
|
|
data: [],
|
|
fill: false
|
|
}, {
|
|
label: 'Cache Hits/sec',
|
|
borderColor: '#10B981',
|
|
data: [],
|
|
fill: false
|
|
}, {
|
|
label: 'Tuples Returned/sec',
|
|
borderColor: '#3B82F6',
|
|
data: [],
|
|
fill: false
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
animation: false
|
|
}
|
|
});
|
|
|
|
// Initialize the operations chart
|
|
const opCtx = document.getElementById('operationsChart').getContext('2d');
|
|
const operationsChart = new Chart(opCtx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: [],
|
|
datasets: [{
|
|
label: 'Inserts/sec',
|
|
borderColor: '#10B981',
|
|
data: [],
|
|
fill: false
|
|
}, {
|
|
label: 'Updates/sec',
|
|
borderColor: '#F59E0B',
|
|
data: [],
|
|
fill: false
|
|
}, {
|
|
label: 'Deletes/sec',
|
|
borderColor: '#EF4444',
|
|
data: [],
|
|
fill: false
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
animation: false
|
|
}
|
|
});
|
|
|
|
// Function to update both charts
|
|
async function updateCharts() {
|
|
try {
|
|
const response = await fetch('{{ route('admin.database.io') }}');
|
|
const data = await response.json();
|
|
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
|
|
// Update I/O Chart
|
|
ioChart.data.labels.push(timestamp);
|
|
ioChart.data.datasets[0].data.push(data.blks_read);
|
|
ioChart.data.datasets[1].data.push(data.blks_hit);
|
|
ioChart.data.datasets[2].data.push(data.tup_returned);
|
|
|
|
// Update Operations Chart
|
|
operationsChart.data.labels.push(timestamp);
|
|
operationsChart.data.datasets[0].data.push(data.tup_inserted);
|
|
operationsChart.data.datasets[1].data.push(data.tup_updated);
|
|
operationsChart.data.datasets[2].data.push(data.tup_deleted);
|
|
|
|
// Keep only last 20 points for both charts
|
|
if (ioChart.data.labels.length > 20) {
|
|
ioChart.data.labels.shift();
|
|
ioChart.data.datasets.forEach(dataset => dataset.data.shift());
|
|
|
|
operationsChart.data.labels.shift();
|
|
operationsChart.data.datasets.forEach(dataset => dataset.data.shift());
|
|
}
|
|
|
|
// Update both charts
|
|
ioChart.update();
|
|
operationsChart.update();
|
|
} catch (error) {
|
|
console.error('Error fetching database stats:', error);
|
|
}
|
|
}
|
|
|
|
// Update every 2 seconds
|
|
setInterval(updateCharts, 2000);
|
|
// Initial update
|
|
updateCharts();
|
|
});
|
|
</script>
|
|
@endsection
|