212 lines
6.1 KiB
Vue

<template>
<div>
<LayoutsBreadcrumb />
<!-- Header Section -->
<rs-card class="mb-6">
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center">
<Icon class="mr-2 text-primary" name="ic:outline-speed"></Icon>
<h1 class="text-xl font-bold text-primary">Performance</h1>
</div>
<rs-button
variant="outline"
size="sm"
@click="refreshMetrics"
:loading="isLoading"
>
<Icon class="mr-1" name="ic:outline-refresh"></Icon>
Refresh
</rs-button>
</div>
</template>
<template #body>
<p class="text-gray-600">Monitor system performance and metrics.</p>
</template>
</rs-card>
<!-- Error Alert -->
<rs-alert v-if="error" variant="danger" class="mb-6">
{{ error }}
</rs-alert>
<!-- Loading State -->
<div v-if="isLoading" class="flex justify-center items-center py-12 text-gray-600">
<Icon name="ic:outline-sync" class="w-6 h-6 animate-spin mr-2" />
Loading...
</div>
<div v-else>
<!-- Key Metrics -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<rs-card>
<div class="p-4 text-center">
<h3 class="text-2xl font-bold text-blue-600">
{{ metrics.throughput }}
</h3>
<p class="text-sm text-gray-600">Messages/min</p>
</div>
</rs-card>
<rs-card>
<div class="p-4 text-center">
<h3 class="text-2xl font-bold text-green-600">{{ metrics.uptime }}%</h3>
<p class="text-sm text-gray-600">System Uptime</p>
</div>
</rs-card>
<rs-card>
<div class="p-4 text-center">
<h3 class="text-2xl font-bold text-purple-600">
{{ metrics.workers }}
</h3>
<p class="text-sm text-gray-600">Active Workers</p>
</div>
</rs-card>
<rs-card>
<div class="p-4 text-center">
<h3 class="text-2xl font-bold text-orange-600">{{ metrics.queueLoad }}%</h3>
<p class="text-sm text-gray-600">Queue Load</p>
</div>
</rs-card>
</div>
<!-- Performance Summary -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Throughput Summary -->
<rs-card>
<template #header>
<h3 class="text-lg font-semibold text-primary">Throughput Summary</h3>
</template>
<template #body>
<div class="space-y-4">
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Current Rate</span>
<span class="font-bold">{{ throughput.current }}/min</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Peak Today</span>
<span class="font-bold">{{ throughput.peak }}/min</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Average</span>
<span class="font-bold">{{ throughput.average }}/min</span>
</div>
</div>
</template>
</rs-card>
<!-- System Status -->
<rs-card>
<template #header>
<h3 class="text-lg font-semibold text-primary">System Status</h3>
</template>
<template #body>
<div class="space-y-4">
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Uptime Today</span>
<span class="font-bold text-green-600"
>{{ systemStatus.uptimeToday }}%</span
>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Response Time</span>
<span class="font-bold">{{ systemStatus.responseTime }}ms</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded">
<span class="text-gray-600">Error Rate</span>
<span class="font-bold text-red-600">{{ systemStatus.errorRate }}%</span>
</div>
</div>
</template>
</rs-card>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
definePageMeta({
title: "Performance",
middleware: ["auth"],
requiresAuth: true,
breadcrumb: [
{
name: "Notification",
path: "/notification",
},
{
name: "Queue",
path: "/notification/queue",
},
{
name: "Performance",
path: "/notification/queue/performance",
},
],
});
// Reactive state
const isLoading = ref(true);
const error = ref(null);
const metrics = ref({
throughput: "0",
uptime: "0",
workers: "0",
queueLoad: "0",
});
const throughput = ref({
current: "0",
peak: "0",
average: "0",
});
const systemStatus = ref({
uptimeToday: "0",
responseTime: "0",
errorRate: "0",
});
// Fetch metrics from API
const fetchMetrics = async () => {
try {
isLoading.value = true;
error.value = null;
const response = await useFetch("/api/notifications/queue/performance", {
method: "GET",
});
if (response.error.value) {
throw new Error(response.error.value.data?.message || "Failed to fetch metrics");
}
const data = response.data.value?.data;
if (data) {
metrics.value = data.metrics;
throughput.value = data.throughput;
systemStatus.value = data.systemStatus;
}
} catch (err) {
console.error("Error fetching metrics:", err);
error.value = err.message;
} finally {
isLoading.value = false;
}
};
// Refresh metrics
const refreshMetrics = () => {
fetchMetrics();
};
// Fetch metrics on component mount
onMounted(() => {
fetchMetrics();
});
</script>
<style lang="scss" scoped></style>