Files
flxn-app/src/features/admin/components/dashboard/errors-card.tsx
T
kyle a52872bea8 feat(admin): dashboard home, telemetry section, enrollment ops screen
- mission-control dashboard: now strip, tournament quick actions, usage
  sparklines, error feed, live activity, tools list
- /admin/telemetry with functions/events/errors/players/usage child routes,
  hand-rolled svg chart primitives, decomposed activities table
- error browser with grouping and mark-resolved
- consolidated per-tournament enrollment screen; hub simplified with
  run tournament promoted
- /admin/activities redirects to /admin/telemetry/functions
2026-08-25 21:54:21 -07:00

63 lines
2.3 KiB
TypeScript

import { Badge, Card, Group, Stack, Text, UnstyledButton } from "@mantine/core";
import { Trans } from "@lingui/react/macro";
import { useNavigate } from "@tanstack/react-router";
import { CheckCircleIcon, WarningCircleIcon } from "@phosphor-icons/react";
import { useClientErrorGroups } from "@/features/telemetry/queries";
import { RelativeTime } from "@/features/telemetry/components/shared";
import { lastNDays } from "@/features/telemetry/range";
export const ErrorsCard = () => {
const navigate = useNavigate();
const range = lastNDays(30);
const { data: groups } = useClientErrorGroups({ from: range.from, to: range.to });
return (
<UnstyledButton w="100%" onClick={() => navigate({ to: "/admin/telemetry/errors" })}>
<Card withBorder radius="md" p="md">
<Stack gap="sm">
<Group justify="space-between" wrap="nowrap">
<Text fw={600} size="sm">
<Trans>Client errors</Trans>
</Text>
{groups && groups.length > 0 ? (
<Badge color="red" variant="light">
{groups.length}
</Badge>
) : (
<CheckCircleIcon size={18} color="var(--mantine-color-green-6)" weight="fill" />
)}
</Group>
{groups && groups.length > 0 ? (
<Stack gap="xs">
{groups.slice(0, 3).map((group) => (
<Group key={group.group_hash} gap="xs" wrap="nowrap" align="flex-start">
<WarningCircleIcon
size={14}
color="var(--mantine-color-red-6)"
style={{ flexShrink: 0, marginTop: 2 }}
/>
<Stack gap={0} style={{ minWidth: 0 }}>
<Text size="xs" lineClamp={1}>
{group.sample.message}
</Text>
<Text size="xs" c="dimmed">
<RelativeTime date={group.lastSeen} />
</Text>
</Stack>
</Group>
))}
</Stack>
) : (
<Text size="sm" c="dimmed">
<Trans>No unresolved errors</Trans>
</Text>
)}
</Stack>
</Card>
</UnstyledButton>
);
};
export default ErrorsCard;