From 190f9f5f73ccd99d665710f28fe1c6829295c61b Mon Sep 17 00:00:00 2001 From: oxdev03 <140103378+oxdev03@users.noreply.github.com> Date: Sun, 28 Jun 2026 12:31:44 +0200 Subject: [PATCH 1/2] refactor: remove CSS modules in favor of native Mantine components and utility classes --- .../components/layouts/Dashboard.module.css | 8 - .../components/layouts/Dashboard.tsx | 35 ++--- .../components/partials/Head.module.css | 42 ------ apps/dashboard/components/partials/Head.tsx | 78 ++++------ .../components/partials/Nav.module.css | 67 --------- apps/dashboard/components/partials/Nav.tsx | 76 ++++------ .../components/process/ProcessActionRow.tsx | 23 +-- .../components/process/ProcessGitMetric.tsx | 19 ++- .../components/process/ProcessHeader.tsx | 6 +- .../components/process/ProcessItem.tsx | 28 ++-- .../components/process/ProcessLog.tsx | 10 +- .../components/process/ProcessMetric.tsx | 14 +- .../components/process/ProcessMetricRow.tsx | 48 ++++-- .../settings/UpdateConfiguration.module.css | 7 - .../settings/UpdateConfiguration.tsx | 26 ++-- .../components/stats/StatsRing.module.css | 11 -- apps/dashboard/components/stats/StatsRing.tsx | 12 +- .../components/user/table/UserItem.module.css | 3 - .../components/user/table/UserItem.tsx | 4 +- apps/dashboard/pages/_app.tsx | 2 +- apps/dashboard/pages/index.tsx | 141 +++++++++++------- apps/dashboard/pages/settings.tsx | 23 +-- apps/dashboard/pages/user.tsx | 65 +++----- apps/dashboard/styles/index.module.css | 9 -- apps/dashboard/styles/process.module.css | 51 ------- apps/dashboard/styles/user.module.css | 21 --- 26 files changed, 286 insertions(+), 543 deletions(-) delete mode 100644 apps/dashboard/components/layouts/Dashboard.module.css delete mode 100644 apps/dashboard/components/partials/Head.module.css delete mode 100644 apps/dashboard/components/partials/Nav.module.css delete mode 100644 apps/dashboard/components/settings/UpdateConfiguration.module.css delete mode 100644 apps/dashboard/components/stats/StatsRing.module.css delete mode 100644 apps/dashboard/components/user/table/UserItem.module.css delete mode 100644 apps/dashboard/styles/index.module.css delete mode 100644 apps/dashboard/styles/process.module.css delete mode 100644 apps/dashboard/styles/user.module.css diff --git a/apps/dashboard/components/layouts/Dashboard.module.css b/apps/dashboard/components/layouts/Dashboard.module.css deleted file mode 100644 index d71fa47..0000000 --- a/apps/dashboard/components/layouts/Dashboard.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.appShellRoot { - background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-9)); -} - -.appShellMain { - display: flex; - flex-direction: column; -} diff --git a/apps/dashboard/components/layouts/Dashboard.tsx b/apps/dashboard/components/layouts/Dashboard.tsx index eb94ea1..e10f50f 100644 --- a/apps/dashboard/components/layouts/Dashboard.tsx +++ b/apps/dashboard/components/layouts/Dashboard.tsx @@ -1,26 +1,27 @@ -import { AppShell } from "@mantine/core"; +import { AppShell, Container } from "@mantine/core"; +import { useDisclosure } from "@mantine/hooks"; import { ReactNode } from "react"; import { Head } from "../partials/Head"; import { Nav } from "../partials/Nav"; -import classes from "./Dashboard.module.css"; export function Dashboard({ children }: { children: ReactNode }) { + const [mobileOpened, { toggle: toggleMobile }] = useDisclosure(); + return ( - <> - - - - {children} - - > + + + + + + {children} + + + ); } diff --git a/apps/dashboard/components/partials/Head.module.css b/apps/dashboard/components/partials/Head.module.css deleted file mode 100644 index 380be6e..0000000 --- a/apps/dashboard/components/partials/Head.module.css +++ /dev/null @@ -1,42 +0,0 @@ -.values { - flex-wrap: nowrap; - overflow-x: auto; - overflow-y: hidden; - - &::-webkit-scrollbar { - height: 0.4rem; - } - - &::-webkit-scrollbar-track { - box-shadow: inset 0 0 6px rgba(0, 0, 0, 0); - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0); - } - - &::-webkit-scrollbar-thumb { - background-color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-2)); - border-radius: 0.3rem; - } -} - -.inputField { - --input-padding-y: 0; -} - -.modal { - overflow-y: visible; - .section { - overflow-y: visible; - } -} - -.defaultSelectGroup { - @media (max-width: $mantine-breakpoint-md) { - display: none; - } -} - -.filterIcon { - @media (min-width: $mantine-breakpoint-md) { - display: none; - } -} diff --git a/apps/dashboard/components/partials/Head.tsx b/apps/dashboard/components/partials/Head.tsx index 7116182..d712d77 100644 --- a/apps/dashboard/components/partials/Head.tsx +++ b/apps/dashboard/components/partials/Head.tsx @@ -1,4 +1,4 @@ -import { ActionIcon, AppShell, Box, Center, Flex, Group, Modal, rem, Stack } from "@mantine/core"; +import { ActionIcon, AppShell, Box, Burger, Center, Flex, Group, Modal, rem, Stack } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { IProcess } from "@pm2.web/typings"; import { IconCircleFilled, IconDatabaseCog, IconFilterCog, IconLock, IconServerCog } from "@tabler/icons-react"; @@ -9,9 +9,8 @@ import Access from "@/utils/access"; import { useSelected } from "../context/SelectedProvider"; import { CustomMultiSelect, IItem } from "../misc/MultiSelect/CustomMultiSelect"; -import classes from "./Head.module.css"; -export function Head() { +export function Head({ mobileOpened, toggleMobile }: { mobileOpened?: boolean; toggleMobile?: () => void }) { const { servers, selectItem, selectedItem } = useSelected(); const { data: session } = useSession(); const [opened, { open, close }] = useDisclosure(false); @@ -36,7 +35,7 @@ export function Head() { value: server._id, label: server.name, status: new Date(server.updatedAt).getTime() > Date.now() - 1000 * 60 ? "online" : "offline", - disabled: !server.processes.some((process) => hasAccess(server._id, process._id)), // check whether user has access to any process + disabled: !server.processes.some((process) => hasAccess(server._id, process._id)), })) || [] } onChange={(values) => { @@ -45,15 +44,9 @@ export function Head() { itemComponent={itemComponent} placeholder="Select Server" searchable - w={{ - md: "25rem", - }} - radius={"md"} - classNames={{ - pillsList: classes.values, - }} + w={{ md: "15rem", base: "100%" }} + radius="md" hidePickedOptions - // zIndex={204} /> } @@ -79,23 +72,13 @@ export function Head() { }} placeholder="Select Process" searchable - w={{ - md: "25rem", - }} + w={{ md: "15rem", base: "100%" }} maxValues={4} - radius={"md"} + radius="md" withScrollArea maxDropdownHeight={200} - classNames={{ - pillsList: classes.values, - }} - style={{ - zIndex: 204, - }} - comboboxProps={{ - position: "bottom", - middlewares: { flip: false, shift: false }, - }} + style={{ zIndex: 204 }} + comboboxProps={{ position: "bottom", middlewares: { flip: false, shift: false } }} hidePickedOptions /> > @@ -105,32 +88,33 @@ export function Head() { return ( - - + + {MultiSelectItems} - - - - + + + {toggleMobile && ( + + )} + + - - {MultiSelectItems} - - - - + + + + {MultiSelectItems} + + + diff --git a/apps/dashboard/components/partials/Nav.module.css b/apps/dashboard/components/partials/Nav.module.css deleted file mode 100644 index 0573c5f..0000000 --- a/apps/dashboard/components/partials/Nav.module.css +++ /dev/null @@ -1,67 +0,0 @@ -.stackLink { - @media (max-width: $mantine-breakpoint-xs) { - gap: rem(10); - } -} - -.stackAction { - @media (max-width: $mantine-breakpoint-xs) { - gap: rem(15); - } -} - -.link { - width: rem(50); - height: rem(50); - border-radius: var(--mantine-radius-md); - display: flex; - align-items: center; - justify-content: center; - color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); - - &:hover { - background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5)); - } - - @media (max-width: $mantine-breakpoint-sm) { - width: rem(20); - height: rem(20); - } -} - -.icon { - width: rem(24); - height: rem(24); - - @media (max-width: $mantine-breakpoint-sm) { - width: rem(20); - height: rem(20); - } -} - -.active { - &, - &:hover { - background-color: var(--mantine-primary-color-light); - } -} - -.colorSchemeDark { - @mixin dark { - display: none; - } - - @mixin light { - display: block; - } -} - -.colorSchemeLight { - @mixin light { - display: none; - } - - @mixin dark { - display: block; - } -} diff --git a/apps/dashboard/components/partials/Nav.tsx b/apps/dashboard/components/partials/Nav.tsx index 2a898b1..0cf5aea 100644 --- a/apps/dashboard/components/partials/Nav.tsx +++ b/apps/dashboard/components/partials/Nav.tsx @@ -1,4 +1,4 @@ -import { AppShell, Stack, Tooltip, UnstyledButton, useMantineColorScheme } from "@mantine/core"; +import { AppShell, Stack, Tooltip, ActionIcon, useMantineColorScheme, useMantineTheme } from "@mantine/core"; import { IconGauge, IconLayoutDashboard, @@ -9,52 +9,46 @@ import { IconUser, TablerIcon, } from "@tabler/icons-react"; -import cx from "clsx"; import Link from "next/link"; import { useRouter } from "next/router"; import { Session } from "next-auth"; import { signOut, useSession } from "next-auth/react"; -import classes from "./Nav.module.css"; - -interface NavbarBtnProps { - icon: TablerIcon; - label: string; - active?: boolean; - onClick?(): void; -} - -function NavbarBtn({ icon: Icon, label, active, onClick }: NavbarBtnProps) { - return ( - - - - - - ); -} - interface NavbarLinkProps { icon: TablerIcon; label: string; active?: boolean; href?: string; + onClick?: () => void; } -function NavbarLink({ icon: Icon, label, active, href }: NavbarLinkProps) { - return ( +function NavbarLink({ icon: Icon, label, active, href, onClick }: NavbarLinkProps) { + const theme = useMantineTheme(); + + const content = ( - - - + + + ); + + if (href) { + return {content}; + } + + return content; } const navLinks = [ { icon: IconGauge, label: "Overview", href: "/" }, { icon: IconLayoutDashboard, label: "Process", href: "/process" }, - /* { icon: IconServerBolt, label: 'Server', href: '/server' }, */ // TODO: Add server page, server { icon: IconUser, label: "User Administration", @@ -67,37 +61,33 @@ const navLinks = [ return false; }, }, - /* { icon: IconBellCog, label: 'Alerts', href: '/alert' }, */ { icon: IconSettings, label: "Settings", href: "/settings" }, ]; export function Nav() { - const { toggleColorScheme } = useMantineColorScheme(); + const { colorScheme, toggleColorScheme } = useMantineColorScheme(); const { data: session } = useSession(); - //active page const router = useRouter(); - const active = navLinks.findIndex((link) => router.pathname === link.href); const links = navLinks .filter((link) => (link.onlyIf ? link.onlyIf(session) : true)) - .map((link, index) => ); + .map((link) => ); return ( - - - + + + {links} - - - toggleColorScheme()}> - - - - - signOut()} /> + + toggleColorScheme()} + /> + signOut()} /> diff --git a/apps/dashboard/components/process/ProcessActionRow.tsx b/apps/dashboard/components/process/ProcessActionRow.tsx index 54471fd..6f3104d 100644 --- a/apps/dashboard/components/process/ProcessActionRow.tsx +++ b/apps/dashboard/components/process/ProcessActionRow.tsx @@ -1,7 +1,5 @@ import { ActionIcon, Flex } from "@mantine/core"; import { IconPower, IconReload, IconSquareRoundedMinus, IconTrash } from "@tabler/icons-react"; - -import classes from "@/styles/process.module.css"; import { sendNotification } from "@/utils/notification"; import { trpc } from "@/utils/trpc"; @@ -70,26 +68,13 @@ export default function ProcessAction({ processId, collapse }: ProcessActionProp - - - - + ); diff --git a/apps/dashboard/components/process/ProcessGitMetric.tsx b/apps/dashboard/components/process/ProcessGitMetric.tsx index 0319027..61ed17f 100644 --- a/apps/dashboard/components/process/ProcessGitMetric.tsx +++ b/apps/dashboard/components/process/ProcessGitMetric.tsx @@ -1,32 +1,31 @@ -import { Anchor, Flex, Paper, Popover, Text } from "@mantine/core"; +import { Anchor, Group, Badge, Popover, Text } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { IProcess } from "@pm2.web/typings"; import { IconGitMerge } from "@tabler/icons-react"; -import classes from "@/styles/process.module.css"; - export default function ProcessGitMetric({ versioning }: { versioning?: IProcess["versioning"] }) { const [opened, { close, open }] = useDisclosure(false); return ( - - + {versioning?.branch} {versioning?.unstaged && "*"} - - + + {versioning?.comment?.split("\n")?.map((t, tIdx) => ( diff --git a/apps/dashboard/components/process/ProcessHeader.tsx b/apps/dashboard/components/process/ProcessHeader.tsx index 9b5fa92..5d3e5fd 100644 --- a/apps/dashboard/components/process/ProcessHeader.tsx +++ b/apps/dashboard/components/process/ProcessHeader.tsx @@ -1,4 +1,4 @@ -import { Flex, Indicator, Text } from "@mantine/core"; +import { Flex, Group, Indicator, Text } from "@mantine/core"; import { IProcess } from "@pm2.web/typings"; import { IconBrandCSharp, @@ -54,13 +54,13 @@ export default function ProcessHeader({ }, [interpreter]); return ( - + {name} - + ); } diff --git a/apps/dashboard/components/process/ProcessItem.tsx b/apps/dashboard/components/process/ProcessItem.tsx index 3307973..02d422a 100644 --- a/apps/dashboard/components/process/ProcessItem.tsx +++ b/apps/dashboard/components/process/ProcessItem.tsx @@ -1,10 +1,7 @@ -import { Flex, Paper, Transition } from "@mantine/core"; +import { Paper, Group, Stack, Transition } from "@mantine/core"; import { IProcess, ISetting } from "@pm2.web/typings"; -import cx from "clsx"; import { useState } from "react"; -import classes from "@/styles/process.module.css"; - import ProcessAction from "./ProcessActionRow"; import ProcessChart from "./ProcessChart"; import ProcessHeader from "./ProcessHeader"; @@ -37,25 +34,26 @@ export default function ProcessItem({ process, setting }: ProcessItemProps) { - - + + - + setCollapsed(!collapsed)} /> - - + + {(styles) => ( @@ -68,7 +66,7 @@ export default function ProcessItem({ process, setting }: ProcessItemProps) { )} - + ); } diff --git a/apps/dashboard/components/process/ProcessLog.tsx b/apps/dashboard/components/process/ProcessLog.tsx index ac16e84..9f53df0 100644 --- a/apps/dashboard/components/process/ProcessLog.tsx +++ b/apps/dashboard/components/process/ProcessLog.tsx @@ -1,6 +1,4 @@ -import { Paper, ScrollArea, Text } from "@mantine/core"; - -import classes from "@/styles/process.module.css"; +import { Card, ScrollArea, Text } from "@mantine/core"; import { trpc } from "@/utils/trpc"; interface ProcessActionProps { @@ -17,8 +15,8 @@ export default function ProcessLog({ processId, refetchInterval }: ProcessAction ); return ( - - + + Logs {getLogs?.data?.map((log) => ( @@ -36,6 +34,6 @@ export default function ProcessLog({ processId, refetchInterval }: ProcessAction {getLogs.error && Error: {getLogs.error.message}} - + ); } diff --git a/apps/dashboard/components/process/ProcessMetric.tsx b/apps/dashboard/components/process/ProcessMetric.tsx index 2e337ff..9e3ed82 100644 --- a/apps/dashboard/components/process/ProcessMetric.tsx +++ b/apps/dashboard/components/process/ProcessMetric.tsx @@ -1,9 +1,7 @@ -import { Flex, Paper, Text } from "@mantine/core"; +import { Badge, Group, Text } from "@mantine/core"; import { Icon, IconProps } from "@tabler/icons-react"; import { ForwardRefExoticComponent, RefAttributes } from "react"; -import classes from "@/styles/process.module.css"; - export default function ProcessItemMetric({ w, Icon, @@ -14,11 +12,11 @@ export default function ProcessItemMetric({ value?: string | undefined | boolean; }) { return ( - - + + - {value || ""} - - + {value || ""} + + ); } diff --git a/apps/dashboard/components/process/ProcessMetricRow.tsx b/apps/dashboard/components/process/ProcessMetricRow.tsx index 8444811..504c031 100644 --- a/apps/dashboard/components/process/ProcessMetricRow.tsx +++ b/apps/dashboard/components/process/ProcessMetricRow.tsx @@ -1,4 +1,4 @@ -import { Flex } from "@mantine/core"; +import { Group, Progress, Text, Tooltip, Stack } from "@mantine/core"; import { IProcess } from "@pm2.web/typings"; import { IconCpu, IconDeviceSdCard, IconHistory } from "@tabler/icons-react"; import ms from "ms"; @@ -7,7 +7,6 @@ import { formatBytes } from "@/utils/format"; import { trpc } from "@/utils/trpc"; import ProcessGitMetric from "./ProcessGitMetric"; -import ProcessItemMetric from "./ProcessMetric"; interface ProcessActionProps { process: IProcess; @@ -23,16 +22,43 @@ export default function ProcessMetricRow({ process, refetchInterval, showMetric }, ); + const cpuValue = showMetric ? (getStat.data?.cpu || 0) : 0; + const memValue = showMetric ? (getStat.data?.memory || 0) : 0; + return ( - + {process?.versioning?.url && } - - - - + + + + + + + CPU + + {showMetric ? `${cpuValue.toFixed(0)}%` : '-'} + + + + + + + + + + + RAM + + {showMetric ? formatBytes(memValue) : '-'} + + + + + + + + {showMetric ? ms(getStat.data?.uptime || 0) : '-'} + + ); } diff --git a/apps/dashboard/components/settings/UpdateConfiguration.module.css b/apps/dashboard/components/settings/UpdateConfiguration.module.css deleted file mode 100644 index 1c11229..0000000 --- a/apps/dashboard/components/settings/UpdateConfiguration.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.pinInput { - @media (max-width: $mantine-breakpoint-xs) { - width: 1.5rem; - height: 1.5rem; - min-height: auto; - } -} diff --git a/apps/dashboard/components/settings/UpdateConfiguration.tsx b/apps/dashboard/components/settings/UpdateConfiguration.tsx index 59a4760..e26450a 100644 --- a/apps/dashboard/components/settings/UpdateConfiguration.tsx +++ b/apps/dashboard/components/settings/UpdateConfiguration.tsx @@ -5,7 +5,7 @@ import { Checkbox, CopyButton, Flex, - Grid, + SimpleGrid, Input, NumberInput, PinInput, @@ -21,8 +21,6 @@ import { IconCheck, IconCopy, IconDeviceFloppy, IconRefresh } from "@tabler/icon import { sendNotification } from "@/utils/notification"; import { trpc } from "@/utils/trpc"; -import classes from "./UpdateConfiguration.module.css"; - interface UpdateConfigurationProps { settings: ISetting; } @@ -62,9 +60,8 @@ export default function UpdateConfiguration({ settings }: UpdateConfigurationPro updateSetting.mutate(values))}> - - - + + - - - + - - + } - mt={"sm"} + mt="sm" loading={updateSetting.isPending} > Save - - + + diff --git a/apps/dashboard/components/stats/StatsRing.module.css b/apps/dashboard/components/stats/StatsRing.module.css deleted file mode 100644 index facac7e..0000000 --- a/apps/dashboard/components/stats/StatsRing.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.statsRing { - background: light-dark(white, var(--mantine-color-dark-7)); -} - -.statsRingLabel { - color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-5)); -} - -.statsRingValue { - color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-gray-4)); -} diff --git a/apps/dashboard/components/stats/StatsRing.tsx b/apps/dashboard/components/stats/StatsRing.tsx index b40e7e0..061702a 100644 --- a/apps/dashboard/components/stats/StatsRing.tsx +++ b/apps/dashboard/components/stats/StatsRing.tsx @@ -1,6 +1,4 @@ -import { Box, Flex, Group, Paper, RingProgress, Text } from "@mantine/core"; - -import classes from "./StatsRing.module.css"; +import { Box, Flex, Group, Card, RingProgress, Text } from "@mantine/core"; interface StatsRingProps { title: string; @@ -16,7 +14,7 @@ interface StatsRingProps { export function StatsRing({ stat }: { stat: StatsRingProps }) { return ( - + {stat.stats.map((s) => ( - + {s.label}: - + {s.value} ))} - + ); } diff --git a/apps/dashboard/components/user/table/UserItem.module.css b/apps/dashboard/components/user/table/UserItem.module.css deleted file mode 100644 index 4a1be3a..0000000 --- a/apps/dashboard/components/user/table/UserItem.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.rowSelected { - background-color: var(--mantine-color-blue-light); -} diff --git a/apps/dashboard/components/user/table/UserItem.tsx b/apps/dashboard/components/user/table/UserItem.tsx index e05e984..91efc13 100644 --- a/apps/dashboard/components/user/table/UserItem.tsx +++ b/apps/dashboard/components/user/table/UserItem.tsx @@ -7,8 +7,6 @@ import { GoogleIcon } from "@/components/icons/google"; import { actionNotification } from "@/utils/notification"; import { trpc } from "@/utils/trpc"; -import classes from "./UserItem.module.css"; - interface UserItemProps { selected: boolean; selectUser: (userId: string) => void; @@ -60,7 +58,7 @@ export default function UserItem({ }); return ( - + { return ( <> - + diff --git a/apps/dashboard/pages/index.tsx b/apps/dashboard/pages/index.tsx index 2857214..dec3478 100644 --- a/apps/dashboard/pages/index.tsx +++ b/apps/dashboard/pages/index.tsx @@ -1,5 +1,6 @@ import { AreaChart, DonutChart } from "@mantine/charts"; -import { Flex, Paper, SimpleGrid } from "@mantine/core"; +import { Flex, Card, SimpleGrid, Stack, Center, Group, Text, Paper, ThemeIcon, Title } from "@mantine/core"; +import { IconServer, IconActivity, IconClockHour4, IconCpu, IconDeviceSdCard } from "@tabler/icons-react"; import { ISetting } from "@pm2.web/typings"; import ms from "ms"; import { InferGetServerSidePropsType } from "next"; @@ -10,19 +11,20 @@ import DashboardLog from "@/components/dashboard/DashboardLog"; import { Dashboard } from "@/components/layouts/Dashboard"; import { StatsRing } from "@/components/stats/StatsRing"; import { getServerSideHelpers } from "@/server/helpers"; -import classes from "@/styles/index.module.css"; import { formatBytes } from "@/utils/format"; import { trpc } from "@/utils/trpc"; const statChartProps = { - h: "120px", + h: "300px", withLegend: true, withGradient: true, withDots: false, - withXAxis: false, + withXAxis: true, + withYAxis: true, yAxisProps: { width: 55 }, areaChartProps: { syncId: "stats" }, connectNulls: true, + curveType: "monotone" as any, }; function Home({ settings }: { settings: ISetting }) { @@ -45,23 +47,88 @@ function Home({ settings }: { settings: ISetting }) { const offlineCount = selectedProcesses.filter((p) => p.status == "offline").length; return ( - - - + + + System Overview + + + + + + + Total Servers + {selectedServers.length} + + + + + + + + + + + Online Processes + + {onlineCount} + / {selectedProcesses.length} + + + 0 ? "teal" : "cyan"} variant="light" size={48} radius="md"> + + + + + + + + + Server Uptime + {ms(data?.serverUptime || 0)} + + + + + + + + + + + Process Uptime + {ms(data?.processUptime || 0)} + + + + + + + + + + + + CPU Usage + + value.toFixed(1)} - unit="%" + valueFormatter={(value) => value.toFixed(1) + "%"} series={[ - { name: "processCpu", color: "blue", label: "Process CPU" }, - { name: "serverCpu", color: "grape", label: "Server CPU" }, + { name: "processCpu", color: "cyan.6", label: "Process CPU" }, + { name: "serverCpu", color: "violet.6", label: "Server CPU" }, ]} /> - + + + + Memory Allocation + + formatBytes(value)} series={[ - { name: "processRam", color: "indigo", label: "Process RAM" }, - { name: "serverRam", color: "yellow", label: "Server RAM" }, + { name: "processRam", color: "teal.6", label: "Process RAM" }, + { name: "serverRam", color: "indigo.6", label: "Server RAM" }, ]} /> - - - - - - - p._id)} /> - + + + Process Activity Logs + p._id)} /> + + ); } diff --git a/apps/dashboard/pages/settings.tsx b/apps/dashboard/pages/settings.tsx index c9654a8..3f9e143 100644 --- a/apps/dashboard/pages/settings.tsx +++ b/apps/dashboard/pages/settings.tsx @@ -1,4 +1,4 @@ -import { Accordion, Badge, Grid, Overlay, Paper, ScrollArea, Title } from "@mantine/core"; +import { Accordion, Badge, Grid, Overlay, Card, ScrollArea, Title } from "@mantine/core"; import { InferGetServerSidePropsType } from "next"; import Head from "next/head"; import { useSession } from "next-auth/react"; @@ -33,16 +33,9 @@ export default function Settings({}: InferGetServerSidePropsType - - - + + + Configuration @@ -59,10 +52,10 @@ export default function Settings({}: InferGetServerSidePropsType )} - + - - + + User Settings @@ -71,7 +64,7 @@ export default function Settings({}: InferGetServerSidePropsType {isOAuth2 && } - + diff --git a/apps/dashboard/pages/user.tsx b/apps/dashboard/pages/user.tsx index 84c87bd..a290dc1 100644 --- a/apps/dashboard/pages/user.tsx +++ b/apps/dashboard/pages/user.tsx @@ -7,7 +7,7 @@ import { Flex, Grid, Overlay, - Paper, + Card, rem, ScrollArea, Title, @@ -28,8 +28,6 @@ import { actionNotification } from "@/utils/notification"; import { IPermissionConstants, Permission, PERMISSIONS } from "@/utils/permission"; import { trpc } from "@/utils/trpc"; -import classes from "../styles/user.module.css"; - export default function User({}: InferGetServerSidePropsType) { const dashboardQuery = trpc.server.getDashBoardData.useQuery(true); const usersQuery = trpc.user.getUsers.useQuery(); @@ -138,14 +136,7 @@ export default function User({}: InferGetServerSidePropsType - + - - + + Custom Permissions - - - + + + {servers.map((item) => ( @@ -196,10 +176,6 @@ export default function User({}: InferGetServerSidePropsType updatePermsState(item._id, "", values)} data={permissionData} @@ -223,13 +199,10 @@ export default function User({}: InferGetServerSidePropsType - + - + diff --git a/apps/dashboard/styles/index.module.css b/apps/dashboard/styles/index.module.css deleted file mode 100644 index f1a7d8f..0000000 --- a/apps/dashboard/styles/index.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.chartBg { - background: light-dark(white, var(--mantine-color-dark-7)); -} - -.statusLabel { - font-size: var(--mantine-h3-font-size); - font-weight: var(--mantine-h1-font-weight); - transform: translateY(-1em); -} diff --git a/apps/dashboard/styles/process.module.css b/apps/dashboard/styles/process.module.css deleted file mode 100644 index 5965048..0000000 --- a/apps/dashboard/styles/process.module.css +++ /dev/null @@ -1,51 +0,0 @@ -.processItem { - background: light-dark(white, var(--mantine-color-dark-7)); - transition: 0.5s ease-out max-height; -} - -.processItem.opened { - max-height: 400px; - @media (max-width: $mantine-breakpoint-xs) { - max-height: 440px; - } -} - -.processItem.closed { - max-height: 55px; - - @media (max-width: $mantine-breakpoint-sm) { - max-height: 90px; - } - - @media (max-width: $mantine-breakpoint-xs) { - max-height: 120px; - } -} - -.processLog { - background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-8)); -} - -.processMetric { - background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-8)); -} - -.colorSchemeDark { - @mixin dark { - display: none; - } - - @mixin light { - display: block; - } -} - -.colorSchemeLight { - @mixin light { - display: none; - } - - @mixin dark { - display: block; - } -} diff --git a/apps/dashboard/styles/user.module.css b/apps/dashboard/styles/user.module.css deleted file mode 100644 index 218fe30..0000000 --- a/apps/dashboard/styles/user.module.css +++ /dev/null @@ -1,21 +0,0 @@ -.value { - margin-left: rem(1); - margin-right: rem(1); -} - -.values { - max-width: rem(20-0); - flex-wrap: nowrap; - overflow-x: auto; - scrollbar-width: thin; - overflow-y: hidden; -} - -.content { - padding: 0; - padding-left: rem(60); - - @media (max-width: $mantine-breakpoint-xs) { - padding-left: rem(10); - } -} From 20ee354c7c34f584e7039e61703e616ec524494b Mon Sep 17 00:00:00 2001 From: oxdev03 <140103378+oxdev03@users.noreply.github.com> Date: Sun, 28 Jun 2026 12:32:27 +0200 Subject: [PATCH 2/2] lint and format --- apps/dashboard/components/partials/Head.tsx | 35 ++--- apps/dashboard/components/partials/Nav.tsx | 12 +- .../components/process/ProcessActionRow.tsx | 9 +- .../components/process/ProcessGitMetric.tsx | 4 +- .../components/process/ProcessItem.tsx | 6 +- .../components/process/ProcessLog.tsx | 1 + .../components/process/ProcessMetric.tsx | 4 +- .../components/process/ProcessMetricRow.tsx | 28 ++-- .../settings/UpdateConfiguration.tsx | 120 +++++++++--------- apps/dashboard/components/stats/StatsRing.tsx | 2 +- apps/dashboard/pages/index.tsx | 67 +++++++--- apps/dashboard/pages/settings.tsx | 2 +- apps/dashboard/pages/user.tsx | 16 +-- 13 files changed, 170 insertions(+), 136 deletions(-) diff --git a/apps/dashboard/components/partials/Head.tsx b/apps/dashboard/components/partials/Head.tsx index d712d77..0df5155 100644 --- a/apps/dashboard/components/partials/Head.tsx +++ b/apps/dashboard/components/partials/Head.tsx @@ -89,31 +89,34 @@ export function Head({ mobileOpened, toggleMobile }: { mobileOpened?: boolean; t return ( - - {MultiSelectItems} - + {MultiSelectItems} - {toggleMobile && ( - - )} + {toggleMobile && } - + - + - + {MultiSelectItems} - + diff --git a/apps/dashboard/components/partials/Nav.tsx b/apps/dashboard/components/partials/Nav.tsx index 0cf5aea..91a7469 100644 --- a/apps/dashboard/components/partials/Nav.tsx +++ b/apps/dashboard/components/partials/Nav.tsx @@ -1,4 +1,4 @@ -import { AppShell, Stack, Tooltip, ActionIcon, useMantineColorScheme, useMantineTheme } from "@mantine/core"; +import { ActionIcon, AppShell, Stack, Tooltip, useMantineColorScheme, useMantineTheme } from "@mantine/core"; import { IconGauge, IconLayoutDashboard, @@ -24,7 +24,7 @@ interface NavbarLinkProps { function NavbarLink({ icon: Icon, label, active, href, onClick }: NavbarLinkProps) { const theme = useMantineTheme(); - + const content = ( {content}; + return ( + + {content} + + ); } return content; @@ -83,7 +87,7 @@ export function Nav() { toggleColorScheme()} /> diff --git a/apps/dashboard/components/process/ProcessActionRow.tsx b/apps/dashboard/components/process/ProcessActionRow.tsx index 6f3104d..78fb48e 100644 --- a/apps/dashboard/components/process/ProcessActionRow.tsx +++ b/apps/dashboard/components/process/ProcessActionRow.tsx @@ -1,5 +1,6 @@ import { ActionIcon, Flex } from "@mantine/core"; import { IconPower, IconReload, IconSquareRoundedMinus, IconTrash } from "@tabler/icons-react"; + import { sendNotification } from "@/utils/notification"; import { trpc } from "@/utils/trpc"; @@ -67,13 +68,7 @@ export default function ProcessAction({ processId, collapse }: ProcessActionProp > - + diff --git a/apps/dashboard/components/process/ProcessGitMetric.tsx b/apps/dashboard/components/process/ProcessGitMetric.tsx index 61ed17f..1a3e919 100644 --- a/apps/dashboard/components/process/ProcessGitMetric.tsx +++ b/apps/dashboard/components/process/ProcessGitMetric.tsx @@ -1,4 +1,4 @@ -import { Anchor, Group, Badge, Popover, Text } from "@mantine/core"; +import { Anchor, Badge, Group, Popover, Text } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { IProcess } from "@pm2.web/typings"; import { IconGitMerge } from "@tabler/icons-react"; @@ -16,7 +16,7 @@ export default function ProcessGitMetric({ versioning }: { versioning?: IProcess h="30px" onMouseEnter={open} onMouseLeave={close} - style={{ cursor: 'pointer' }} + style={{ cursor: "pointer" }} > diff --git a/apps/dashboard/components/process/ProcessItem.tsx b/apps/dashboard/components/process/ProcessItem.tsx index 02d422a..fd2c9af 100644 --- a/apps/dashboard/components/process/ProcessItem.tsx +++ b/apps/dashboard/components/process/ProcessItem.tsx @@ -1,4 +1,4 @@ -import { Paper, Group, Stack, Transition } from "@mantine/core"; +import { Group, Paper, Stack, Transition } from "@mantine/core"; import { IProcess, ISetting } from "@pm2.web/typings"; import { useState } from "react"; @@ -38,8 +38,8 @@ export default function ProcessItem({ process, setting }: ProcessItemProps) { shadow="sm" bg="var(--mantine-color-body)" style={{ - transition: 'box-shadow 0.2s ease, transform 0.2s ease', - border: '1px solid var(--mantine-color-default-border)' + transition: "box-shadow 0.2s ease, transform 0.2s ease", + border: "1px solid var(--mantine-color-default-border)", }} > diff --git a/apps/dashboard/components/process/ProcessLog.tsx b/apps/dashboard/components/process/ProcessLog.tsx index 9f53df0..9006111 100644 --- a/apps/dashboard/components/process/ProcessLog.tsx +++ b/apps/dashboard/components/process/ProcessLog.tsx @@ -1,4 +1,5 @@ import { Card, ScrollArea, Text } from "@mantine/core"; + import { trpc } from "@/utils/trpc"; interface ProcessActionProps { diff --git a/apps/dashboard/components/process/ProcessMetric.tsx b/apps/dashboard/components/process/ProcessMetric.tsx index 9e3ed82..6fae8e6 100644 --- a/apps/dashboard/components/process/ProcessMetric.tsx +++ b/apps/dashboard/components/process/ProcessMetric.tsx @@ -15,7 +15,9 @@ export default function ProcessItemMetric({ - {value || ""} + + {value || ""} + ); diff --git a/apps/dashboard/components/process/ProcessMetricRow.tsx b/apps/dashboard/components/process/ProcessMetricRow.tsx index 504c031..798b467 100644 --- a/apps/dashboard/components/process/ProcessMetricRow.tsx +++ b/apps/dashboard/components/process/ProcessMetricRow.tsx @@ -1,4 +1,4 @@ -import { Group, Progress, Text, Tooltip, Stack } from "@mantine/core"; +import { Group, Progress, Stack, Text, Tooltip } from "@mantine/core"; import { IProcess } from "@pm2.web/typings"; import { IconCpu, IconDeviceSdCard, IconHistory } from "@tabler/icons-react"; import ms from "ms"; @@ -22,21 +22,25 @@ export default function ProcessMetricRow({ process, refetchInterval, showMetric }, ); - const cpuValue = showMetric ? (getStat.data?.cpu || 0) : 0; - const memValue = showMetric ? (getStat.data?.memory || 0) : 0; + const cpuValue = showMetric ? getStat.data?.cpu || 0 : 0; + const memValue = showMetric ? getStat.data?.memory || 0 : 0; return ( {process?.versioning?.url && } - + - CPU + + CPU + - {showMetric ? `${cpuValue.toFixed(0)}%` : '-'} + + {showMetric ? `${cpuValue.toFixed(0)}%` : "-"} + @@ -47,9 +51,13 @@ export default function ProcessMetricRow({ process, refetchInterval, showMetric - RAM + + RAM + - {showMetric ? formatBytes(memValue) : '-'} + + {showMetric ? formatBytes(memValue) : "-"} + @@ -57,7 +65,9 @@ export default function ProcessMetricRow({ process, refetchInterval, showMetric - {showMetric ? ms(getStat.data?.uptime || 0) : '-'} + + {showMetric ? ms(getStat.data?.uptime || 0) : "-"} + ); diff --git a/apps/dashboard/components/settings/UpdateConfiguration.tsx b/apps/dashboard/components/settings/UpdateConfiguration.tsx index e26450a..5386dbb 100644 --- a/apps/dashboard/components/settings/UpdateConfiguration.tsx +++ b/apps/dashboard/components/settings/UpdateConfiguration.tsx @@ -5,10 +5,10 @@ import { Checkbox, CopyButton, Flex, - SimpleGrid, Input, NumberInput, PinInput, + SimpleGrid, Stack, Title, Tooltip, @@ -62,68 +62,64 @@ export default function UpdateConfiguration({ settings }: UpdateConfigurationPro updateSetting.mutate(values))}> - - - + + + - - - - - - globalConfiguration.setFieldValue("registrationCode", randomId().slice(8, 14))} - > - - - - {({ copied, copy }) => ( - - - {copied ? : } - - - )} - - - + + + + + + globalConfiguration.setFieldValue("registrationCode", randomId().slice(8, 14))} + > + + + + {({ copied, copy }) => ( + + + {copied ? : } + + + )} + + + - Total Servers - {selectedServers.length} + + Total Servers + + + {selectedServers.length} + @@ -68,13 +72,24 @@ function Home({ settings }: { settings: ISetting }) { - Online Processes + + Online Processes + - {onlineCount} - / {selectedProcesses.length} + + {onlineCount} + + + / {selectedProcesses.length} + - 0 ? "teal" : "cyan"} variant="light" size={48} radius="md"> + 0 ? "teal" : "cyan"} + variant="light" + size={48} + radius="md" + > @@ -83,8 +98,12 @@ function Home({ settings }: { settings: ISetting }) { - Server Uptime - {ms(data?.serverUptime || 0)} + + Server Uptime + + + {ms(data?.serverUptime || 0)} + @@ -95,8 +114,12 @@ function Home({ settings }: { settings: ISetting }) { - Process Uptime - {ms(data?.processUptime || 0)} + + Process Uptime + + + {ms(data?.processUptime || 0)} + @@ -108,8 +131,12 @@ function Home({ settings }: { settings: ISetting }) { - CPU Usage - + + CPU Usage + + + + - Memory Allocation - + + Memory Allocation + + + + - Process Activity Logs + + Process Activity Logs + p._id)} /> diff --git a/apps/dashboard/pages/settings.tsx b/apps/dashboard/pages/settings.tsx index 3f9e143..77be24b 100644 --- a/apps/dashboard/pages/settings.tsx +++ b/apps/dashboard/pages/settings.tsx @@ -1,4 +1,4 @@ -import { Accordion, Badge, Grid, Overlay, Card, ScrollArea, Title } from "@mantine/core"; +import { Accordion, Badge, Card, Grid, Overlay, ScrollArea, Title } from "@mantine/core"; import { InferGetServerSidePropsType } from "next"; import Head from "next/head"; import { useSession } from "next-auth/react"; diff --git a/apps/dashboard/pages/user.tsx b/apps/dashboard/pages/user.tsx index a290dc1..0ede34c 100644 --- a/apps/dashboard/pages/user.tsx +++ b/apps/dashboard/pages/user.tsx @@ -3,11 +3,11 @@ import { Badge, Box, Button, + Card, Divider, Flex, Grid, Overlay, - Card, rem, ScrollArea, Title, @@ -154,12 +154,7 @@ export default function User({}: InferGetServerSidePropsType {servers.map((item) => ( - + ( - +