import { LuActivity, LuGithub, LuLanguages, LuLifeBuoy, LuList, LuLogOut, LuMoon, LuSquarePen, LuScanFace, 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 { 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 { useState } from "react"; import { useRestart } from "@/api/ws"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import { isDesktop, isMobile } from "react-device-detect"; import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer"; import { Dialog, DialogClose, DialogContent, DialogPortal, DialogTrigger, } from "../ui/dialog"; import { TooltipPortal } from "@radix-ui/react-tooltip"; import { cn } from "@/lib/utils"; import useSWR from "swr"; import RestartDialog from "../overlay/dialog/RestartDialog"; import { useLanguage } from "@/context/language-provider"; import { useIsAdmin } from "@/hooks/use-is-admin"; import SetPasswordDialog from "../overlay/SetPasswordDialog"; import { toast } from "sonner"; import axios from "axios"; import { FrigateConfig } from "@/types/frigateConfig"; import { useTranslation } from "react-i18next"; type GeneralSettingsProps = { className?: string; }; export default function GeneralSettings({ className }: GeneralSettingsProps) { const { t } = useTranslation(["common", "views/settings"]); const { data: profile } = useSWR("profile"); const { data: config } = useSWR("config"); const logoutUrl = config?.proxy?.logout_url || "/api/logout"; // settings const { language, setLanguage } = useLanguage(); const { theme, colorScheme, setTheme, setColorScheme } = useTheme(); const [restartDialogOpen, setRestartDialogOpen] = useState(false); const [passwordDialogOpen, setPasswordDialogOpen] = useState(false); const { send: sendRestart } = useRestart(); const isAdmin = useIsAdmin(); 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; const handlePasswordSave = async (password: string) => { if (!profile?.username || profile.username === "anonymous") return; axios .put(`users/${profile.username}/password`, { password }) .then((response) => { if (response.status === 200) { setPasswordDialogOpen(false); toast.success( t("users.toast.success.updatePassword", { ns: "views/settings", }), { position: "top-center", }, ); } }) .catch((error) => { const errorMessage = error.response?.data?.message || error.response?.data?.detail || "Unknown error"; toast.error( t("users.toast.error.setPasswordFailed", { ns: "views/settings", errorMessage, }), { position: "top-center", }, ); }); }; return ( <>

{t("menu.settings")}

{isMobile && (
{t("menu.user.current", { user: profile?.username || t("menu.user.anonymous"), })}{" "} {t("role." + profile?.role) && `(${t("role." + profile?.role)})`} {profile?.username && profile.username !== "anonymous" && ( setPasswordDialogOpen(true)} > {t("menu.user.setPassword", { ns: "common" })} )} {t("menu.user.logout", { ns: "common" })}
)} {isAdmin && ( <> {t("menu.system")} {t("menu.systemMetrics")} {t("menu.systemLogs")} )} {t("menu.configuration")} {t("menu.settings")} {isAdmin && ( <> {t("menu.configurationEditor")} )} {isAdmin && isMobile && config?.face_recognition.enabled && ( <> {t("menu.faceLibrary")} )} {t("menu.appearance")} {t("menu.languages")} setLanguage("en")} > {language.trim() === "en" ? ( <> {t("menu.language.en")} ) : ( {t("menu.language.en")} )} setLanguage("zh-CN")} > {language === "zh-CN" ? ( <> {t("menu.language.zhCN")} ) : ( {t("menu.language.zhCN")} )} {t("menu.darkMode.label")} setTheme("light")} > {theme === "light" ? ( <> {t("menu.darkMode.light")} ) : ( {t("menu.darkMode.light")} )} setTheme("dark")} > {theme === "dark" ? ( <> {t("menu.darkMode.dark")} ) : ( {t("menu.darkMode.dark")} )} setTheme("system")} > {theme === "system" ? ( <> {t("menu.withSystem")} ) : ( {t("menu.withSystem")} )} {t("menu.theme.label")} {colorSchemes.map((scheme) => ( setColorScheme(scheme)} > {scheme === colorScheme ? ( <> {t(friendlyColorSchemeName(scheme))} ) : ( {t(friendlyColorSchemeName(scheme))} )} ))} {t("menu.help")} {t("menu.documentation.title")} GitHub {isAdmin && ( <> setRestartDialogOpen(true)} > {t("menu.restart")} )}
setRestartDialogOpen(false)} onRestart={() => sendRestart("restart")} /> setPasswordDialogOpen(false)} username={profile?.username} /> ); }