From cdef88e55e11ac7defb8feef73f3288953958647 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Sat, 12 Aug 2023 17:11:41 +0200 Subject: [PATCH] add: some util to dashboard --- pkgs/ui/README.md | 18 +- pkgs/ui/prettier.config.cjs | 4 + pkgs/ui/src/app/layout.tsx | 4 +- pkgs/ui/src/app/nodes/NodeList.tsx | 14 +- pkgs/ui/src/app/nodes/NodePieChart.tsx | 2 +- pkgs/ui/src/app/nodes/page.tsx | 89 +-------- pkgs/ui/src/app/nodes/styles.module.css | 0 pkgs/ui/src/app/page.tsx | 27 ++- pkgs/ui/src/components/card/index.tsx | 21 ++- .../dashboard/NetworkOverview/index.tsx | 74 ++++++++ .../components/dashboard/activity/index.tsx | 12 ++ .../dashboard/notifications/index.tsx | 73 ++++++++ .../ui/src/components/noDataOverlay/index.tsx | 80 +++++++++ pkgs/ui/src/components/quickActions/index.tsx | 11 ++ pkgs/ui/src/components/sidebar/index.tsx | 2 +- pkgs/ui/src/data/dashboardData.tsx | 170 ++++++++++++++++++ pkgs/ui/src/data/nodeData.tsx | 97 ++++++++++ 17 files changed, 582 insertions(+), 116 deletions(-) create mode 100644 pkgs/ui/prettier.config.cjs delete mode 100644 pkgs/ui/src/app/nodes/styles.module.css create mode 100644 pkgs/ui/src/components/dashboard/NetworkOverview/index.tsx create mode 100644 pkgs/ui/src/components/dashboard/activity/index.tsx create mode 100644 pkgs/ui/src/components/dashboard/notifications/index.tsx create mode 100644 pkgs/ui/src/components/noDataOverlay/index.tsx create mode 100644 pkgs/ui/src/components/quickActions/index.tsx create mode 100644 pkgs/ui/src/data/dashboardData.tsx create mode 100644 pkgs/ui/src/data/nodeData.tsx diff --git a/pkgs/ui/README.md b/pkgs/ui/README.md index 93a122f01..6077578bf 100644 --- a/pkgs/ui/README.md +++ b/pkgs/ui/README.md @@ -1,5 +1,22 @@ # cLan - awesome UI +## Prettier + +To use prettier and the plugins using vscode/vscodium the `prettier.config.js` needs to be at the root level of the editor's file explorer + +`cd clan-core/pkgs/ui && code .` + +When inspecting `OUTPUT > Prettier` the config should've been loaded: + +```sh +["INFO" - 1:47:43 PM] Formatting completed in 48ms. +["INFO" - 1:48:07 PM] Using config file at '.../clan-core/pkgs/ui/prettier.config.cjs' +``` + +If you have enabled `formatOnSave` the tailwind classes should get sorted into the officially recommended order. + +`prettier -w ./src/ --config prettier.config.cjs` + ## Commands After changing dependencies with @@ -17,4 +34,3 @@ To sort classnames manually: `cd /clan-core/pkgs/ui/` -`prettier -w ./src/ --config pconf.cjs` diff --git a/pkgs/ui/prettier.config.cjs b/pkgs/ui/prettier.config.cjs new file mode 100644 index 000000000..fa7765f54 --- /dev/null +++ b/pkgs/ui/prettier.config.cjs @@ -0,0 +1,4 @@ +// prettier.config.js +module.exports = { + plugins: ["prettier-plugin-tailwindcss"], +}; diff --git a/pkgs/ui/src/app/layout.tsx b/pkgs/ui/src/app/layout.tsx index 82233b193..224c83a9f 100644 --- a/pkgs/ui/src/app/layout.tsx +++ b/pkgs/ui/src/app/layout.tsx @@ -71,7 +71,7 @@ export default function RootLayout({
@@ -96,7 +96,7 @@ export default function RootLayout({
-
+
{children}
diff --git a/pkgs/ui/src/app/nodes/NodeList.tsx b/pkgs/ui/src/app/nodes/NodeList.tsx index e52a4cc70..f00dee905 100644 --- a/pkgs/ui/src/app/nodes/NodeList.tsx +++ b/pkgs/ui/src/app/nodes/NodeList.tsx @@ -38,19 +38,7 @@ import { } from "@mui/material"; import hexRgb from "hex-rgb"; import useMediaQuery from "@mui/material/useMediaQuery"; - -export interface TableData { - name: string; - id: string; - status: NodeStatus; - last_seen: number; -} - -export enum NodeStatus { - Online, - Offline, - Pending, -} +import { NodeStatus, TableData } from "@/data/nodeData"; interface HeadCell { disablePadding: boolean; diff --git a/pkgs/ui/src/app/nodes/NodePieChart.tsx b/pkgs/ui/src/app/nodes/NodePieChart.tsx index 6e715826e..12ed80418 100644 --- a/pkgs/ui/src/app/nodes/NodePieChart.tsx +++ b/pkgs/ui/src/app/nodes/NodePieChart.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent } from "react"; +import React from "react"; import { PieChart, Pie, diff --git a/pkgs/ui/src/app/nodes/page.tsx b/pkgs/ui/src/app/nodes/page.tsx index 03993bb5f..3e4190ba9 100644 --- a/pkgs/ui/src/app/nodes/page.tsx +++ b/pkgs/ui/src/app/nodes/page.tsx @@ -1,94 +1,9 @@ "use client"; -import { StrictMode } from "react"; -import NodeList, { NodeStatus, TableData } from "./NodeList"; +import NodeList from "./NodeList"; import Box from "@mui/material/Box"; - -function createData( - name: string, - id: string, - status: NodeStatus, - last_seen: number, -): TableData { - return { - name, - id, - status, - last_seen: last_seen, - }; -} - -const tableData = [ - createData( - "Matchbox", - "42:0:f21:6916:e333:c47e:4b5c:e74c", - NodeStatus.Pending, - 0, - ), - createData( - "Ahorn", - "42:0:3c46:b51c:b34d:b7e1:3b02:8d24", - NodeStatus.Online, - 0, - ), - createData( - "Yellow", - "42:0:3c46:98ac:9c80:4f25:50e3:1d8f", - NodeStatus.Offline, - 16.0, - ), - createData( - "Rauter", - "42:0:61ea:b777:61ea:803:f885:3523", - NodeStatus.Offline, - 6.0, - ), - createData( - "Porree", - "42:0:e644:4499:d034:895e:34c8:6f9a", - NodeStatus.Offline, - 13, - ), - createData( - "Helsinki", - "42:0:3c46:fd4a:acf9:e971:6036:8047", - NodeStatus.Online, - 0, - ), - createData( - "Kelle", - "42:0:3c46:362d:a9aa:4996:c78e:839a", - NodeStatus.Online, - 0, - ), - createData( - "Shodan", - "42:0:3c46:6745:adf4:a844:26c4:bf91", - NodeStatus.Online, - 0.0, - ), - createData( - "Qubasa", - "42:0:3c46:123e:bbea:3529:db39:6764", - NodeStatus.Offline, - 7.0, - ), - createData( - "Green", - "42:0:a46e:5af:632c:d2fe:a71d:cde0", - NodeStatus.Offline, - 2, - ), - createData("Gum", "42:0:e644:238d:3e46:c884:6ec5:16c", NodeStatus.Offline, 0), - createData("Xu", "42:0:ca48:c2c2:19fb:a0e9:95b9:794f", NodeStatus.Online, 0), - createData( - "Zaatar", - "42:0:3c46:156e:10b6:3bd6:6e82:b2cd", - NodeStatus.Online, - 0, - ), -]; +import { tableData } from "@/data/nodeData"; export default function Page() { return ( diff --git a/pkgs/ui/src/app/nodes/styles.module.css b/pkgs/ui/src/app/nodes/styles.module.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/pkgs/ui/src/app/page.tsx b/pkgs/ui/src/app/page.tsx index 093b3e98a..432dc4a60 100644 --- a/pkgs/ui/src/app/page.tsx +++ b/pkgs/ui/src/app/page.tsx @@ -1,10 +1,15 @@ +import { RecentActivity } from "@/components/dashboard/activity"; +import { NetworkOverview } from "@/components/dashboard/NetworkOverview"; +import { Notifications } from "@/components/dashboard/notifications"; +import { QuickActions } from "@/components/quickActions"; + interface DashboardCardProps { children?: React.ReactNode; } const DashboardCard = (props: DashboardCardProps) => { const { children } = props; return ( -
+
{children}
); @@ -16,7 +21,7 @@ interface DashboardPanelProps { const DashboardPanel = (props: DashboardPanelProps) => { const { children } = props; return ( -
+
{children}
); @@ -28,12 +33,12 @@ interface SplitDashboardCardProps { const SplitDashboardCard = (props: SplitDashboardCardProps) => { const { children } = props; return ( -
+
{children?.map((row, idx) => (
{row}
@@ -46,12 +51,16 @@ const SplitDashboardCard = (props: SplitDashboardCardProps) => { export default function Dashboard() { return (
-
- Current CLAN Overview - Recent Activity Log +
+ + + + + + -
Notifications
-
Quick Action
+ +
Panel Side Bar (misc) diff --git a/pkgs/ui/src/components/card/index.tsx b/pkgs/ui/src/components/card/index.tsx index 4639b21ec..ad7942067 100644 --- a/pkgs/ui/src/components/card/index.tsx +++ b/pkgs/ui/src/components/card/index.tsx @@ -1,5 +1,22 @@ -import { Card } from "@mui/material"; +import { Typography } from "@mui/material"; +import { ReactNode } from "react"; -const DashboardCard = Card; +interface DashboardCardProps { + title: string; + children?: ReactNode; +} +const DashboardCard = (props: DashboardCardProps) => { + const { children, title } = props; + return ( +
+
+ + {title} + + {children} +
+
+ ); +}; export { DashboardCard }; diff --git a/pkgs/ui/src/components/dashboard/NetworkOverview/index.tsx b/pkgs/ui/src/components/dashboard/NetworkOverview/index.tsx new file mode 100644 index 000000000..ed7c10848 --- /dev/null +++ b/pkgs/ui/src/components/dashboard/NetworkOverview/index.tsx @@ -0,0 +1,74 @@ +import { DashboardCard } from "@/components/card"; +import { NoDataOverlay } from "@/components/noDataOverlay"; +import { status, Status, clanStatus } from "@/data/dashboardData"; +import { + Chip, + Divider, + List, + ListItem, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; +import Link from "next/link"; +import React from "react"; + +const statusColorMap: Record< + Status, + "default" | "primary" | "secondary" | "error" | "info" | "success" | "warning" +> = { + online: "info", + offline: "error", + pending: "default", +}; + +const MAX_OTHERS = 5; + +export const NetworkOverview = () => { + const { self, other } = clanStatus; + + const firstOthers = other.slice(0, MAX_OTHERS); + return ( + + + + + + + + + + {!other.length && ( +
+ Add devices} + /> + } + /> +
+ )} + {firstOthers.map((o) => ( + + + + + + + ))} + {other.length > MAX_OTHERS && ( + + + + )} +
+
+ ); +}; diff --git a/pkgs/ui/src/components/dashboard/activity/index.tsx b/pkgs/ui/src/components/dashboard/activity/index.tsx new file mode 100644 index 000000000..a65b663fc --- /dev/null +++ b/pkgs/ui/src/components/dashboard/activity/index.tsx @@ -0,0 +1,12 @@ +import { DashboardCard } from "@/components/card"; +import { NoDataOverlay } from "@/components/noDataOverlay"; + +export const RecentActivity = () => { + return ( + +
+ +
+
+ ); +}; diff --git a/pkgs/ui/src/components/dashboard/notifications/index.tsx b/pkgs/ui/src/components/dashboard/notifications/index.tsx new file mode 100644 index 000000000..769311486 --- /dev/null +++ b/pkgs/ui/src/components/dashboard/notifications/index.tsx @@ -0,0 +1,73 @@ +import { DashboardCard } from "@/components/card"; +import { notificationData } from "@/data/dashboardData"; +import { tw } from "@/utils/tailwind"; +import { + Avatar, + Chip, + List, + ListItem, + ListItemAvatar, + ListItemButton, + ListItemIcon, + ListItemText, +} from "@mui/material"; +import { Label } from "recharts"; + +import CheckIcon from "@mui/icons-material/Check"; +import InfoIcon from "@mui/icons-material/Info"; +import PriorityHighIcon from "@mui/icons-material/PriorityHigh"; +import CloseIcon from "@mui/icons-material/Close"; + +const severityMap = { + info: { + icon: , + color: "info", + }, + success: { + icon: , + color: "success", + }, + warning: { + icon: , + color: "warning", + }, + error: { + icon: , + color: "error", + }, +}; + +export const Notifications = () => { + return ( + + + {notificationData.map((n, idx) => ( + + + + {severityMap[n.severity].icon} + + + + + + ))} + + + ); +}; diff --git a/pkgs/ui/src/components/noDataOverlay/index.tsx b/pkgs/ui/src/components/noDataOverlay/index.tsx new file mode 100644 index 000000000..51904272f --- /dev/null +++ b/pkgs/ui/src/components/noDataOverlay/index.tsx @@ -0,0 +1,80 @@ +"use client"; + +import * as React from "react"; +import Box from "@mui/material/Box"; +import { styled } from "@mui/material/styles"; + +const StyledGridOverlay = styled("div")(({ theme }) => ({ + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + height: "100%", + "& .ant-empty-img-1": { + fill: theme.palette.mode === "light" ? "#aeb8c2" : "#262626", + }, + "& .ant-empty-img-2": { + fill: theme.palette.mode === "light" ? "#f5f5f7" : "#595959", + }, + "& .ant-empty-img-3": { + fill: theme.palette.mode === "light" ? "#dce0e6" : "#434343", + }, + "& .ant-empty-img-4": { + fill: theme.palette.mode === "light" ? "#fff" : "#1c1c1c", + }, + "& .ant-empty-img-5": { + fillOpacity: theme.palette.mode === "light" ? "0.8" : "0.08", + fill: theme.palette.mode === "light" ? "#f5f5f5" : "#fff", + }, +})); + +interface NoDataOverlayProps { + label: React.ReactNode; +} +export function NoDataOverlay(props: NoDataOverlayProps) { + const { label } = props; + return ( + + + + + + + + + + + + + + + + + {label} + + ); +} diff --git a/pkgs/ui/src/components/quickActions/index.tsx b/pkgs/ui/src/components/quickActions/index.tsx new file mode 100644 index 000000000..20794a769 --- /dev/null +++ b/pkgs/ui/src/components/quickActions/index.tsx @@ -0,0 +1,11 @@ +import { Button } from "@mui/material"; + +export const QuickActions = () => { + return ( +
+ + + +
+ ); +}; diff --git a/pkgs/ui/src/components/sidebar/index.tsx b/pkgs/ui/src/components/sidebar/index.tsx index 843456733..b5ff6bd05 100644 --- a/pkgs/ui/src/components/sidebar/index.tsx +++ b/pkgs/ui/src/components/sidebar/index.tsx @@ -76,7 +76,7 @@ export function Sidebar(props: SidebarProps) {