76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { createFileRoute } from "@tanstack/react-router";
|
|
import { prefetchServerQuery } from "@/lib/tanstack-query/utils/prefetch";
|
|
import { ActivitiesTable, activityQueries } from "@/features/activities";
|
|
import { PlayersActivityTable, playerQueries } from "@/features/players";
|
|
import { Box, Divider, Group, Skeleton, Stack, Tabs } from "@mantine/core";
|
|
import { Suspense, useState } from "react";
|
|
import { Trans } from "@lingui/react/macro";
|
|
import { msg } from "@lingui/core/macro";
|
|
|
|
export const Route = createFileRoute("/_authed/admin/activities")({
|
|
component: Stats,
|
|
beforeLoad: ({ context }) => {
|
|
const queryClient = context.queryClient;
|
|
prefetchServerQuery(queryClient, activityQueries.search());
|
|
prefetchServerQuery(queryClient, playerQueries.activity());
|
|
},
|
|
loader: () => ({
|
|
withPadding: false,
|
|
fullWidth: true,
|
|
header: {
|
|
title: msg`Activities`,
|
|
withBackButton: true,
|
|
},
|
|
refresh: [activityQueries.search().queryKey, playerQueries.activity().queryKey],
|
|
}),
|
|
});
|
|
|
|
function ActivityRowsSkeleton({ withSearch = false }: { withSearch?: boolean }) {
|
|
return (
|
|
<Stack gap={0}>
|
|
{withSearch && (
|
|
<Box px="md" pb="sm">
|
|
<Skeleton height={42} radius="sm" />
|
|
</Box>
|
|
)}
|
|
{Array.from({ length: 8 }).map((_, index) => (
|
|
<div key={`activity-skeleton-${index}`} style={{ opacity: Math.max(1 - index * 0.1, 0.35) }}>
|
|
<Group p="md" wrap="nowrap" w="100%" justify="space-between">
|
|
<Stack gap={6}>
|
|
<Skeleton height={14} width={160} radius="sm" />
|
|
<Skeleton height={10} width={100} radius="sm" />
|
|
</Stack>
|
|
<Skeleton height={10} width={60} radius="sm" />
|
|
</Group>
|
|
<Divider />
|
|
</div>
|
|
))}
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
function Stats() {
|
|
const [activeTab, setActiveTab] = useState<string | null>("server-functions");
|
|
|
|
return (
|
|
<Tabs value={activeTab} onChange={setActiveTab}>
|
|
<Tabs.List mb='md'>
|
|
<Tabs.Tab value="server-functions"><Trans>Server Functions</Trans></Tabs.Tab>
|
|
<Tabs.Tab value="player-activity"><Trans>Player Activity</Trans></Tabs.Tab>
|
|
</Tabs.List>
|
|
|
|
<Tabs.Panel value="server-functions">
|
|
<Suspense fallback={<ActivityRowsSkeleton withSearch />}>
|
|
<ActivitiesTable />
|
|
</Suspense>
|
|
</Tabs.Panel>
|
|
|
|
<Tabs.Panel value="player-activity">
|
|
<Suspense fallback={<ActivityRowsSkeleton />}>
|
|
<PlayersActivityTable />
|
|
</Suspense>
|
|
</Tabs.Panel>
|
|
</Tabs>
|
|
);
|
|
}
|