import Heading from "@/components/ui/heading"; import { useCallback, useEffect, useMemo, useState } from "react"; import { Toaster } from "sonner"; import { Button } from "@/components/ui/button"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { useTranslation } from "react-i18next"; import { Label } from "@/components/ui/label"; import CameraEditForm from "@/components/settings/CameraEditForm"; import CameraWizardDialog from "@/components/settings/CameraWizardDialog"; import { LuPlus } from "react-icons/lu"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { IoMdArrowRoundBack } from "react-icons/io"; import { isDesktop } from "react-device-detect"; import { CameraNameLabel } from "@/components/camera/FriendlyNameLabel"; import { Switch } from "@/components/ui/switch"; import { Trans } from "react-i18next"; import { Separator } from "@/components/ui/separator"; import { useEnabledState } from "@/api/ws"; type CameraManagementViewProps = { setUnsavedChanges: React.Dispatch>; }; export default function CameraManagementView({ setUnsavedChanges, }: CameraManagementViewProps) { const { t } = useTranslation(["views/settings"]); const { data: config, mutate: updateConfig } = useSWR("config"); const [viewMode, setViewMode] = useState<"settings" | "add" | "edit">( "settings", ); // Control view state const [editCameraName, setEditCameraName] = useState( undefined, ); // Track camera being edited const [showWizard, setShowWizard] = useState(false); // List of cameras for dropdown const cameras = useMemo(() => { if (config) { return Object.keys(config.cameras).sort(); } return []; }, [config]); useEffect(() => { document.title = t("documentTitle.cameraManagement"); }, [t]); // Handle back navigation from add/edit form const handleBack = useCallback(() => { setViewMode("settings"); setEditCameraName(undefined); setUnsavedChanges(false); updateConfig(); }, [updateConfig, setUnsavedChanges]); return ( <>
{viewMode === "settings" ? ( <> {t("cameraManagement.title")}
{cameras.length > 0 && ( <>
cameraManagement.streams.title
cameraManagement.streams.desc
{cameras.map((camera) => (
))}
)}
) : ( <>
)}
setShowWizard(false)} /> ); } type CameraEnableSwitchProps = { cameraName: string; }; function CameraEnableSwitch({ cameraName }: CameraEnableSwitchProps) { const { payload: enabledState, send: sendEnabled } = useEnabledState(cameraName); return (
{ sendEnabled(isChecked ? "ON" : "OFF"); }} />
); }