feat: modernize dashboard widgets
This commit is contained in:
1 parent
1a5e083fd0
commit
6f2cd7fc2b
270 files changed
+10189
-3544
No files matched your search
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { Box, Center, List, Text, useMantineTheme } from "@mantine/core";
|
||||
import { Badge, Card, Group, List, ScrollArea, SimpleGrid, Stack, Text, useMantineTheme } from "@mantine/core";
|
||||
import { IconCircleCheckFilled, IconCircleXFilled } from "@tabler/icons-react";
|
||||
import dayjs from "dayjs";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
@@ -19,6 +18,8 @@ dayjs.extend(duration);
|
||||
|
||||
export default function NetworkControllerSummaryWidget({
|
||||
integrationIds,
|
||||
width,
|
||||
displayMode,
|
||||
}: WidgetComponentProps<"networkControllerSummary">) {
|
||||
const { data: summaries = [] } = clientApi.widget.networkController.summary.useQuery({
|
||||
integrationIds,
|
||||
@@ -26,33 +27,57 @@ export default function NetworkControllerSummaryWidget({
|
||||
|
||||
const t = useI18n();
|
||||
|
||||
const data = useMemo(() => summaries.flatMap(({ summary }) => summary), [summaries]);
|
||||
const isAdvanced = displayMode === "advanced";
|
||||
const columns = isAdvanced && width >= 720 ? 2 : 1;
|
||||
|
||||
return (
|
||||
<Box h="100%" p="sm">
|
||||
<Center h={"100%"}>
|
||||
<List spacing={"xs"} center>
|
||||
<List.Item icon={<StatusIcon status={data[0]?.wanStatus} />}>WAN</List.Item>
|
||||
<List.Item icon={<StatusIcon status={data[0]?.www.status} />}>
|
||||
<Text>
|
||||
WWW
|
||||
<Text c={"dimmed"} size={"md"} ms={"xs"} span>
|
||||
{data[0]?.www.latency}ms
|
||||
</Text>
|
||||
</Text>
|
||||
</List.Item>
|
||||
<List.Item icon={<StatusIcon status={data[0]?.wifi.status} />}>Wi-Fi</List.Item>
|
||||
<List.Item icon={<StatusIcon status={data[0]?.vpn.status} />}>
|
||||
<Text>
|
||||
VPN
|
||||
<Text c={"dimmed"} size={"md"} ms={"xs"} span>
|
||||
{t("widget.networkControllerSummary.card.vpn.countConnected", { count: `${data[0]?.vpn.users}` })}
|
||||
</Text>
|
||||
</Text>
|
||||
</List.Item>
|
||||
</List>
|
||||
</Center>
|
||||
</Box>
|
||||
<ScrollArea h="100%" p={isAdvanced ? "md" : "sm"}>
|
||||
<SimpleGrid cols={columns} spacing="sm">
|
||||
{summaries.map(({ integration, summary }) => (
|
||||
<Card key={integration.id} p={isAdvanced ? "md" : "xs"} withBorder={summaries.length > 1 || isAdvanced}>
|
||||
<Stack gap="xs">
|
||||
{(isAdvanced || summaries.length > 1) && (
|
||||
<Group justify="space-between" wrap="nowrap">
|
||||
<Text fw={600} size="sm" truncate="end">
|
||||
{integration.name}
|
||||
</Text>
|
||||
<Badge size="xs" variant="light">
|
||||
{integration.kind}
|
||||
</Badge>
|
||||
</Group>
|
||||
)}
|
||||
<List spacing="xs" center>
|
||||
<List.Item icon={<StatusIcon status={summary.wanStatus} />}>WAN</List.Item>
|
||||
<List.Item icon={<StatusIcon status={summary.www.status} />}>
|
||||
<Text>
|
||||
WWW
|
||||
<Text c="dimmed" size="sm" ms="xs" span>
|
||||
{summary.www.latency}ms{isAdvanced ? ` · ${summary.www.ping}ms` : ""}
|
||||
</Text>
|
||||
</Text>
|
||||
</List.Item>
|
||||
<List.Item icon={<StatusIcon status={summary.wifi.status} />}>
|
||||
Wi-Fi{isAdvanced ? ` · ${summary.wifi.users + summary.wifi.guests}` : ""}
|
||||
</List.Item>
|
||||
{isAdvanced && (
|
||||
<List.Item icon={<StatusIcon status={summary.lan.status} />}>
|
||||
LAN · {summary.lan.users + summary.lan.guests}
|
||||
</List.Item>
|
||||
)}
|
||||
<List.Item icon={<StatusIcon status={summary.vpn.status} />}>
|
||||
<Text>
|
||||
VPN
|
||||
<Text c="dimmed" size="sm" ms="xs" span>
|
||||
{t("widget.networkControllerSummary.card.vpn.countConnected", { count: `${summary.vpn.users}` })}
|
||||
</Text>
|
||||
</Text>
|
||||
</List.Item>
|
||||
</List>
|
||||
</Stack>
|
||||
</Card>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</ScrollArea>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,5 +86,6 @@ const StatusIcon = ({ status }: { status?: "enabled" | "disabled" }) => {
|
||||
if (status === "enabled") {
|
||||
return <IconCircleCheckFilled size={20} color={mantineTheme.colors.green[6]} />;
|
||||
}
|
||||
return <IconCircleXFilled size={20} color={mantineTheme.colors.red[6]} />;
|
||||
if (status === "disabled") return <IconCircleXFilled size={20} color={mantineTheme.colors.red[6]} />;
|
||||
return <IconCircleXFilled size={20} color={mantineTheme.colors.gray[6]} />;
|
||||
};
|
||||
Reference in new issue
Block a user