From 4bad308669be85334fa042f242a53506461f869b Mon Sep 17 00:00:00 2001
From: Samed <sbalcioglu@graphpolaris.com>
Date: Mon, 9 Dec 2024 13:35:39 +0000
Subject: [PATCH] feat: persist report on the backend

---
 .../lib/components/textEditor/TextEditor.tsx  |  59 +++--
 .../components/textEditor/VariableNode.tsx    |  26 ++-
 .../plugins/InsertVariablesPlugin.tsx         |   1 +
 .../textEditor/plugins/SaveButtonPlugin.tsx   |  18 ++
 .../textEditor/plugins/ToolbarPlugin.tsx      |   5 +-
 libs/shared/lib/data-access/api/eventBus.tsx  |   4 +-
 libs/shared/lib/data-access/broker/types.ts   |   2 +-
 .../data-access/broker/wsInsightSharing.ts    |  93 ++++++++
 libs/shared/lib/data-access/store/hooks.ts    |   4 +
 .../data-access/store/insightSharingSlice.ts  |  74 +++++++
 libs/shared/lib/data-access/store/store.ts    |   2 +
 libs/shared/lib/insight-sharing/FormAlert.tsx | 178 +++++++++++++++
 .../shared/lib/insight-sharing/FormReport.tsx | 203 ++++++++++++++++++
 .../lib/insight-sharing/InsightDialog.tsx     |  59 ++---
 .../lib/insight-sharing/SettingsPanel.tsx     |  53 -----
 .../insight-sharing/alerting/AlertingForm.tsx |  43 ----
 .../insight-sharing/components/AddItem.tsx    |  52 ++++-
 .../insight-sharing/components/Sidebar.tsx    |  89 ++++----
 .../components/StartScreen.tsx                |  11 +-
 .../reporting/ReportingForm.tsx               |  57 -----
 20 files changed, 783 insertions(+), 250 deletions(-)
 create mode 100644 libs/shared/lib/components/textEditor/plugins/SaveButtonPlugin.tsx
 create mode 100644 libs/shared/lib/data-access/broker/wsInsightSharing.ts
 create mode 100644 libs/shared/lib/data-access/store/insightSharingSlice.ts
 create mode 100644 libs/shared/lib/insight-sharing/FormAlert.tsx
 create mode 100644 libs/shared/lib/insight-sharing/FormReport.tsx
 delete mode 100644 libs/shared/lib/insight-sharing/SettingsPanel.tsx
 delete mode 100644 libs/shared/lib/insight-sharing/alerting/AlertingForm.tsx
 delete mode 100644 libs/shared/lib/insight-sharing/reporting/ReportingForm.tsx

diff --git a/libs/shared/lib/components/textEditor/TextEditor.tsx b/libs/shared/lib/components/textEditor/TextEditor.tsx
index 2b931b872..32664ad31 100644
--- a/libs/shared/lib/components/textEditor/TextEditor.tsx
+++ b/libs/shared/lib/components/textEditor/TextEditor.tsx
@@ -1,43 +1,61 @@
-import { useRef } from 'react';
+import { useEffect, useRef, useCallback } from 'react';
 import { LexicalComposer } from '@lexical/react/LexicalComposer';
 import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
 import { ContentEditable } from '@lexical/react/LexicalContentEditable';
 import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
-import { LexicalEditor, EditorState } from 'lexical';
-import { $generateHtmlFromNodes } from '@lexical/html';
-import { MyOnChangePlugin } from './plugins/StateChangePlugin';
+import { SerializedEditorState} from 'lexical';
 import { ToolbarPlugin } from './plugins/ToolbarPlugin';
 import { PreviewPlugin } from './plugins/PreviewPlugin';
 import { InsertVariablesPlugin } from './plugins/InsertVariablesPlugin';
 import { ErrorHandler } from './ErrorHandler';
 import { Placeholder } from './Placeholder';
 import { VariableNode } from './VariableNode';
-import { fontFamily } from 'html2canvas/dist/types/css/property-descriptors/font-family';
+import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
+import { SaveButtonPlugin } from './plugins/SaveButtonPlugin';
 
 type TextEditorProps = {
-  editorState: EditorState | undefined;
-  setEditorState: (value: EditorState) => void;
+  children: React.ReactNode;
+  editorState: SerializedEditorState | null;
+  setEditorState: (value: SerializedEditorState) => void;
   showToolbar: boolean;
   placeholder?: string;
+  handleSave: (elements: SerializedEditorState) => void;
 };
 
-export function TextEditor({ editorState, setEditorState, showToolbar, placeholder }: TextEditorProps) {
-  function onChange(editorState: EditorState, editor: LexicalEditor) {
-    setEditorState(editorState);
-    editor.read(() => {
-      // TODO:
+function InitialStateLoader({ editorState }: { editorState: SerializedEditorState | null}) {
+  const [editor] = useLexicalComposerContext();
+  const previousEditorStateRef = useRef<string | null>(null);
+  
+  useEffect(() => {
+    if (!editor || !editorState) return;
+    queueMicrotask(() => { 
+      editor.setEditorState(editor.parseEditorState(editorState));
     });
-  }
+    
+  }, [editor, editorState]);
+
+  return null;
+}
+
+export function TextEditor({ editorState, showToolbar, placeholder, handleSave, children }: TextEditorProps) {
+  const contentEditableRef = useRef<HTMLDivElement>(null);
+  const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null);
+  const isUpdatingRef = useRef(false);
+
+  useEffect(() => {
+    return () => {
+      if (updateTimeoutRef.current) {
+        clearTimeout(updateTimeoutRef.current);
+      }
+    };
+  }, []);
 
   const initialConfig = {
     namespace: 'MyEditor',
-    editorState: editorState,
     onError: ErrorHandler,
     nodes: [VariableNode],
   };
 
-  const contentEditableRef = useRef<HTMLDivElement>(null);
-
   return (
     <LexicalComposer initialConfig={initialConfig}>
       <div className="editor-toolbar flex items-center bg-secondary-50 rounded mt-4 space-x-2">
@@ -54,8 +72,13 @@ export function TextEditor({ editorState, setEditorState, showToolbar, placehold
         </div>
         <div className="preview min-h-24 p-3 hidden"></div>
       </div>
-      <MyOnChangePlugin onChange={onChange} />
       <InsertVariablesPlugin />
+      <InitialStateLoader editorState={editorState} />
+      <div className='flex justify-end mt-3'>
+        {children}
+        <SaveButtonPlugin 
+        onChange={handleSave}></SaveButtonPlugin>
+      </div>
     </LexicalComposer>
   );
-}
+}
\ No newline at end of file
diff --git a/libs/shared/lib/components/textEditor/VariableNode.tsx b/libs/shared/lib/components/textEditor/VariableNode.tsx
index 300242055..a2341e498 100644
--- a/libs/shared/lib/components/textEditor/VariableNode.tsx
+++ b/libs/shared/lib/components/textEditor/VariableNode.tsx
@@ -1,4 +1,4 @@
-import type { NodeKey, LexicalEditor, DOMExportOutput } from 'lexical';
+import type { NodeKey, LexicalEditor, DOMExportOutput, SerializedLexicalNode, Spread } from 'lexical';
 import { DecoratorNode, EditorConfig } from 'lexical';
 
 export enum VariableType {
@@ -6,6 +6,14 @@ export enum VariableType {
   visualization = 'visualization',
 }
 
+export type SerializedVariableNode = Spread<
+  {
+    name: string,
+    variableType: VariableType
+  },
+  SerializedLexicalNode
+>;
+
 export class VariableNode extends DecoratorNode<JSX.Element> {
   __name: string;
   __variableType: VariableType;
@@ -39,6 +47,22 @@ export class VariableNode extends DecoratorNode<JSX.Element> {
     return `{{ ${self.__variableType}:${self.__name} }}`;
   }
 
+  // Import and export
+
+  exportJSON(): SerializedVariableNode {
+    return {
+      type: this.getType(),
+      variableType: this.__variableType,
+      name: this.__name,
+      version: 1,
+    };
+  }
+
+  static importJSON(jsonNode: SerializedVariableNode): VariableNode {
+    const node = new VariableNode(jsonNode.name, jsonNode.variableType);
+    return node;
+  }
+
   // View
 
   createDOM(config: EditorConfig): HTMLElement {
diff --git a/libs/shared/lib/components/textEditor/plugins/InsertVariablesPlugin.tsx b/libs/shared/lib/components/textEditor/plugins/InsertVariablesPlugin.tsx
index c854fe4a2..c996a62e5 100644
--- a/libs/shared/lib/components/textEditor/plugins/InsertVariablesPlugin.tsx
+++ b/libs/shared/lib/components/textEditor/plugins/InsertVariablesPlugin.tsx
@@ -44,6 +44,7 @@ export const InsertVariablesPlugin = () => {
     <>
       {nodeTypes.map((nodeType) => (
         <Input
+          key={nodeType}
           type="dropdown"
           label={`${nodeType} variable`}
           value=""
diff --git a/libs/shared/lib/components/textEditor/plugins/SaveButtonPlugin.tsx b/libs/shared/lib/components/textEditor/plugins/SaveButtonPlugin.tsx
new file mode 100644
index 000000000..b4c8944ed
--- /dev/null
+++ b/libs/shared/lib/components/textEditor/plugins/SaveButtonPlugin.tsx
@@ -0,0 +1,18 @@
+import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
+import { Button } from '../../buttons';
+import { SerializedEditorState } from 'lexical';
+
+export function SaveButtonPlugin({ onChange }: { onChange: (elements: SerializedEditorState) => void }) {
+    const [editor] = useLexicalComposerContext();
+
+    function handleSave() {
+        editor.read(() => {
+            const data = editor.getEditorState();
+            const jsonData = data.toJSON();
+
+           onChange(jsonData);
+        })
+    }
+
+    return <Button label="Save" variantType="primary" className="ml-2" onClick={handleSave} />;
+}
diff --git a/libs/shared/lib/components/textEditor/plugins/ToolbarPlugin.tsx b/libs/shared/lib/components/textEditor/plugins/ToolbarPlugin.tsx
index e4b1ec07e..041367db0 100644
--- a/libs/shared/lib/components/textEditor/plugins/ToolbarPlugin.tsx
+++ b/libs/shared/lib/components/textEditor/plugins/ToolbarPlugin.tsx
@@ -19,8 +19,9 @@ export function ToolbarPlugin() {
   };
 
   return [
-    <div style={{ flex: '1 1 auto' }}></div>,
+    <div key= "spacer" style={{ flex: '1 1 auto' }}></div>,
     <Button
+      key = "bold"
       className="my-2"
       variantType="secondary"
       variant="ghost"
@@ -29,6 +30,7 @@ export function ToolbarPlugin() {
       onClick={formatBold}
     />,
     <Button
+      key="italic"
       className="my-2"
       variantType="secondary"
       variant="ghost"
@@ -37,6 +39,7 @@ export function ToolbarPlugin() {
       onClick={formatItalic}
     />,
     <Button
+      key="underline"
       className="my-2 me-2"
       variantType="secondary"
       variant="ghost"
diff --git a/libs/shared/lib/data-access/api/eventBus.tsx b/libs/shared/lib/data-access/api/eventBus.tsx
index 03d9e7f29..d58c915cf 100644
--- a/libs/shared/lib/data-access/api/eventBus.tsx
+++ b/libs/shared/lib/data-access/api/eventBus.tsx
@@ -43,14 +43,14 @@ import {
   setFetchingSaveStates,
   setStateAuthorization,
 } from '../store/sessionSlice';
-import { URLParams, getParam, deleteParam } from './url';
+import { URLParams, getParam } from './url';
 import { VisState, setVisualizationState } from '../store/visualizationSlice';
 import { isEqual } from 'lodash-es';
 import { setSchemaAttributeDimensions, setSchemaAttributeInformation, setSchemaLoading } from '../store/schemaSlice';
 import { addError } from '@graphpolaris/shared/lib/data-access/store/configSlice';
 import { unSelect } from '../store/interactionSlice';
 import { SchemaGraphStats } from '../../schema';
-import { wsUserGetPolicy, wsUserPolicyCheck } from '../broker/wsUser';
+import { wsUserGetPolicy } from '../broker/wsUser';
 import { authorized } from '../store/authSlice';
 
 export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }) => {
diff --git a/libs/shared/lib/data-access/broker/types.ts b/libs/shared/lib/data-access/broker/types.ts
index dc3dd7c22..8d6decc5a 100644
--- a/libs/shared/lib/data-access/broker/types.ts
+++ b/libs/shared/lib/data-access/broker/types.ts
@@ -19,7 +19,7 @@ type QueryOrchestratorMessage = {
   queryID: string;
 };
 
-export type keyTypeI = 'broadcastState' | 'dbConnection' | 'schema' | 'query' | 'state' | 'user';
+export type keyTypeI = 'broadcastState' | 'dbConnection' | 'schema' | 'query' | 'state' | 'user' | 'insight';
 export type subKeyTypeI =
   // Crud
   | 'create'
diff --git a/libs/shared/lib/data-access/broker/wsInsightSharing.ts b/libs/shared/lib/data-access/broker/wsInsightSharing.ts
new file mode 100644
index 000000000..04c366a3e
--- /dev/null
+++ b/libs/shared/lib/data-access/broker/wsInsightSharing.ts
@@ -0,0 +1,93 @@
+import { Broker } from './broker';
+import { InsightRequest, InsightResponse, InsightType } from '../store/insightSharingSlice';
+
+type GetInsightsResponse = (data: { reports: InsightResponse[]; alerts: InsightResponse[] }, status: string) => void;
+export function wsGetInsights(saveStateId: string, callback?: GetInsightsResponse) {
+  const internalCallback: GetInsightsResponse = (data, status) => {
+    if (callback) callback(data, status);
+  };
+
+  Broker.instance().sendMessage(
+    {
+      key: 'insight',
+      subKey: 'getAll',
+      body: JSON.stringify({ saveStateId: saveStateId })
+    },
+    internalCallback
+  );
+}
+
+export function wsCreateInsight(insight: InsightRequest, callback?: Function) {
+  Broker.instance().sendMessage(
+    {
+      key: 'insight',
+      subKey: 'create',
+      body: JSON.stringify(insight),
+    },
+    (data: any, status: string) => {
+      if (status === 'Bad Request') {
+        console.error('Failed to create insight:', data);
+        if (callback) callback(data, status);
+        return;
+      }
+
+      if (!data || typeof data !== 'object') {
+        console.error('Invalid repsonse data', data)
+        if (callback) callback(null, 'error');
+        return;
+      }
+
+      if (!data.type || !data.id) {
+        console.error('Missing fields in response', data)
+        if (callback) callback(null, 'error');
+        return;
+      }
+
+      if (callback) callback(data, status);
+    }
+  );
+}
+
+export function wsUpdateInsight(
+  id: string,
+  insight: InsightRequest,
+  callback?: (data: any, status: string) => void
+) {
+  Broker.instance().sendMessage(
+    {
+      key: 'insight',
+      subKey: 'update',
+      body: JSON.stringify({ id: id, insight: insight }),
+    },
+    (data: any, status: string) => {
+      if (status === 'Bad Request') {
+        console.error('Failed to update insight:', data);
+      }
+      if (callback) callback(data, status);
+    }
+  );
+}
+
+export function wsDeleteInsight(id: string, callback?: Function) {
+
+  Broker.instance().sendMessage(
+    {
+      key: 'insight',
+      subKey: 'delete',
+      body: JSON.stringify({ id }),
+    },
+    (data: any, status: string) => {
+      if (status === 'Bad Request') {
+        console.error('Failed to delete insight:', data);
+      }
+      if (callback) callback(data, status);
+    }
+  );
+}
+
+export function wsInsightSubscription(callback: (data: any, status: string) => void) {
+  const id = Broker.instance().subscribe(callback, 'insight_result');
+  return () => {
+    Broker.instance().unSubscribe('insight_result', id);
+  };
+}
diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts
index 7df070ec3..444a28b38 100644
--- a/libs/shared/lib/data-access/store/hooks.ts
+++ b/libs/shared/lib/data-access/store/hooks.ts
@@ -44,6 +44,7 @@ import { PolicyUsersState, selectPolicyState } from './authorizationUsersSlice';
 import { PolicyResourcesState, selectResourcesPolicyState } from './authorizationResourcesSlice';
 import { SaveStateAuthorizationHeaders, SaveStateI } from '..';
 import { GraphStatistics } from '../../statistics';
+import { InsightResponse, selectInsights } from './insightSharingSlice';
 
 // Use throughout your app instead of plain `useDispatch` and `useSelector`
 export const useAppDispatch: () => AppDispatch = useDispatch;
@@ -100,3 +101,6 @@ export const useUsersPolicy: () => PolicyUsersState = () => useAppSelector(selec
 
 // Authorization Resources Slice
 export const useResourcesPolicy: () => PolicyResourcesState = () => useAppSelector(selectResourcesPolicyState);
+
+// Insights - Reports and Alerts
+export const useInsights: () => InsightResponse[] = () => useAppSelector(selectInsights);
\ No newline at end of file
diff --git a/libs/shared/lib/data-access/store/insightSharingSlice.ts b/libs/shared/lib/data-access/store/insightSharingSlice.ts
new file mode 100644
index 000000000..a3a4105e0
--- /dev/null
+++ b/libs/shared/lib/data-access/store/insightSharingSlice.ts
@@ -0,0 +1,74 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import { RootState } from '../store';
+
+export type InsightType = 'report' | 'alert';
+
+export type InsightRequest = {
+  name: string;
+  description: string;
+  recipients: string[];
+  frequency: string;
+  template: string;
+  saveStateId: string;
+  type: 'report' | 'alert';
+}
+
+export type InsightResponse = {
+  id: string;
+  createdAt: string;
+  updatedAt: string;
+} & InsightRequest;
+
+type InsightState = {
+  insights: InsightResponse[];
+}
+
+const initialState: InsightState = {
+  insights: []
+};
+
+const insightSharingSlice = createSlice({
+  name: 'insightSharing',
+  initialState,
+  reducers: {
+    setInsights(state, action: PayloadAction<InsightResponse[]>) {
+      state.insights = action.payload;
+    },
+    addInsight: (state, action: PayloadAction<InsightResponse>) => {
+      if (!action.payload) {
+        console.error('Received null payload in addInsight');
+        return;
+      }
+
+      const type = action.payload.type;
+      if (!type) {
+        console.error('Insight type is missing in payload', action.payload);
+        return;
+      }
+
+      state.insights.push(action.payload);
+    },
+    updateInsight(state, action: PayloadAction<InsightResponse>) {
+      const index = state.insights.findIndex((i) => i.id === action.payload.id);
+      if (index !== -1) {
+        state.insights[index] = { ...action.payload };
+      } else {
+        state.insights.push(action.payload);
+      }
+    },
+    deleteInsight(state, action: PayloadAction<{ id: string; }>) {
+      const index = state.insights.findIndex((i) => i.id === action.payload.id);
+      if (index !== -1) {
+        state.insights.splice(index, 1);
+      }
+    },
+  },
+});
+
+export const { setInsights, addInsight, updateInsight, deleteInsight } = insightSharingSlice.actions;
+
+export const selectReports = (state: RootState): InsightResponse[] => state.insightSharing.insights.filter((i) => i.type === 'report');
+export const selectAlerts = (state: RootState): InsightResponse[] => state.insightSharing.insights.filter((i) => i.type === 'alert');
+export const selectInsights = (state: RootState): InsightResponse[] => state.insightSharing.insights;
+
+export default insightSharingSlice.reducer;
diff --git a/libs/shared/lib/data-access/store/store.ts b/libs/shared/lib/data-access/store/store.ts
index c1aea4606..3b1ea1c4d 100644
--- a/libs/shared/lib/data-access/store/store.ts
+++ b/libs/shared/lib/data-access/store/store.ts
@@ -11,6 +11,7 @@ import visualizationSlice from './visualizationSlice';
 import interactionSlice from './interactionSlice';
 import policyUsersSlice from './authorizationUsersSlice';
 import policyPermissionSlice from './authorizationResourcesSlice';
+import insightSharingSlice from './insightSharingSlice';
 
 export const store = configureStore({
   reducer: {
@@ -26,6 +27,7 @@ export const store = configureStore({
     visualize: visualizationSlice,
     policyUsers: policyUsersSlice,
     policyResources: policyPermissionSlice,
+    insightSharing: insightSharingSlice,
   },
   middleware: (getDefaultMiddleware) =>
     getDefaultMiddleware({
diff --git a/libs/shared/lib/insight-sharing/FormAlert.tsx b/libs/shared/lib/insight-sharing/FormAlert.tsx
new file mode 100644
index 000000000..4f4d2c6af
--- /dev/null
+++ b/libs/shared/lib/insight-sharing/FormAlert.tsx
@@ -0,0 +1,178 @@
+import { useEffect, useState } from 'react';
+import { Accordion, AccordionItem, AccordionHead, AccordionBody } from '../components/accordion';
+import { TextEditor } from '../components/textEditor';
+import {
+  InsightResponse,
+  updateInsight,
+  deleteInsight,
+  addInsight,
+  InsightRequest,
+} from '@graphpolaris/shared/lib/data-access/store/insightSharingSlice';
+import { useAppDispatch, useSessionCache } from '@graphpolaris/shared/lib/data-access';
+import { Button, Input, LoadingSpinner } from '../components';
+import { wsUpdateInsight, wsCreateInsight, wsDeleteInsight } from '@graphpolaris/shared/lib/data-access/broker/wsInsightSharing';
+import { addError, addSuccess } from '@graphpolaris/shared/lib/data-access/store/configSlice';
+import { SerializedEditorState } from 'lexical';
+
+type Props = {
+  insight: InsightResponse;
+  setActive?: (val: string) => void;
+  handleDelete: () => void;
+};
+
+export function FormAlert(props: Props) {
+  const dispatch = useAppDispatch();
+  const session = useSessionCache();
+  const [loading, setLoading] = useState(false);
+  const [name, setName] = useState(props.insight.name);
+  const [description, setDescription] = useState(props.insight.description);
+  const [recipients, setRecipients] = useState<string[]>(props.insight.recipients || []);
+  const [recipientInput, setRecipientInput] = useState<string>('');
+  const [editorState, setEditorState] = useState<SerializedEditorState | null>(null);
+
+  useEffect(() => {
+    let isMounted = true;
+
+    if (isMounted) {
+      setName(props.insight.name);
+      setDescription(props.insight.description);
+      setRecipientInput(props.insight.recipients ? props.insight.recipients.join(', ') : '');
+      setRecipients(props.insight.recipients || []);
+      if (props.insight.template) {
+        try {
+          const parsedTemplate = JSON.parse(props.insight.template);
+          setEditorState(parsedTemplate);
+        } catch (e) {
+          setEditorState(null);
+          console.error('Failed to parse template:', e);
+        }
+      } else {
+        setEditorState(null);
+      }
+    }
+
+    return () => {
+      isMounted = false;
+      setEditorState(null);
+    };
+  }, [props.insight]);
+
+  const handleSave = async (element: SerializedEditorState) => {
+    if (!name || name.trim() === '') {
+      dispatch(addError('Name is required'));
+      return;
+    }
+
+    const alertData: InsightRequest = {
+      name,
+      description,
+      recipients,
+      template: JSON.stringify(element),
+      saveStateId: session.currentSaveState || '',
+      type: 'alert' as const,
+      frequency: '',
+    };
+
+    setLoading(true);
+
+    if (props.insight.id) {
+      wsUpdateInsight(props.insight.id, alertData, (data: any, status: string) => {
+        setLoading(false);
+        if (status === 'success') {
+          dispatch(updateInsight(data));
+          dispatch(addSuccess('Alert updated successfully'));
+          console.log('Alert updated successfully');
+        } else {
+          console.error('Failed to update alert:', data);
+          dispatch(addError('Failed to update alert.'));
+        }
+      });
+    } else {
+      wsCreateInsight(alertData, (data: any, status: string) => {
+        setLoading(false);
+        if (status === 'success') {
+          dispatch(addInsight(data));
+          dispatch(addSuccess('Alert created successfully'));
+          console.log('Alert created successfully');
+          if (props.setActive) props.setActive(data.id);
+        } else {
+          console.error('Failed to create alert:', data);
+          dispatch(addError('Failed to create alert.'));
+        }
+      });
+    }
+  };
+
+  const handleDelete = async () => {
+    if (!props.insight.id) {
+      dispatch(addError('Cannot delete an alert without an ID.'));
+      return;
+    }
+
+    setLoading(true);
+    wsDeleteInsight(props.insight.id, (data: any, status: string) => {
+      setLoading(false);
+      if (status === 'success') {
+        dispatch(deleteInsight({ id: props.insight.id }));
+        if (props.setActive) props.setActive('');
+        dispatch(addSuccess('Alert deleted successfully'));
+        console.log('Alert deleted successfully');
+      } else {
+        console.error('Failed to delete alert:', data);
+        dispatch(addError('Failed to delete alert'));
+      }
+    });
+  };
+
+  if (loading) {
+    return <LoadingSpinner />;
+  }
+
+  return (
+    <div>
+      <span className="text-lg text-secondary-600 font-bold mb-4">Alert ID: {props.insight.id}</span>
+      <Input label="Name" type="text" value={name} onChange={setName} className="mb-4" />
+      <Input label="Description" type="text" value={description} onChange={setDescription} className="mb-4" />
+      <Accordion defaultOpenAll={true} className="border-t divide-y">
+        <AccordionItem className="pt-2 pb-4">
+          <AccordionHead showArrow={false}>
+            <span className="font-semibold">Recipient(s)</span>
+          </AccordionHead>
+          <AccordionBody>
+            <div>
+              <Input
+                type="text"
+                value={recipientInput}
+                onChange={(value) => {
+                  setRecipientInput(String(value));
+                  const recipientList = String(value)
+                    .split(/[, ]/)
+                    .map((r) => r.trim())
+                    .filter((r) => r.length > 0);
+                  setRecipients(recipientList);
+                }}
+                placeholder="Enter recipient(s)"
+                className="w-full"
+              />
+            </div>
+          </AccordionBody>
+        </AccordionItem>
+        <AccordionItem className="pt-2 pb-4">
+          <AccordionHead showArrow={false}>
+            <span className="font-semibold">Alerting text</span>
+          </AccordionHead>
+          <AccordionBody>
+          <TextEditor
+                key={`editor-${props.insight.id}`}
+                editorState={editorState}
+                setEditorState={setEditorState}
+                showToolbar={true}
+                placeholder="Start typing your alert template..."
+                handleSave={handleSave}
+              ><Button label="Delete" variantType="secondary" variant="outline" onClick={handleDelete} /></TextEditor>
+          </AccordionBody>
+        </AccordionItem>
+      </Accordion>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/insight-sharing/FormReport.tsx b/libs/shared/lib/insight-sharing/FormReport.tsx
new file mode 100644
index 000000000..e41546b2f
--- /dev/null
+++ b/libs/shared/lib/insight-sharing/FormReport.tsx
@@ -0,0 +1,203 @@
+import { useState, useEffect } from 'react';
+import { Button, Input, LoadingSpinner } from '../components';
+import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '../components/accordion';
+import { TextEditor } from '../components/textEditor';
+import {
+  InsightResponse,
+  updateInsight,
+  deleteInsight,
+  InsightRequest,
+} from '@graphpolaris/shared/lib/data-access/store/insightSharingSlice';
+import { useAppDispatch, useSessionCache } from '@graphpolaris/shared/lib/data-access';
+import { SerializedEditorState } from 'lexical';
+import { wsCreateInsight, wsDeleteInsight, wsUpdateInsight } from '@graphpolaris/shared/lib/data-access/broker/wsInsightSharing';
+import { addError, addSuccess } from '@graphpolaris/shared/lib/data-access/store/configSlice';
+
+type Props = {
+  insight: InsightResponse;
+  setActive: (val: string) => void;
+  handleDelete: () => void;
+};
+
+export function FormReport(props: Props) {
+  const dispatch = useAppDispatch();
+  const session = useSessionCache();
+  const [loading, setLoading] = useState(false);
+  const [name, setName] = useState(props.insight.name);
+  const [description, setDescription] = useState(props.insight.description);
+  const [recipients, setRecipients] = useState(props.insight.recipients || []);
+  const [recipientInput, setRecipientInput] = useState<string>('');
+  const [frequency, setFrequency] = useState(props.insight.frequency || 'Daily');
+  const [editorState, setEditorState] = useState<SerializedEditorState| null>(null);
+
+  useEffect(() => {
+    let isMounted = true;
+    
+    if (isMounted) {
+      setName(props.insight.name);
+      setDescription(props.insight.description);
+      setRecipientInput(props.insight.recipients ? props.insight.recipients.join(', ') : '');
+      setRecipients(props.insight.recipients || []);
+      if (props.insight.template) {
+        try {
+          const parsedTemplate = JSON.parse(props.insight.template);
+          setEditorState(parsedTemplate);
+        } catch (e) {
+          setEditorState(null);
+          console.error('Failed to parse template:', e);
+        }
+      } else {
+        setEditorState(null);
+      }
+    }
+  
+    return () => {
+      isMounted = false;
+      setEditorState(null);
+    };
+  }, [props.insight]);
+
+  const handleSetFrequency = (value: string | number) => {
+    setFrequency(value as string);
+  };
+
+  const handleSetName = (value: string | number) => {
+    setName(value as string);
+  };
+
+  const handleSetDescription = (value: string | number) => {
+    setDescription(value as string);
+  };
+
+  const handleSave = async (elements: SerializedEditorState) => {
+    if (!name || name.trim() === '') {
+      dispatch(addError('Please enter a name for the report.'));
+      return;
+    }
+
+    const reportData: InsightRequest = {
+      name,
+      description,
+      recipients,
+      frequency,
+      template: JSON.stringify(elements),
+      saveStateId: session.currentSaveState || '',
+      type: 'report' as const,
+    };
+
+    setLoading(true);
+    if (props.insight.id) {
+      wsUpdateInsight(props.insight.id, reportData, (data: any, status: string) => {
+        setLoading(false);
+        if (status === 'success') {
+          dispatch(updateInsight(data));
+          dispatch(addSuccess('Report updated successfully'));
+          console.log('Report updated successfully');
+        } else {
+          console.error('Failed to update report:', data);
+          dispatch(addError('Failed to update alert'));
+        }
+      });
+    } else {
+      wsCreateInsight(reportData, (data: any, status: string) => {
+        debugger;
+        setLoading(false);
+        if (status === 'success') {
+          dispatch(updateInsight(data));
+          dispatch(addSuccess('Report created successfully'));
+          console.log('Report created successfully');
+          if (props.setActive) props.setActive(data.id);
+        } else {
+          console.error('Failed to create report:', data);
+          dispatch(addError('Failed to create alert'));
+        }
+      });
+    }
+  };
+
+  const handleDelete = async () => {
+    if (!props.insight.id) {
+      dispatch(addError('Cannot delete a report without an ID.'));
+      return;
+    }
+
+    setLoading(true);
+    wsDeleteInsight(props.insight.id, (data: any, status: string) => {
+      setLoading(false);
+      if (status === 'success') {
+        dispatch(deleteInsight({ id: props.insight.id }));
+        props.setActive('');
+        dispatch(addSuccess('Report deleted successfully'));
+        console.log('Report deleted successfully');
+      } else {
+        console.error('Failed to delete report:', data);
+        dispatch(addError('Failed to delete report'));
+      }
+    });
+  };
+
+  return loading ? (
+    <LoadingSpinner />
+  ) : (
+    <div>
+      <span className="text-lg text-secondary-600 font-bold mb-4">Report ID: {props.insight.id}</span>
+      <Input label="Name" type="text" value={name} onChange={handleSetName} className="mb-4" />
+      <Input label="Description" type="text" value={description} onChange={handleSetDescription} className="mb-4" />
+      <Accordion defaultOpenAll={true} className="border-t divide-y">
+        <AccordionItem className="pt-2 pb-4">
+          <AccordionHead showArrow={false}>
+            <span className="font-semibold">Recipient(s)</span>
+          </AccordionHead>
+          <AccordionBody>
+            <div>
+              <Input
+                type="text"
+                value={recipientInput}
+                onChange={(value) => {
+                  setRecipientInput(String(value));
+                  const recipientList = String(value)
+                    .split(/[, ]/)
+                    .map((r) => r.trim())
+                    .filter((r) => r.length > 0);
+                  setRecipients(recipientList);
+                }}
+                placeholder="Enter recipient(s)"
+                className="w-full"
+              />
+            </div>
+          </AccordionBody>
+        </AccordionItem>
+        <AccordionItem className="pt-2 pb-4">
+          <AccordionHead showArrow={false}>
+            <span className="font-semibold">Repeat</span>
+          </AccordionHead>
+          <AccordionBody>
+            <Input
+              label="Frequency"
+              type="dropdown"
+              value={frequency}
+              onChange={handleSetFrequency}
+              options={['Daily', 'Weekly']}
+              className="mb-1"
+            />
+          </AccordionBody>
+        </AccordionItem>
+        <AccordionItem className="pt-2 pb-4">
+          <AccordionHead showArrow={false}>
+            <span className="font-semibold">Email Template</span>
+          </AccordionHead>
+          <AccordionBody>
+              <TextEditor
+                key={`editor-${props.insight.id}`}
+                editorState={editorState}
+                setEditorState={setEditorState}
+                showToolbar={true}
+                placeholder="Start typing your alert template..."
+                handleSave={handleSave}
+              ><Button label="Delete" variantType="secondary" variant="outline" onClick={handleDelete} /></TextEditor>
+          </AccordionBody>
+        </AccordionItem>
+      </Accordion>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/insight-sharing/InsightDialog.tsx b/libs/shared/lib/insight-sharing/InsightDialog.tsx
index 0af6191f2..44f1d2fe1 100644
--- a/libs/shared/lib/insight-sharing/InsightDialog.tsx
+++ b/libs/shared/lib/insight-sharing/InsightDialog.tsx
@@ -1,24 +1,34 @@
-import React, { useState } from 'react';
+import React, { useMemo, useState } from 'react';
 import { Dialog, DialogContent } from '../components';
-import { SettingsPanel } from './SettingsPanel';
 import { MonitorType, Sidebar } from './components/Sidebar';
+import { AddItem } from './components/AddItem';
+import { useAppDispatch, useInsights } from '..';
+import { StartScreen } from './components/StartScreen';
+import { FormReport } from './FormReport';
+import { FormAlert } from './FormAlert';
+import { wsDeleteInsight } from '../data-access/broker/wsInsightSharing';
+import { deleteInsight } from '../data-access/store/insightSharingSlice';
 
 type Props = {
   open: boolean;
   onClose: () => void;
 };
 
-const reports = ['Sequence 1', 'Sequence 2'];
-const alerts = ['Potential New Incident', 'Potential New Info'];
-
 export function InsightDialog(props: Props) {
-  const [adding, setAdding] = useState<boolean>(false);
+  const dispatch = useAppDispatch();
+
+  const [adding, setAdding] = useState<false | MonitorType>(false);
   const [active, setActive] = useState<string>('');
-  const [activeCategory, setActiveCategory] = useState<MonitorType | undefined>(undefined);
+  const insights = useInsights();
+
+  const selectedInsight = useMemo(() => insights.find((i) => i.id === active), [active, insights]);
 
-  const handleChangeActive = (category: MonitorType, name: string) => {
-    setActive(name);
-    setActiveCategory(category);
+  const handleDelete = () => {
+    if (!selectedInsight) return;
+
+    dispatch(deleteInsight({ id: selectedInsight.id }));
+    wsDeleteInsight(selectedInsight.id);
+    setActive('');
   };
 
   return (
@@ -30,20 +40,21 @@ export function InsightDialog(props: Props) {
     >
       <DialogContent className="w-5/6 h-5/6 rounded-none py-0 px-0">
         <div className="flex w-full h-full">
-          <Sidebar
-            reports={reports}
-            alerts={alerts}
-            changeActive={handleChangeActive}
-            setAdding={setAdding}
-            setActiveCategory={setActiveCategory}
-          />
-          <SettingsPanel
-            activeCategory={activeCategory}
-            active={active}
-            adding={adding}
-            setAdding={setAdding}
-            setActiveCategory={setActiveCategory}
-          />
+          <div className="w-1/4 border-r overflow-auto flex flex-col h-full">
+            <Sidebar setAdding={setAdding} setActive={setActive} />
+          </div>
+
+          <div className="w-3/4 p-8">
+            {adding ? (
+              <AddItem setAdding={setAdding} setActive={setActive} type={adding} />
+            ) : !selectedInsight ? (
+              <StartScreen setAdding={setAdding} />
+            ) : selectedInsight.type === 'report' ? (
+              <FormReport insight={selectedInsight} setActive={setActive} handleDelete={handleDelete} />
+            ) : (
+              <FormAlert insight={selectedInsight} setActive={setActive} handleDelete={handleDelete} />
+            )}
+          </div>
         </div>
       </DialogContent>
     </Dialog>
diff --git a/libs/shared/lib/insight-sharing/SettingsPanel.tsx b/libs/shared/lib/insight-sharing/SettingsPanel.tsx
deleted file mode 100644
index 9d0a7a676..000000000
--- a/libs/shared/lib/insight-sharing/SettingsPanel.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { ReportingForm } from './reporting/ReportingForm';
-import { AlertingForm } from './alerting/AlertingForm';
-import { Button, Icon } from '../components';
-import { AddItem } from './components/AddItem';
-import { StartScreen } from './components/StartScreen';
-import { MonitorType } from './components/Sidebar';
-
-type Props = {
-  active: string;
-  activeCategory: MonitorType | undefined;
-  adding: boolean;
-  setAdding: (val: boolean) => void;
-  setActiveCategory: (val: MonitorType | undefined) => void;
-};
-
-export function SettingsPanel(props: Props) {
-  const [contacts, setContacts] = useState<string[]>([]);
-
-  const getContacts = (): string[] => ['Jan', 'Piet'];
-
-  useEffect(() => {
-    if (!contacts) {
-      const userContacts = getContacts();
-      setContacts(userContacts);
-    }
-  }, []);
-
-  return props.activeCategory ? (
-    <div className="w-3/4 p-4">
-      {props.adding ? (
-        <AddItem category={props.activeCategory} />
-      ) : (
-        props.active &&
-        props.activeCategory && (
-          <div>
-            {props.activeCategory === 'report' ? (
-              <ReportingForm activeTemplate={props.active} />
-            ) : (
-              <AlertingForm activeTemplate={props.active} />
-            )}
-          </div>
-        )
-      )}
-      <div className="flex justify-end mt-2">
-        <Button label="Delete" variantType="secondary" variant="outline" />
-        <Button label="Save" variantType="primary" className="ml-2" />
-      </div>
-    </div>
-  ) : (
-    <StartScreen setAdding={props.setAdding} setActiveCategory={props.setActiveCategory} />
-  );
-}
diff --git a/libs/shared/lib/insight-sharing/alerting/AlertingForm.tsx b/libs/shared/lib/insight-sharing/alerting/AlertingForm.tsx
deleted file mode 100644
index 11ea8d907..000000000
--- a/libs/shared/lib/insight-sharing/alerting/AlertingForm.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React, { useState } from 'react';
-import { Accordion, AccordionItem, AccordionHead, AccordionBody } from '../../components/accordion';
-import { TextEditor } from '../../components/textEditor';
-import { EditorState } from 'lexical';
-
-type Props = {
-  activeTemplate: string;
-};
-
-export function AlertingForm(props: Props) {
-  const [editorState, setEditorState] = useState<EditorState | undefined>(undefined);
-
-  return (
-    <div>
-      <span className="text-lg text-secondary-600 font-bold mb-4">Alert ID: {props.activeTemplate}</span>
-      <Accordion defaultOpenAll={true} className="border-t divide-y">
-        <AccordionItem className="pt-2 pb-4">
-          <AccordionHead showArrow={false}>
-            <span className="font-semibold">Recipient(s)</span>
-          </AccordionHead>
-          <AccordionBody>
-            <div>
-              <input className="border" />
-            </div>
-          </AccordionBody>
-        </AccordionItem>
-        <AccordionItem className="pt-2 pb-4">
-          <AccordionHead showArrow={false}>
-            <span className="font-semibold">Alerting text</span>
-          </AccordionHead>
-          <AccordionBody>
-            <TextEditor
-              editorState={editorState}
-              setEditorState={setEditorState}
-              showToolbar={true}
-              placeholder="Start typing your alert template..."
-            />
-          </AccordionBody>
-        </AccordionItem>
-      </Accordion>
-    </div>
-  );
-}
diff --git a/libs/shared/lib/insight-sharing/components/AddItem.tsx b/libs/shared/lib/insight-sharing/components/AddItem.tsx
index 771ab6bcc..b207b9ec6 100644
--- a/libs/shared/lib/insight-sharing/components/AddItem.tsx
+++ b/libs/shared/lib/insight-sharing/components/AddItem.tsx
@@ -1,18 +1,58 @@
 import React, { useState } from 'react';
-import { Input } from '../../components';
-import { MonitorType } from './Sidebar';
+import { Input, Button } from '../../components';
+import { MonitorType as InsightType, MonitorType } from './Sidebar';
+import { useAppDispatch, useSessionCache } from '../../data-access';
+import { addInsight } from '../../data-access/store/insightSharingSlice';
+import { wsCreateInsight } from '../../data-access/broker/wsInsightSharing';
+import { addError, addSuccess,  } from '@graphpolaris/shared/lib/data-access/store/configSlice';
 
 type Props = {
-  category: MonitorType;
+  setAdding: (val: false | MonitorType) => void;
+  setActive: (val: string) => void;
+  type: InsightType;
 };
 
 export function AddItem(props: Props) {
-  const [value, setValue] = useState<string>('');
+  const [name, setName] = useState<string>('');
+  const [description, setDescription] = useState<string>('');
+  const dispatch = useAppDispatch();
+  const session = useSessionCache();
+
+  const handleSave = async () => {
+    if (!name.trim()) {
+      dispatch(addError('Name is required'));
+      return;
+    }
+
+    const newInsight = {
+      name,
+      description,
+      recipients: [],
+      template: '',
+      frequency: props.type === 'report' ? 'Daily' : '',
+      saveStateId: session.currentSaveState || '',
+      type: props.type,
+    };
+
+    wsCreateInsight(newInsight, (data: any, status: string) => {
+      if (status === 'success') {
+        dispatch(addInsight(data));
+        props.setActive(data.id);
+        props.setAdding(false);
+        dispatch(addSuccess('Succesfully created ' + props.type));
+      } else {
+        console.error('Failed to create insight:', data);
+        dispatch(addError('Failed to create new ' + props.type))
+      }
+    });
+  };
 
   return (
     <div>
-      <span className="text-lg text-secondary-600 font-bold mb-4">Add a new {props.category}ing service</span>
-      <Input type="text" label="Name" value={value} onChange={setValue} />
+      <span className="text-lg text-secondary-600 font-bold mb-4">Add a new {props.type}ing service</span>
+      <Input type="text" label="Name" value={name} onChange={setName} className="mb-2" />
+      <Input type="text" label="Description" value={description} onChange={setDescription} className="mb-2" />
+      <Button label="Save" onClick={handleSave} disabled={!name || !description} className="mt-2" />
     </div>
   );
 }
diff --git a/libs/shared/lib/insight-sharing/components/Sidebar.tsx b/libs/shared/lib/insight-sharing/components/Sidebar.tsx
index d8ebcfe1c..96aefb1f1 100644
--- a/libs/shared/lib/insight-sharing/components/Sidebar.tsx
+++ b/libs/shared/lib/insight-sharing/components/Sidebar.tsx
@@ -1,30 +1,42 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import { Button } from '../../components';
 import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '../../components/accordion';
+import { useAppDispatch, useInsights } from '../../data-access';
+import { setInsights } from '../../data-access/store/insightSharingSlice';
+import { useSessionCache } from '../../data-access';
+import { wsGetInsights } from '../../data-access/broker/wsInsightSharing';
 
 export type MonitorType = 'report' | 'alert';
 
 type SidebarProps = {
-  reports: string[];
-  alerts: string[];
-  changeActive: (category: MonitorType, val: string) => void;
-  setAdding: (val: boolean) => void;
-  setActiveCategory: (val: MonitorType | undefined) => void;
+  setAdding: (val: false | MonitorType) => void;
+  setActive: (val: string) => void;
 };
 
 export function Sidebar(props: SidebarProps) {
+  const dispatch = useAppDispatch();
+  const session = useSessionCache();
+  const insights = useInsights();
+
+  useEffect(() => {
+    if (session.currentSaveState && session.currentSaveState !== '') {
+      wsGetInsights(session.currentSaveState, (data: any, status: string) => {
+        dispatch(setInsights(data));
+      });
+    }
+  }, [session.currentSaveState]);
+
   return (
-    <div className="w-1/4 border-r overflow-auto flex flex-col h-full">
+    <>
       <span className="text-lg text-secondary-700 font-semibold px-2 py-4">Insight Sharing</span>
-      <Accordion defaultOpenIndex={0}>
+      <Accordion defaultOpenAll={true}>
         <AccordionItem className="">
           <AccordionHead className="border-b bg-secondary-50 hover:bg-secondary-100 p-1">
             <div className="w-full flex justify-between">
               <span className="font-semibold">Reports</span>
               <div
                 onClick={(e) => {
-                  props.setAdding(true);
-                  props.setActiveCategory('report');
+                  props.setAdding('report');
                   e.stopPropagation();
                 }}
               >
@@ -41,18 +53,20 @@ export function Sidebar(props: SidebarProps) {
           </AccordionHead>
           <AccordionBody className="ml-0">
             <ul className="space-y-2">
-              {props.reports.map((name, index) => (
-                <li
-                  key={index}
-                  className="cursor-pointer p-2 hover:bg-secondary-50"
-                  onClick={() => {
-                    props.changeActive('report', name);
-                    props.setAdding(false);
-                  }}
-                >
-                  {name}
-                </li>
-              ))}
+              {insights
+                .filter((insight) => insight.type === 'report')
+                .map((report) => (
+                  <li
+                    key={report.id}
+                    className="cursor-pointer p-2 hover:bg-secondary-50"
+                    onClick={() => {
+                      props.setAdding(false);
+                      props.setActive(report.id);
+                    }}
+                  >
+                    {report.name}
+                  </li>
+                ))}
             </ul>
           </AccordionBody>
         </AccordionItem>
@@ -62,8 +76,7 @@ export function Sidebar(props: SidebarProps) {
               <span className="font-semibold">Alerts</span>
               <div
                 onClick={(e) => {
-                  props.setAdding(true);
-                  props.setActiveCategory('alert');
+                  props.setAdding('alert');
                   e.stopPropagation();
                 }}
               >
@@ -80,22 +93,24 @@ export function Sidebar(props: SidebarProps) {
           </AccordionHead>
           <AccordionBody className="ml-0">
             <ul className="space-y-2">
-              {props.alerts.map((name, index) => (
-                <li
-                  key={index}
-                  className="cursor-pointer p-2 hover:bg-secondary-50"
-                  onClick={() => {
-                    props.changeActive('alert', name);
-                    props.setAdding(false);
-                  }}
-                >
-                  {name}
-                </li>
-              ))}
+              {insights
+                .filter((insight) => insight.type === 'alert')
+                .map((alert) => (
+                  <li
+                    key={alert.id}
+                    className="cursor-pointer p-2 hover:bg-secondary-50"
+                    onClick={() => {
+                      props.setAdding(false);
+                      props.setActive(alert.id);
+                    }}
+                  >
+                    {alert.name}
+                  </li>
+                ))}
             </ul>
           </AccordionBody>
         </AccordionItem>
       </Accordion>
-    </div>
+    </>
   );
 }
diff --git a/libs/shared/lib/insight-sharing/components/StartScreen.tsx b/libs/shared/lib/insight-sharing/components/StartScreen.tsx
index 801331c40..377ad49d9 100644
--- a/libs/shared/lib/insight-sharing/components/StartScreen.tsx
+++ b/libs/shared/lib/insight-sharing/components/StartScreen.tsx
@@ -3,13 +3,12 @@ import { Button, Icon } from '../../components';
 import { MonitorType } from './Sidebar';
 
 type Props = {
-  setAdding: (val: boolean) => void;
-  setActiveCategory: (val: MonitorType | undefined) => void;
+  setAdding: (val: false | MonitorType) => void;
 };
 
 export function StartScreen(props: Props) {
   return (
-    <div className="w-full flex justify-center items-center">
+    <div className="w-full h-full flex justify-center items-center">
       <div className="">
         <span className="text-lg text-secondary-700 font-bold mb-4">Start</span>
         <div>
@@ -19,8 +18,7 @@ export function StartScreen(props: Props) {
             variant="outline"
             className="mb-2"
             onClick={() => {
-              props.setAdding(true);
-              props.setActiveCategory('report');
+              props.setAdding('report');
             }}
           />
           <Button
@@ -28,8 +26,7 @@ export function StartScreen(props: Props) {
             label="New alert"
             variant="outline"
             onClick={() => {
-              props.setAdding(true);
-              props.setActiveCategory('alert');
+              props.setAdding('alert');
             }}
           />
         </div>
diff --git a/libs/shared/lib/insight-sharing/reporting/ReportingForm.tsx b/libs/shared/lib/insight-sharing/reporting/ReportingForm.tsx
deleted file mode 100644
index 9b2645b91..000000000
--- a/libs/shared/lib/insight-sharing/reporting/ReportingForm.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import React, { useState } from 'react';
-import { Input, LoadingSpinner } from '../../components';
-import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '../../components/accordion';
-import { TextEditor } from '../../components/textEditor';
-import { EditorState } from 'lexical';
-
-type Props = {
-  activeTemplate: string;
-};
-
-export function ReportingForm(props: Props) {
-  const [loading, setLoading] = useState(false);
-  const [editorState, setEditorState] = useState<EditorState | undefined>(undefined);
-
-  return loading ? (
-    <LoadingSpinner />
-  ) : (
-    props.activeTemplate && (
-      <div>
-        <span className="text-lg text-secondary-600 font-bold mb-4">Report ID: {props.activeTemplate}</span>
-        <Accordion defaultOpenAll={true} className="border-t divide-y">
-          <AccordionItem className="pt-2 pb-4">
-            <AccordionHead showArrow={false}>
-              <span className="font-semibold">Recipient(s)</span>
-            </AccordionHead>
-            <AccordionBody>
-              <div>
-                <input className="border" />
-              </div>
-            </AccordionBody>
-          </AccordionItem>
-          <AccordionItem className="pt-2 pb-4">
-            <AccordionHead showArrow={false}>
-              <span className="font-semibold">Repeat</span>
-            </AccordionHead>
-            <AccordionBody>
-              <Input label="Frequency" type="dropdown" value={'Daily'} onChange={() => {}} options={['Daily', 'Weekly']} className="mb-1" />
-            </AccordionBody>
-          </AccordionItem>
-          <AccordionItem className="pt-2 pb-4">
-            <AccordionHead showArrow={false}>
-              <span className="font-semibold">Email template</span>
-            </AccordionHead>
-            <AccordionBody>
-              <TextEditor
-                editorState={editorState}
-                setEditorState={setEditorState}
-                showToolbar={true}
-                placeholder="Start typing your report template..."
-              />
-            </AccordionBody>
-          </AccordionItem>
-        </Accordion>
-      </div>
-    )
-  );
-}
-- 
GitLab