fix: Replace unsafe .toFixed() calls with safeFixed() in analytics views

- AnalyticsView: avg_players, uptime_percentage
- WipeAnalyticsView: success_rate, population curve, durations, CSV export
- PlayerRetentionView: retention percentages, session duration, tooltip
- MapAnalyticsView: rotation effectiveness, performance metrics, table

All analytics views now use safe formatter utilities with optional chaining
to prevent null/undefined runtime errors when displaying numeric data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell
2026-02-15 21:56:04 -05:00
parent daa9c3035f
commit 26e717ac96
18 changed files with 111 additions and 53 deletions

View File

@@ -2,6 +2,7 @@
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { Server, Users, Activity, TrendingUp, Search } from 'lucide-vue-next'
import { useApi } from '@/composables/useApi'
import { safeFixed } from '@/utils/formatters'
interface ServerStatus {
server_name: string
@@ -199,7 +200,7 @@ onUnmounted(() => {
Platform Uptime
</div>
<p class="text-2xl font-bold text-neutral-100">
{{ platformHealth.uptime_percent.toFixed(1) }}%
{{ safeFixed(platformHealth.uptime_percent, 1) }}%
</p>
</div>
</div>
@@ -297,15 +298,15 @@ onUnmounted(() => {
<!-- Uptime Badges -->
<div class="flex gap-2">
<div :class="getUptimeBadgeColor(server.uptime_24h_percent)" class="flex-1 rounded-lg px-2 py-1.5 text-center">
<div class="text-xs font-medium">{{ server.uptime_24h_percent.toFixed(1) }}%</div>
<div class="text-xs font-medium">{{ safeFixed(server.uptime_24h_percent, 1) }}%</div>
<div class="text-[10px] opacity-75">24h</div>
</div>
<div :class="getUptimeBadgeColor(server.uptime_7d_percent)" class="flex-1 rounded-lg px-2 py-1.5 text-center">
<div class="text-xs font-medium">{{ server.uptime_7d_percent.toFixed(1) }}%</div>
<div class="text-xs font-medium">{{ safeFixed(server.uptime_7d_percent, 1) }}%</div>
<div class="text-[10px] opacity-75">7d</div>
</div>
<div :class="getUptimeBadgeColor(server.uptime_30d_percent)" class="flex-1 rounded-lg px-2 py-1.5 text-center">
<div class="text-xs font-medium">{{ server.uptime_30d_percent.toFixed(1) }}%</div>
<div class="text-xs font-medium">{{ safeFixed(server.uptime_30d_percent, 1) }}%</div>
<div class="text-[10px] opacity-75">30d</div>
</div>
</div>

View File

@@ -3,6 +3,7 @@ import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import type { PublicStoreInfo, PublicStoreItem, StorePurchaseRequest, StorePurchaseResponse } from '@/types'
import { ShoppingCart, Package, Filter, X, AlertCircle, ExternalLink, Check } from 'lucide-vue-next'
import { safeCurrency } from '@/utils/formatters'
const route = useRoute()
const subdomain = computed(() => route.params.subdomain as string)
@@ -138,7 +139,7 @@ async function confirmPurchase() {
}
function formatPrice(price: number): string {
return `$${price.toFixed(2)}`
return safeCurrency(price, '$')
}
function itemTypeBadgeClass(itemType: string): string {