diff --git a/web/public/locales/en/views/classificationModel.json b/web/public/locales/en/views/classificationModel.json
index f28cb3753..dcfc5a1b2 100644
--- a/web/public/locales/en/views/classificationModel.json
+++ b/web/public/locales/en/views/classificationModel.json
@@ -49,5 +49,9 @@
"new": "Create New Class"
},
"categorizeImageAs": "Classify Image As:",
- "categorizeImage": "Classify Image"
+ "categorizeImage": "Classify Image",
+ "wizard": {
+ "title": "Create New Classification",
+ "description": "Create a new state or object classification model."
+ }
}
diff --git a/web/src/components/classification/ClassificationModelWizardDialog.tsx b/web/src/components/classification/ClassificationModelWizardDialog.tsx
new file mode 100644
index 000000000..c6c06baa2
--- /dev/null
+++ b/web/src/components/classification/ClassificationModelWizardDialog.tsx
@@ -0,0 +1,66 @@
+import { useTranslation } from "react-i18next";
+import StepIndicator from "../indicators/StepIndicator";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+} from "../ui/dialog";
+import { useState } from "react";
+
+const STEPS = [
+ "classificationWizard.steps.nameAndDefine",
+ "classificationWizard.steps.stateArea",
+ "classificationWizard.steps.chooseExamples",
+ "classificationWizard.steps.train",
+];
+
+type ClassificationModelWizardDialogProps = {
+ open: boolean;
+ onClose: () => void;
+};
+export default function ClassificationModelWizardDialog({
+ open,
+ onClose,
+}: ClassificationModelWizardDialogProps) {
+ const { t } = useTranslation(["views/classificationModel"]);
+
+ // step management
+ const [currentStep, setCurrentStep] = useState(0);
+
+ return (
+
+ );
+}
diff --git a/web/src/types/frigateConfig.ts b/web/src/types/frigateConfig.ts
index f82ca9838..ffe4cc14d 100644
--- a/web/src/types/frigateConfig.ts
+++ b/web/src/types/frigateConfig.ts
@@ -304,10 +304,10 @@ export type CustomClassificationModelConfig = {
enabled: boolean;
name: string;
threshold: number;
- object_config: null | {
+ object_config?: {
objects: string[];
};
- state_config: null | {
+ state_config?: {
cameras: {
[cameraName: string]: {
crop: [number, number, number, number];
diff --git a/web/src/views/classification/ModelSelectionView.tsx b/web/src/views/classification/ModelSelectionView.tsx
index c6366a139..e4db0ab5b 100644
--- a/web/src/views/classification/ModelSelectionView.tsx
+++ b/web/src/views/classification/ModelSelectionView.tsx
@@ -1,4 +1,5 @@
import { baseUrl } from "@/api/baseUrl";
+import ClassificationModelWizardDialog from "@/components/classification/ClassificationModelWizardDialog";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import { Button } from "@/components/ui/button";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
@@ -52,6 +53,10 @@ export default function ModelSelectionView({
});
}, [config, pageToggle]);
+ // new model wizard
+
+ const [newModel, setNewModel] = useState(false);
+
if (!config) {
return