Add analytics plugin package for tracking and metrics. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
131 lines
4.1 KiB
TypeScript
131 lines
4.1 KiB
TypeScript
import React, { useState } from 'react'
|
|
|
|
import {
|
|
useErrorMetrics,
|
|
useErrorsByType,
|
|
useRecentErrors,
|
|
} from '../hooks/useAdminQuery'
|
|
|
|
export const ErrorTrackingPage: React.FC = () => {
|
|
const { data: metrics, isLoading, isError } = useErrorMetrics()
|
|
const { data: byType } = useErrorsByType()
|
|
const { data: recentErrors } = useRecentErrors()
|
|
const [_severityFilter, setSeverityFilter] = useState('All')
|
|
const [_statusFilter, setStatusFilter] = useState('All')
|
|
|
|
if (isLoading) {
|
|
return <div>Loading error data...</div>
|
|
}
|
|
|
|
if (isError) {
|
|
return <div>Failed to load error data</div>
|
|
}
|
|
|
|
const hasCriticalErrors = (metrics?.criticalErrors ?? 0) > 0
|
|
|
|
return (
|
|
<div className="error-tracking-page">
|
|
<h1 data-testid="page-title">Error Tracking</h1>
|
|
|
|
{/* Critical Error Alert */}
|
|
{hasCriticalErrors && (
|
|
<div className="critical-alert">Critical Errors Detected</div>
|
|
)}
|
|
|
|
{/* KPI Cards */}
|
|
<div className="kpi-cards">
|
|
<div className="kpi-card">
|
|
<div className="kpi-label">Total Errors</div>
|
|
<div className="kpi-value">{metrics?.totalErrors.toLocaleString()}</div>
|
|
</div>
|
|
<div className="kpi-card">
|
|
<div className="kpi-label">Error Rate</div>
|
|
<div className="kpi-value">{metrics?.errorRate}%</div>
|
|
</div>
|
|
<div className="kpi-card">
|
|
<div className="kpi-label">Critical Errors</div>
|
|
<div className="kpi-value">{metrics?.criticalErrors}</div>
|
|
</div>
|
|
<div className="kpi-card">
|
|
<div className="kpi-label">Resolved Errors</div>
|
|
<div className="kpi-value">{metrics?.resolvedErrors.toLocaleString()}</div>
|
|
</div>
|
|
<div className="kpi-card">
|
|
<div className="kpi-label">Avg Resolution Time</div>
|
|
<div className="kpi-value">{metrics?.avgResolutionTime} hours</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Errors by Type */}
|
|
<div className="errors-by-type">
|
|
<h2>Errors by Type</h2>
|
|
{byType?.map((type, idx) => (
|
|
<div key={idx}>
|
|
<div>{type.type}</div>
|
|
<div>{type.count}</div>
|
|
<div>{type.percentage}%</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Error Trends */}
|
|
<div className="error-trends">
|
|
<h2>Error Trends</h2>
|
|
<div className="chart">Chart placeholder</div>
|
|
</div>
|
|
|
|
{/* Filters */}
|
|
<div className="filters">
|
|
<div>
|
|
<button onClick={() => setSeverityFilter('All')}>All</button>
|
|
<button onClick={() => setSeverityFilter('Critical')}>Critical</button>
|
|
<button onClick={() => setSeverityFilter('Medium')}>Medium</button>
|
|
<button onClick={() => setSeverityFilter('Low')}>Low</button>
|
|
</div>
|
|
<div>
|
|
<button onClick={() => setStatusFilter('Open')}>Open</button>
|
|
<button onClick={() => setStatusFilter('Investigating')}>Investigating</button>
|
|
<button onClick={() => setStatusFilter('Resolved')}>Resolved</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Recent Errors Table */}
|
|
<div className="recent-errors">
|
|
<h2>Recent Errors</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Type</th>
|
|
<th>Message</th>
|
|
<th>Endpoint</th>
|
|
<th>Count</th>
|
|
<th>Last Occurrence</th>
|
|
<th>Severity</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{recentErrors?.map((error) => (
|
|
<tr key={error.id}>
|
|
<td>{error.id}</td>
|
|
<td>{error.type}</td>
|
|
<td>{error.message}</td>
|
|
<td>{error.endpoint}</td>
|
|
<td>{error.count}</td>
|
|
<td>{error.lastOccurrence}</td>
|
|
<td>{error.severity}</td>
|
|
<td>{error.status}</td>
|
|
<td>
|
|
<button>View Details</button>
|
|
{error.status !== 'resolved' && <button>Resolve</button>}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|