diff --git a/src/client/components/CommandPanel.tsx b/src/client/components/CommandPanel.tsx new file mode 100644 index 0000000..0503693 --- /dev/null +++ b/src/client/components/CommandPanel.tsx @@ -0,0 +1,236 @@ +import React, { useEffect, useState } from 'react'; +import { + Command, + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from '@/components/ui/command'; +import { + LuAreaChart, + LuBellDot, + LuFilePieChart, + LuMonitorDot, + LuSearch, + LuServer, + LuUserCircle2, + LuWifi, +} from 'react-icons/lu'; +import { NavigateOptions, useNavigate } from '@tanstack/react-router'; +import { useEvent } from '@/hooks/useEvent'; +import { useCommandState } from 'cmdk'; +import { useTranslation } from '@i18next-toolkit/react'; +import { trpc } from '@/api/trpc'; +import { useCurrentWorkspaceId } from '@/store/user'; +import { Button } from './ui/button'; + +export const CommandPanel: React.FC = React.memo(() => { + const [open, setOpen] = useState(false); + const navigate = useNavigate(); + const { t } = useTranslation(); + + const handleJump = useEvent((options: NavigateOptions) => { + return () => { + setOpen(false); + navigate(options); + }; + }); + + useEffect(() => { + const down = (e: KeyboardEvent) => { + if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + setOpen((open) => !open); + } + }; + + document.addEventListener('keydown', down); + return () => document.removeEventListener('keydown', down); + }, []); + + return ( + <> + + + + + + + {t('No results found.')} + + + + + {t('Website')} + + + + {t('Monitor')} + + + + {t('Servers')} + + + + {t('Telemetry')} + + + + {t('Pages')} + + + + + + + {t('Profile')} + + + + {t('Notifications')} + + + + + + + ); +}); +CommandPanel.displayName = 'CommandPanel'; + +interface CommandPanelSearchGroupProps { + handleJump: (options: NavigateOptions) => () => void; +} +export const CommandPanelSearchGroup: React.FC = + React.memo((props) => { + const handleJump = props.handleJump; + const search = useCommandState((state) => state.search); + const workspaceId = useCurrentWorkspaceId(); + const { t } = useTranslation(); + const { data: websites = [] } = trpc.website.all.useQuery({ + workspaceId, + }); + const { data: monitors = [] } = trpc.monitor.all.useQuery({ + workspaceId, + }); + const { data: telemetryList = [] } = trpc.telemetry.all.useQuery({ + workspaceId, + }); + const { data: pages = [] } = trpc.monitor.getAllPages.useQuery({ + workspaceId, + }); + + if (!search) { + return null; + } + + return ( + + {websites.map((w) => ( + + + {w.name} + + ))} + {monitors.map((m) => ( + + + {m.name} + + ))} + {telemetryList.map((t) => ( + + + {t.name} + + ))} + {pages.map((p) => ( + + + {p.title} + + ))} + + ); + }); +CommandPanelSearchGroup.displayName = 'CommandPanelSearchGroup'; diff --git a/src/client/components/ui/command.tsx b/src/client/components/ui/command.tsx index 91b2295..b18e756 100644 --- a/src/client/components/ui/command.tsx +++ b/src/client/components/ui/command.tsx @@ -27,7 +27,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { return ( - + {children} @@ -87,7 +87,7 @@ const CommandGroup = React.forwardRef< = React.memo((props) => { +
+ +
+