diff --git a/web/src/App.tsx b/web/src/App.tsx index 743d98711..98385fc20 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -25,7 +25,7 @@ function App() { -
+
{isDesktop && } {isDesktop && } {isMobile && } diff --git a/web/src/components/navigation/Bottombar.tsx b/web/src/components/navigation/Bottombar.tsx index 68b28d22a..bee4a0616 100644 --- a/web/src/components/navigation/Bottombar.tsx +++ b/web/src/components/navigation/Bottombar.tsx @@ -1,6 +1,5 @@ import { navbarLinks } from "@/pages/site-navigation"; import NavItem from "./NavItem"; -import SettingsNavItems from "../settings/SettingsNavItems"; import { IoIosWarning } from "react-icons/io"; import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer"; import useSWR from "swr"; @@ -8,6 +7,8 @@ import { FrigateStats } from "@/types/stats"; import { useFrigateStats } from "@/api/ws"; import { useMemo } from "react"; import useStats from "@/hooks/use-stats"; +import GeneralSettings from "../settings/GeneralSettings"; +import AccountSettings from "../settings/AccountSettings"; function Bottombar() { return ( @@ -23,7 +24,8 @@ function Bottombar() { dev={item.dev} /> ))} - + +
); diff --git a/web/src/components/navigation/Sidebar.tsx b/web/src/components/navigation/Sidebar.tsx index 024c9113c..61ad84a38 100644 --- a/web/src/components/navigation/Sidebar.tsx +++ b/web/src/components/navigation/Sidebar.tsx @@ -1,9 +1,10 @@ import Logo from "../Logo"; import { navbarLinks } from "@/pages/site-navigation"; -import SettingsNavItems from "../settings/SettingsNavItems"; import NavItem from "./NavItem"; import { CameraGroupSelector } from "../filter/CameraGroupSelector"; import { useLocation } from "react-router-dom"; +import GeneralSettings from "../settings/GeneralSettings"; +import AccountSettings from "../settings/AccountSettings"; function Sidebar() { const location = useLocation(); @@ -31,7 +32,10 @@ function Sidebar() { ); })}
- +
+ + +
); } diff --git a/web/src/components/settings/AccountSettings.tsx b/web/src/components/settings/AccountSettings.tsx new file mode 100644 index 000000000..e5881465e --- /dev/null +++ b/web/src/components/settings/AccountSettings.tsx @@ -0,0 +1,22 @@ +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { VscAccount } from "react-icons/vsc"; +import { Button } from "../ui/button"; + +export default function AccountSettings() { + return ( + + + + + +

Account

+
+
+ ); +} diff --git a/web/src/components/settings/GeneralSettings.tsx b/web/src/components/settings/GeneralSettings.tsx new file mode 100644 index 000000000..ba2168980 --- /dev/null +++ b/web/src/components/settings/GeneralSettings.tsx @@ -0,0 +1,420 @@ +import { + LuActivity, + LuGithub, + LuHardDrive, + LuLifeBuoy, + LuList, + LuMoon, + LuPenSquare, + LuRotateCw, + LuSettings, + LuSun, + LuSunMoon, +} from "react-icons/lu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from "../ui/dropdown-menu"; +import { Button } from "../ui/button"; +import { Link } from "react-router-dom"; +import { CgDarkMode } from "react-icons/cg"; +import { + colorSchemes, + friendlyColorSchemeName, + useTheme, +} from "@/context/theme-provider"; +import { IoColorPalette } from "react-icons/io5"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "../ui/alert-dialog"; +import { useEffect, useState } from "react"; +import { useRestart } from "@/api/ws"; +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, +} from "../ui/sheet"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import ActivityIndicator from "../indicators/activity-indicator"; +import { isDesktop } from "react-device-detect"; +import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer"; +import { + Dialog, + DialogClose, + DialogContent, + DialogPortal, + DialogTrigger, +} from "../ui/dialog"; + +type GeneralSettings = { + className?: string; +}; +export default function GeneralSettings({ className }: GeneralSettings) { + const { theme, colorScheme, setTheme, setColorScheme } = useTheme(); + const [restartDialogOpen, setRestartDialogOpen] = useState(false); + const [restartingSheetOpen, setRestartingSheetOpen] = useState(false); + const [countdown, setCountdown] = useState(60); + + const { send: sendRestart } = useRestart(); + + useEffect(() => { + let countdownInterval: NodeJS.Timeout; + + if (restartingSheetOpen) { + countdownInterval = setInterval(() => { + setCountdown((prevCountdown) => prevCountdown - 1); + }, 1000); + } + + return () => { + clearInterval(countdownInterval); + }; + }, [restartingSheetOpen]); + + useEffect(() => { + if (countdown === 0) { + window.location.href = "/"; + } + }, [countdown]); + + const handleForceReload = () => { + window.location.href = "/"; + }; + + const Container = isDesktop ? DropdownMenu : Drawer; + const Trigger = isDesktop ? DropdownMenuTrigger : DrawerTrigger; + const Content = isDesktop ? DropdownMenuContent : DrawerContent; + const MenuItem = isDesktop ? DropdownMenuItem : DialogClose; + const SubItem = isDesktop ? DropdownMenuSub : Dialog; + const SubItemTrigger = isDesktop ? DropdownMenuSubTrigger : DialogTrigger; + const SubItemContent = isDesktop ? DropdownMenuSubContent : DialogContent; + const Portal = isDesktop ? DropdownMenuPortal : DialogPortal; + + return ( + <> +
+ + + + + + + + +

Settings

+
+
+
+
+ +
+ System + + + + + + Storage + + + + + + System metrics + + + + + + System logs + + + + + Configuration + + + + + + + Settings + + + + + + Configuration editor + + + + Appearance + + + + + + Dark Mode + + + + + setTheme("light")} + > + {theme === "light" ? ( + <> + + Light + + ) : ( + Light + )} + + setTheme("dark")} + > + {theme === "dark" ? ( + <> + + Dark + + ) : ( + Dark + )} + + setTheme("system")} + > + {theme === "system" ? ( + <> + + System + + ) : ( + System + )} + + + + + + + + Theme + + + + + {colorSchemes.map((scheme) => ( + setColorScheme(scheme)} + > + {scheme === colorScheme ? ( + <> + + {friendlyColorSchemeName(scheme)} + + ) : ( + + {friendlyColorSchemeName(scheme)} + + )} + + ))} + + + + + + Help + + + + + + Documentation + + + + + + GitHub + + + + setRestartDialogOpen(true)} + > + + Restart Frigate + +
+
+
+
+ {restartDialogOpen && ( + setRestartDialogOpen(false)} + > + + + + Are you sure you want to restart Frigate? + + + + Cancel + { + setRestartingSheetOpen(true); + sendRestart("restart"); + }} + > + Restart + + + + + )} + {restartingSheetOpen && ( + <> + setRestartingSheetOpen(false)} + > + e.preventDefault()} + > +
+ + + + Frigate is Restarting + + +

This page will reload in {countdown} seconds.

+
+
+ +
+
+
+ + )} + + ); +} diff --git a/web/src/components/settings/SettingsNavItems.tsx b/web/src/components/settings/SettingsNavItems.tsx deleted file mode 100644 index a43c7bb91..000000000 --- a/web/src/components/settings/SettingsNavItems.tsx +++ /dev/null @@ -1,312 +0,0 @@ -import { - LuActivity, - LuGithub, - LuHardDrive, - LuLifeBuoy, - LuList, - LuMoon, - LuPenSquare, - LuRotateCw, - LuSettings, - LuSun, - LuSunMoon, -} from "react-icons/lu"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuPortal, - DropdownMenuSeparator, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger, -} from "../ui/dropdown-menu"; -import { Button } from "../ui/button"; -import { Link } from "react-router-dom"; -import { CgDarkMode } from "react-icons/cg"; -import { VscAccount } from "react-icons/vsc"; -import { - colorSchemes, - friendlyColorSchemeName, - useTheme, -} from "@/context/theme-provider"; -import { IoColorPalette } from "react-icons/io5"; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, -} from "../ui/alert-dialog"; -import { useEffect, useState } from "react"; -import { useRestart } from "@/api/ws"; -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, -} from "../ui/sheet"; -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/components/ui/tooltip"; -import ActivityIndicator from "../indicators/activity-indicator"; - -type SettingsNavItemsProps = { - className?: string; -}; -export default function SettingsNavItems({ className }: SettingsNavItemsProps) { - const { theme, colorScheme, setTheme, setColorScheme } = useTheme(); - const [restartDialogOpen, setRestartDialogOpen] = useState(false); - const [restartingSheetOpen, setRestartingSheetOpen] = useState(false); - const [countdown, setCountdown] = useState(60); - - const { send: sendRestart } = useRestart(); - - useEffect(() => { - let countdownInterval: NodeJS.Timeout; - - if (restartingSheetOpen) { - countdownInterval = setInterval(() => { - setCountdown((prevCountdown) => prevCountdown - 1); - }, 1000); - } - - return () => { - clearInterval(countdownInterval); - }; - }, [restartingSheetOpen]); - - useEffect(() => { - if (countdown === 0) { - window.location.href = "/"; - } - }, [countdown]); - - const handleForceReload = () => { - window.location.href = "/"; - }; - - return ( - <> -
- - - - - - - - -

Settings

-
-
-
-
- - System - - - - - - Storage - - - - - - System metrics - - - - - - System logs - - - - - Configuration - - - - - - - Settings - - - - - - Configuration editor - - - Appearance - - - - - Dark Mode - - - - setTheme("light")}> - {theme === "light" ? ( - <> - - Light - - ) : ( - Light - )} - - setTheme("dark")}> - {theme === "dark" ? ( - <> - - Dark - - ) : ( - Dark - )} - - setTheme("system")}> - {theme === "system" ? ( - <> - - System - - ) : ( - System - )} - - - - - - - - Theme - - - - {colorSchemes.map((scheme) => ( - setColorScheme(scheme)} - > - {scheme === colorScheme ? ( - <> - - {friendlyColorSchemeName(scheme)} - - ) : ( - - {friendlyColorSchemeName(scheme)} - - )} - - ))} - - - - - Help - - - - - Documentation - - - - - - GitHub - - - - setRestartDialogOpen(true)}> - - Restart Frigate - - -
- - - - - -

Account

-
-
-
- {restartDialogOpen && ( - setRestartDialogOpen(false)} - > - - - - Are you sure you want to restart Frigate? - - - - Cancel - { - setRestartingSheetOpen(true); - sendRestart("restart"); - }} - > - Restart - - - - - )} - {restartingSheetOpen && ( - <> - setRestartingSheetOpen(false)} - > - e.preventDefault()} - > -
- - - - Frigate is Restarting - - -

This page will reload in {countdown} seconds.

-
-
- -
-
-
- - )} - - ); -}