add more example utils to dashboard
This commit is contained in:
@@ -96,7 +96,7 @@ export default function RootLayout({
|
||||
</div>
|
||||
|
||||
<div className="px-1">
|
||||
<div className="relative flex flex-1 flex-col overflow-x-hidden">
|
||||
<div className="relative flex h-full flex-1 flex-col">
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import { RecentActivity } from "@/components/dashboard/activity";
|
||||
import { AppOverview } from "@/components/dashboard/appOverview";
|
||||
import { NetworkOverview } from "@/components/dashboard/NetworkOverview";
|
||||
import { Notifications } from "@/components/dashboard/notifications";
|
||||
import { QuickActions } from "@/components/quickActions";
|
||||
import { QuickActions } from "@/components/dashboard/quickActions";
|
||||
import { TaskQueue } from "@/components/dashboard/taskQueue";
|
||||
import { tw } from "@/utils/tailwind";
|
||||
|
||||
interface DashboardCardProps {
|
||||
children?: React.ReactNode;
|
||||
rowSpan?: number;
|
||||
sx?: string;
|
||||
}
|
||||
const DashboardCard = (props: DashboardCardProps) => {
|
||||
const { children } = props;
|
||||
const { children, rowSpan = 1, sx = "" } = props;
|
||||
return (
|
||||
<div className="col-span-full row-span-1 border border-dashed border-slate-400 lg:col-span-1">
|
||||
<div className={tw`col-span-full row-span-${rowSpan} xl:col-span-1 ${sx}`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
@@ -21,9 +26,7 @@ interface DashboardPanelProps {
|
||||
const DashboardPanel = (props: DashboardPanelProps) => {
|
||||
const { children } = props;
|
||||
return (
|
||||
<div className="col-span-full row-span-1 shrink-0 border border-dashed border-slate-400 lg:col-span-2">
|
||||
{children}
|
||||
</div>
|
||||
<div className="col-span-full row-span-1 xl:col-span-2">{children}</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -36,10 +39,7 @@ const SplitDashboardCard = (props: SplitDashboardCardProps) => {
|
||||
<div className="col-span-full row-span-1 lg:col-span-1">
|
||||
<div className="grid h-full grid-cols-1 gap-4">
|
||||
{children?.map((row, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="col-span-full row-span-1 border border-dashed border-slate-400"
|
||||
>
|
||||
<div key={idx} className="col-span-full row-span-1 ">
|
||||
{row}
|
||||
</div>
|
||||
))}
|
||||
@@ -51,19 +51,25 @@ const SplitDashboardCard = (props: SplitDashboardCardProps) => {
|
||||
export default function Dashboard() {
|
||||
return (
|
||||
<div className="flex h-screen w-full">
|
||||
<div className="grid w-full auto-rows-min grid-cols-3 gap-4">
|
||||
<DashboardCard>
|
||||
<div className="grid w-full auto-cols-min grid-flow-row auto-rows-min grid-cols-1 grid-rows-none gap-4 xl:grid-cols-2 2xl:grid-cols-3 ">
|
||||
<DashboardCard rowSpan={2}>
|
||||
<NetworkOverview />
|
||||
</DashboardCard>
|
||||
<DashboardCard>
|
||||
<DashboardCard rowSpan={2}>
|
||||
<RecentActivity />
|
||||
</DashboardCard>
|
||||
<SplitDashboardCard>
|
||||
<DashboardCard>
|
||||
<Notifications />
|
||||
</DashboardCard>
|
||||
<DashboardCard>
|
||||
<QuickActions />
|
||||
</SplitDashboardCard>
|
||||
<DashboardPanel>Panel</DashboardPanel>
|
||||
<DashboardCard>Side Bar (misc)</DashboardCard>
|
||||
</DashboardCard>
|
||||
<DashboardPanel>
|
||||
<AppOverview />
|
||||
</DashboardPanel>
|
||||
<DashboardCard sx={tw`xl:col-span-full 2xl:col-span-1`}>
|
||||
<TaskQueue />
|
||||
</DashboardCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ interface DashboardCardProps {
|
||||
const DashboardCard = (props: DashboardCardProps) => {
|
||||
const { children, title } = props;
|
||||
return (
|
||||
<div className="h-full w-full bg-slate-50 shadow-sm shadow-slate-500">
|
||||
<div className="h-full w-full border border-solid border-slate-100 bg-slate-50 shadow-sm shadow-slate-400">
|
||||
<div className="h-full w-full px-3 py-2">
|
||||
<Typography variant="h6" color={"secondary"}>
|
||||
{title}
|
||||
|
||||
96
pkgs/ui/src/components/dashboard/appOverview/index.tsx
Normal file
96
pkgs/ui/src/components/dashboard/appOverview/index.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import { DashboardCard } from "@/components/card";
|
||||
import Image from "next/image";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
interface AppCardProps {
|
||||
name: string;
|
||||
icon?: string;
|
||||
}
|
||||
const AppCard = (props: AppCardProps) => {
|
||||
const { name, icon } = props;
|
||||
const iconPath = icon
|
||||
? `/app-icons/${icon}`
|
||||
: "app-icons/app-placeholder.svg";
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
className="flex h-40 w-40 cursor-pointer items-center justify-center rounded-3xl p-2
|
||||
align-middle shadow-md ring-2 ring-inset ring-violet-500 hover:bg-slate-200 focus:bg-slate-200 active:bg-slate-300"
|
||||
>
|
||||
<div className="flex w-full flex-col justify-center">
|
||||
<div className="h-22 w-22 my-1 flex items-center justify-center self-center overflow-visible p-1">
|
||||
<Image
|
||||
src={iconPath}
|
||||
alt={`${name}-app-icon`}
|
||||
width={18 * 3}
|
||||
height={18 * 3}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full justify-center">{name}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
type App = {
|
||||
name: string;
|
||||
icon?: string;
|
||||
};
|
||||
|
||||
const apps = [
|
||||
{
|
||||
name: "Firefox",
|
||||
icon: "firefox.svg",
|
||||
},
|
||||
{
|
||||
name: "Discord",
|
||||
icon: "discord.svg",
|
||||
},
|
||||
{
|
||||
name: "Docs",
|
||||
},
|
||||
{
|
||||
name: "Dochub",
|
||||
icon: "dochub.svg",
|
||||
},
|
||||
{
|
||||
name: "Chess",
|
||||
icon: "chess.svg",
|
||||
},
|
||||
{
|
||||
name: "Games",
|
||||
icon: "games.svg",
|
||||
},
|
||||
{
|
||||
name: "Mail",
|
||||
icon: "mail.svg",
|
||||
},
|
||||
{
|
||||
name: "Public transport",
|
||||
icon: "public-transport.svg",
|
||||
},
|
||||
{
|
||||
name: "Outlook",
|
||||
icon: "mail.svg",
|
||||
},
|
||||
{
|
||||
name: "Youtube",
|
||||
icon: "youtube.svg",
|
||||
},
|
||||
];
|
||||
|
||||
export const AppOverview = () => {
|
||||
return (
|
||||
<DashboardCard title="Applications">
|
||||
<div className="flex h-full w-full justify-center">
|
||||
<div className="flex h-full w-fit justify-center">
|
||||
<div className="grid w-full auto-cols-min auto-rows-min grid-cols-2 gap-8 py-8 sm:grid-cols-3 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 ">
|
||||
{apps.map((app) => (
|
||||
<AppCard key={app.name} name={app.name} icon={app.icon} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DashboardCard>
|
||||
);
|
||||
};
|
||||
64
pkgs/ui/src/components/dashboard/quickActions/index.tsx
Normal file
64
pkgs/ui/src/components/dashboard/quickActions/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
"use client";
|
||||
import { DashboardCard } from "@/components/card";
|
||||
import { Button, Fab } from "@mui/material";
|
||||
import { MouseEventHandler, ReactNode } from "react";
|
||||
|
||||
import LanIcon from "@mui/icons-material/Lan";
|
||||
import AppsIcon from "@mui/icons-material/Apps";
|
||||
import DevicesIcon from "@mui/icons-material/Devices";
|
||||
|
||||
type Action = {
|
||||
id: string;
|
||||
icon: ReactNode;
|
||||
label: ReactNode;
|
||||
eventHandler: MouseEventHandler<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
export const QuickActions = () => {
|
||||
const actions: Action[] = [
|
||||
{
|
||||
id: "network",
|
||||
icon: <LanIcon sx={{ mr: 1 }} />,
|
||||
label: "Network",
|
||||
eventHandler: (event) => {
|
||||
console.log({ event });
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "apps",
|
||||
icon: <AppsIcon sx={{ mr: 1 }} />,
|
||||
label: "Apps",
|
||||
eventHandler: (event) => {
|
||||
console.log({ event });
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "nodes",
|
||||
icon: <DevicesIcon sx={{ mr: 1 }} />,
|
||||
label: "Devices",
|
||||
eventHandler: (event) => {
|
||||
console.log({ event });
|
||||
},
|
||||
},
|
||||
];
|
||||
return (
|
||||
<DashboardCard title="Quick Actions">
|
||||
<div className="flex h-fit w-full items-center justify-start pt-5 align-bottom">
|
||||
<div className="flex w-full flex-col flex-wrap justify-evenly gap-2 sm:flex-row">
|
||||
{actions.map(({ id, icon, label, eventHandler }) => (
|
||||
<Fab
|
||||
className="w-fit self-center shadow-none"
|
||||
color="secondary"
|
||||
key={id}
|
||||
onClick={eventHandler}
|
||||
variant="extended"
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</Fab>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</DashboardCard>
|
||||
);
|
||||
};
|
||||
56
pkgs/ui/src/components/dashboard/taskQueue/index.tsx
Normal file
56
pkgs/ui/src/components/dashboard/taskQueue/index.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { DashboardCard } from "@/components/card";
|
||||
|
||||
import SyncIcon from "@mui/icons-material/Sync";
|
||||
import ScheduleIcon from "@mui/icons-material/Schedule";
|
||||
import DoneIcon from "@mui/icons-material/Done";
|
||||
import { ReactNode } from "react";
|
||||
import { Chip } from "@mui/material";
|
||||
|
||||
const statusMap = {
|
||||
running: <SyncIcon className="animate-bounce" />,
|
||||
done: <DoneIcon />,
|
||||
planned: <ScheduleIcon />,
|
||||
};
|
||||
|
||||
interface TaskEntryProps {
|
||||
status: ReactNode;
|
||||
result: "default" | "error" | "info" | "success" | "warning";
|
||||
task: string;
|
||||
details?: string;
|
||||
}
|
||||
const TaskEntry = (props: TaskEntryProps) => {
|
||||
const { result, task, details, status } = props;
|
||||
return (
|
||||
<>
|
||||
<div className="col-span-1">{status}</div>
|
||||
<div className="col-span-4">{task}</div>
|
||||
<div className="col-span-1">
|
||||
<Chip color={result} label={result} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const TaskQueue = () => {
|
||||
return (
|
||||
<DashboardCard title="Task Queue">
|
||||
<div className="grid grid-cols-6 gap-2 p-4">
|
||||
<TaskEntry
|
||||
result="success"
|
||||
task="Update DevX"
|
||||
status={statusMap.done}
|
||||
/>
|
||||
<TaskEntry
|
||||
result="default"
|
||||
task="Update XYZ"
|
||||
status={statusMap.running}
|
||||
/>
|
||||
<TaskEntry
|
||||
result="default"
|
||||
task="Update ABC"
|
||||
status={statusMap.planned}
|
||||
/>
|
||||
</div>
|
||||
</DashboardCard>
|
||||
);
|
||||
};
|
||||
@@ -34,7 +34,7 @@ interface NoDataOverlayProps {
|
||||
export function NoDataOverlay(props: NoDataOverlayProps) {
|
||||
const { label } = props;
|
||||
return (
|
||||
<StyledGridOverlay>
|
||||
<StyledGridOverlay className="block p-2">
|
||||
<svg
|
||||
width="120"
|
||||
height="100"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Button } from "@mui/material";
|
||||
|
||||
export const QuickActions = () => {
|
||||
return (
|
||||
<div className="grid-cols-auto gris">
|
||||
<Button>Action 1</Button>
|
||||
<Button>Action 2</Button>
|
||||
<Button>Action 3</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user