gitscope
← marzneshin / v0.2.1 / app/dashboard/src/pages/nodes/usage.tsx
https://dev.kronoz.win/r/marzneshin.git
app/dashboard/src/pages/nodes/usage.tsx · TypeScript
Blame Raw
 1import {
 2  Box,
 3  CircularProgress,
 4  VStack,
 5  chakra,
 6  useColorMode,
 7} from '@chakra-ui/react';
 8import { ChartPieIcon } from '@heroicons/react/24/outline';
 9import { FilterUsageType } from 'types/filter';
10import { useNodes } from 'stores';
11import dayjs from 'dayjs';
12import { FC, Suspense, useEffect, useState } from 'react';
13import ReactApexChart from 'react-apexcharts';
14import { useTranslation } from 'react-i18next';
15import { Icon } from 'components/icon';
16import { UsageFilter, createUsageConfig } from 'components/usage-filter';
17import { StatisticsCardWide } from 'components/statistics-card';
18
19const UsageIcon = chakra(ChartPieIcon, {
20  baseStyle: {
21    w: 5,
22    h: 5,
23  },
24});
25
26export type NodesUsageProps = {};
27
28export const NodesUsage: FC<NodesUsageProps> = () => {
29  const { isShowingNodesUsage } = useNodes();
30  const { fetchNodesUsage } = useNodes();
31  const { t } = useTranslation();
32  const { colorMode } = useColorMode();
33
34  const usageTitle = t('userDialog.total');
35  const [usage, setUsage] = useState(createUsageConfig(colorMode, usageTitle));
36  const [usageFilter, setUsageFilter] = useState('1m');
37  const fetchUsageWithFilter = (query: FilterUsageType) => {
38    fetchNodesUsage(query).then((data: any) => {
39      const labels = [];
40      const series = [];
41      for (const key in data.usages) {
42        const entry = data.usages[key];
43        series.push(entry.uplink + entry.downlink);
44        labels.push(entry.node_name);
45      }
46      setUsage(createUsageConfig(colorMode, usageTitle, series, labels));
47    });
48  };
49
50  useEffect(() => {
51    if (isShowingNodesUsage) {
52      fetchUsageWithFilter({
53        start: dayjs().utc().subtract(30, 'day').format('YYYY-MM-DDTHH:00:00'),
54      });
55    }
56  }, [isShowingNodesUsage]);
57
58  return (
59    <StatisticsCardWide
60      title={t('header.nodesUsage')}
61      icon={<Icon color="primary">
62        <UsageIcon color="white" /> </Icon>}
63      content={
64        <VStack gap={4}>
65          <UsageFilter
66            defaultValue={usageFilter}
67            onChange={(filter, query) => {
68              setUsageFilter(filter);
69              fetchUsageWithFilter(query);
70            }}
71          />
72          <Box justifySelf="center" w="full" maxW="300px" mt="4">
73            <Suspense fallback={<CircularProgress isIndeterminate />}>
74              <ReactApexChart
75                options={usage.options}
76                series={usage.series}
77                type="donut"
78                height="500px"
79              />
80            </Suspense>
81          </Box>
82        </VStack>
83
84      } />
85  );
86};