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
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user