diff --git a/package-lock.json b/package-lock.json index 960ea1d..a481422 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@monaco-editor/react": "^4.6.0", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", @@ -1157,6 +1158,12 @@ "node": ">=14" } }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", @@ -1581,6 +1588,49 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz", + "integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-separator": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.2.tgz", @@ -1722,6 +1772,21 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", diff --git a/package.json b/package.json index c5586a9..5341aea 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@monaco-editor/react": "^4.6.0", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", diff --git a/public/config.yaml b/public/config.yaml index 88e5c1f..63ad281 100644 --- a/public/config.yaml +++ b/public/config.yaml @@ -1,70 +1,46 @@ -sections: - - id: "system" - title: "System" - icon: "Server" - cardStyle: - background: "bg-blue-50 dark:bg-blue-950/30" - iconColor: "text-blue-600 dark:text-blue-400" - - - id: "media" - title: "Media" - icon: "Play" - cardStyle: - background: "bg-orange-50 dark:bg-orange-950/30" - iconColor: "text-orange-600 dark:text-orange-400" - - - id: "monitoring" - title: "Monitoring" - icon: "Activity" - cardStyle: - background: "bg-emerald-50 dark:bg-emerald-950/30" - iconColor: "text-emerald-600 dark:text-emerald-400" - - - id: "tools" - title: "Tools" - icon: "Settings" - cardStyle: - background: "bg-purple-50 dark:bg-purple-950/30" - iconColor: "text-purple-600 dark:text-purple-400" - - - id: "acot" - title: "ACOT" - icon: "LayoutDashboard" - cardStyle: - background: "bg-sky-50 dark:bg-sky-950/30" - iconColor: "text-sky-600 dark:text-sky-400" - - - id: "home" - title: "Home" - icon: "Home" - cardStyle: - background: "bg-indigo-50 dark:bg-indigo-950/30" - iconColor: "text-indigo-600 dark:text-indigo-400" +tags: + system: "System" + monitoring: "Monitoring" + tools: "Tools" + documents: "Documents" + acot: "ACOT" + home: "Home" + media: "Media" + # Infrastructure tags + docker: "Docker" + nas: "NAS" + security: "Security" + automation: "Automation" + network: "Network" + # Feature tags + analytics: "Analytics" + backup: "Backup" + ai: "AI" + notifications: "Notifications" + development: "Development" + management: "Management" + storage: "Storage" + documentation: "Documentation" + printing: "3D Printing" + camera: "Camera" + streaming: "Streaming" + download: "Download" services: +###### System - name: "Portainer" description: "Docker Manager" url: "https://portainer.kent.pw" iconName: "portainer" category: "system" - cardStyle: - background: "bg-blue-50 dark:bg-blue-950/30" - iconColor: "text-blue-600 dark:text-blue-400" - - - name: "Gitea" - description: "Git Server" - url: "https://gitea.kent.pw" - iconName: "gitea" - category: "system" - cardStyle: - background: "bg-green-50 dark:bg-green-950/30" - iconColor: "text-green-600 dark:text-green-400" + tags: ["system", "docker", "management"] - name: "Cockpit" description: "Server Management" url: "https://cockpit.kent.pw" iconName: "cockpit" category: "system" + tags: ["system", "management", "analytics"] - name: "DiskStation" description: "Synology NAS" @@ -72,52 +48,7 @@ services: iconName: "synology" category: "system" monitorName: "Synology Diskstation" - cardStyle: - background: "bg-slate-50 dark:bg-slate-950/30" - iconColor: "text-slate-600 dark:text-slate-400" - - - name: "Plex" - description: "Media Server" - url: "https://plex.kent.pw" - iconName: "plex" - category: "media" - cardStyle: - background: "bg-orange-50 dark:bg-orange-950/30" - iconColor: "text-orange-600 dark:text-orange-400" - - - name: "Sonarr" - description: "TV Manager" - url: "https://sonarr.kent.pw" - iconName: "sonarr" - category: "media" - cardStyle: - background: "bg-blue-50 dark:bg-blue-950/30" - iconColor: "text-blue-600 dark:text-blue-400" - - - name: "Jackett" - description: "Torrent Indexer" - url: "https://jackett.kent.pw" - iconName: "jackett" - category: "media" - - - name: "Deluge" - description: "Torrent Client" - url: "https://deluge.kent.pw" - iconName: "deluge" - category: "media" - cardStyle: - background: "bg-green-50 dark:bg-green-950/30" - iconColor: "text-green-600 dark:text-green-400" - - - name: "Uptime" - description: "Service Monitoring" - url: "https://uptime.kent.pw" - iconName: "uptime-kuma" - category: "monitoring" - monitorName: "Uptime Kuma" - cardStyle: - background: "bg-emerald-50 dark:bg-emerald-950/30" - iconColor: "text-emerald-600 dark:text-emerald-400" + tags: ["system", "nas", "storage", "backup"] - name: "AdGuard" description: "DNS Ad Blocking" @@ -125,32 +56,30 @@ services: iconName: "adguard-home" category: "system" monitorName: "Adguard Home" - cardStyle: - background: "bg-green-50 dark:bg-green-950/30" - iconColor: "text-green-600 dark:text-green-400" + tags: ["system", "network", "security"] - - name: "NocoDB" - description: "Database Platform" - url: "https://noco.kent.pw" - iconName: "nocodb" - category: "tools" - monitorName: "NocoDB" + - name: "Authelia" + description: "Service Protection" + url: "https://auth.kent.pw" + iconName: "authelia" + category: "system" + tags: ["system", "security", "management"] - - name: "IT Tools" - description: "Developer Utilities" - url: "https://ittools.kent.pw" - iconName: "it-tools" - category: "tools" - monitorName: "IT Tools" - - - name: "Firefox" - description: "Browser Instance" - url: "https://firefox.kent.pw" - iconName: "firefox" - category: "tools" - cardStyle: - background: "bg-orange-50 dark:bg-orange-950/30" - iconColor: "text-orange-600 dark:text-orange-400" + - name: "OliveTin" + description: "Run Scripts" + url: "https://olivetin.kent.pw" + iconName: "olivetin" + category: "system" + tags: ["system", "automation", "management"] + +###### Monitoring + - name: "Uptime" + description: "Service Monitoring" + url: "https://uptime.kent.pw" + iconName: "uptime-kuma" + category: "monitoring" + monitorName: "Uptime Kuma" + tags: ["monitoring", "analytics", "notifications"] - name: "Speedtest" description: "Internet Speed" @@ -158,9 +87,7 @@ services: iconName: "speedtest-tracker" category: "monitoring" monitorName: "Speedtest Tracker" - cardStyle: - background: "bg-blue-50 dark:bg-blue-950/30" - iconColor: "text-blue-600 dark:text-blue-400" + tags: ["monitoring", "network", "analytics"] - name: "Netdata" description: "Server Monitoring" @@ -168,9 +95,52 @@ services: iconName: "netdata" category: "monitoring" monitorName: "Netdata" - cardStyle: - background: "bg-purple-50 dark:bg-purple-950/30" - iconColor: "text-purple-600 dark:text-purple-400" + tags: ["monitoring", "analytics", "system"] + + - name: "Beszel" + description: "Server Monitoring" + url: "https://beszel.kent.pw" + iconName: "beszel" + category: "monitoring" + tags: ["monitoring", "analytics", "system"] + + - name: "Dockwatch" + description: "Docker Monitoring" + url: "https://dockwatch.kent.pw" + iconName: "dockwatch" + category: "monitoring" + tags: ["monitoring", "docker", "analytics"] + +###### Tools + - name: "Gitea" + description: "Git Server" + url: "https://gitea.kent.pw" + iconName: "gitea" + category: "tools" + tags: ["tools", "development", "management"] + + - name: "NocoDB" + description: "Database Platform" + url: "https://noco.kent.pw" + iconName: "nocodb" + category: "tools" + monitorName: "NocoDB" + tags: ["tools", "development", "storage"] + + - name: "IT Tools" + description: "Developer Utilities" + url: "https://ittools.kent.pw" + iconName: "it-tools" + category: "tools" + monitorName: "IT Tools" + tags: ["tools", "development"] + + - name: "Firefox" + description: "Browser Instance" + url: "https://firefox.kent.pw" + iconName: "firefox" + category: "tools" + tags: ["tools", "automation"] - name: "FileBrowser" description: "Edit Server Files" @@ -179,48 +149,80 @@ services: category: "tools" monitorName: "File Browser" cardStyle: - background: "bg-blue-50 dark:bg-blue-950/30" - iconColor: "text-blue-600 dark:text-blue-400" + iconColor: "text-sky-500 dark:text-sky-600" + tags: ["tools", "management", "storage"] + + - name: "Color Picker" + description: "Convert Colors" + url: "https://kent.pw/color-picker" + iconName: "lucide-rainbow" + category: "tools" + monitorName: "Color-Picker" + cardStyle: + iconColor: "text-indigo-500 dark:text-indigo-600" + tags: ["tools", "development"] + - name: "Ntfy" + description: "Send Notifications" + url: "https://ntfy.kent.pw" + iconName: "ntfy" + category: "tools" + tags: ["tools", "notifications", "automation"] + +###### Documents - name: "Drive" description: "File Storage" url: "https://drive.kent.pw" iconName: "synology" - category: "tools" + category: "documents" monitorName: "Synology Drive" + tags: ["documents", "storage", "backup"] + - name: "Paperless" + description: "Document Storage" + url: "https://paperless.kent.pw" + iconName: "paperless-ngx" + category: "documents" + tags: ["documents", "storage", "documentation"] + + - name: "Paperless-AI" + description: "Enhance Paperless" + url: "https://paperless-ai.kent.pw" + iconName: "lucide-leaf" + category: "documents" + cardStyle: + iconColor: "text-blue-500 dark:text-blue-600" + tags: ["documents", "ai", "automation"] + +###### ACOT - name: "Dashboard" description: "ACOT Dashboard" url: "https://dashboard.kent.pw" iconName: "lucide-layout-dashboard" category: "acot" - cardStyle: - background: "bg-sky-50 dark:bg-sky-950/30" - iconColor: "text-sky-600 dark:text-sky-400" + tags: ["acot", "analytics", "management"] - name: "Inventory" description: "ACOT Inventory" url: "https://inventory.kent.pw" iconName: "lucide-box" category: "acot" + tags: ["acot", "management", "storage"] +###### Home - name: "Homebridge" description: "HomeKit Bridge" url: "https://homebridge.kent.pw" iconName: "homebridge" category: "home" - cardStyle: - background: "bg-purple-50 dark:bg-purple-950/30" - iconColor: "text-purple-600 dark:text-purple-400" + tags: ["home", "automation", "management"] - name: "Scrypted" description: "Manage Cameras" url: "https://scrypted.kent.pw" iconName: "scrypted" category: "home" - cardStyle: - background: "bg-indigo-50 dark:bg-indigo-950/30" - iconColor: "text-indigo-600 dark:text-indigo-400" + tags: ["home", "camera", "streaming"] - name: "3D Printer" description: "Fluidd Interface" @@ -228,9 +230,14 @@ services: iconName: "fluidd" category: "home" monitorName: "Printer" - cardStyle: - background: "bg-sky-50 dark:bg-sky-950/30" - iconColor: "text-sky-600 dark:text-sky-400" + tags: ["home", "printing", "automation"] + + - name: "Spoolman" + description: "Manage Filament" + url: "https://spoolman.kent.pw" + iconName: "spoolman" + category: "home" + tags: ["home", "printing", "management"] - name: "Go2RTC" description: "Stream Cameras" @@ -238,6 +245,33 @@ services: iconName: "lucide-webcam" category: "home" monitorName: "Go2RTC" - cardStyle: - background: "bg-orange-50 dark:bg-orange-950/30" - iconColor: "text-orange-600 dark:text-orange-400" \ No newline at end of file + tags: ["home", "camera", "streaming"] + +###### Media + - name: "Plex" + description: "Media Server" + url: "https://plex.kent.pw" + iconName: "plex" + category: "media" + tags: ["media", "streaming", "management"] + + - name: "Sonarr" + description: "TV Manager" + url: "https://sonarr.kent.pw" + iconName: "sonarr" + category: "media" + tags: ["media", "download", "automation"] + + - name: "Jackett" + description: "Torrent Indexer" + url: "https://jackett.kent.pw" + iconName: "jackett" + category: "media" + tags: ["media", "download"] + + - name: "Deluge" + description: "Torrent Client" + url: "https://deluge.kent.pw" + iconName: "deluge" + category: "media" + tags: ["media", "download"] \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index e61c9ca..36ad70a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,4 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Separator } from "@/components/ui/separator" import { Button } from "@/components/ui/button" import { Moon, Sun, Monitor} from "lucide-react" import * as LucideIcons from "lucide-react" @@ -7,10 +6,14 @@ import { useTheme } from "@/components/theme-provider" import { useMetrics } from "./hooks/useMetrics" import { useConfig } from "./hooks/useConfig" import { ServiceStatus } from "./types/metrics" -import { ServiceCard, Section, CardStyle } from "./types/services" +import { ServiceCard, CardStyle, Config } from "./types/services" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { AlertCircle } from "lucide-react" +import { AlertCircle, Search, ArrowUpDown, X } from "lucide-react" +import { Input } from "@/components/ui/input" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Badge } from "@/components/ui/badge" +import { useState, useMemo, useRef, useEffect } from "react" const getIconUrl = (name: string | undefined, isDark: boolean = false): string => { if (!name) return '' @@ -21,7 +24,7 @@ const getIconUrl = (name: string | undefined, isDark: boolean = false): string = return `https://cdn.jsdelivr.net/gh/selfhst/icons/png/${ref}${suffix}.png` } -function ServiceIcon({ service, section, isDark }: { service: ServiceCard, section: Section, isDark: boolean }) { +function ServiceIcon({ service, isDark }: { service: ServiceCard, isDark: boolean }) { if (service.icon) { return