+ {integrationDetails?.appSpecificIntegrationMetaData?.severity3Alerts?.active ? (
+ <>
+
+
+
+ Severity 3 alerts ACTIVE
+
+
+
+
+ {severity3AlertRecipients?.emailContacts.map((e, i) => {
+ return (
+
+ {e}
+
+ );
+ })}
+
+
+ >
+ ) : (
+ <>
+
+
+
+ Severity 3 alerts INACTIVE
+
+
+ >
+ )}
+
+
+
+ {integrationDetails?.appSpecificIntegrationMetaData?.megaPhoneAlerts?.active ? (
+ <>
+
+
+
+ Megaphone alerts ACTIVE
+
+
+
+
+ {megaphoneAlertRecipients?.emailContacts.map((e, i) => {
+ return (
+
+ {e}
+
+ );
+ })}
+ {megaphoneAlertRecipients?.teamsChannel.map((t, i) => {
+ return teamsChannels.map((tc) => {
+ if (tc.id === t) {
+ return (
+
+ {tc.name}
+
+ );
+ }
+ return null;
+ });
+ })}
+
+
+ >
+ ) : (
+ <>
+
+
+
+ Megaphone alerts INACTIVE
+
+
+ >
+ )}
+
+ >
+ );
+}
+
+export default GeneralTab;
diff --git a/client-reactjs/src/components/admin/Integrations/asr/ProductModal.jsx b/client-reactjs/src/components/admin/Integrations/asr/ProductModal.jsx
new file mode 100644
index 000000000..2f1ff4633
--- /dev/null
+++ b/client-reactjs/src/components/admin/Integrations/asr/ProductModal.jsx
@@ -0,0 +1,161 @@
+// Package imports
+import React, { useEffect } from 'react';
+import { Modal, Form, Input, Select, message } from 'antd';
+import { useSelector } from 'react-redux';
+
+// Local imports
+import { createNewProduct, getProducts, updateProduct } from './asr-integration-util';
+
+// Product tiers
+const tiers = [
+ { label: 'No Tier', value: 0 },
+ { label: 'Tier 1', value: 1 },
+ { label: 'Tier 2', value: 2 },
+ { label: 'Tier 3', value: 3 },
+];
+
+const ProductModal = ({
+ productModalOpen,
+ setProductModalOpen,
+ domains,
+ selectedProduct,
+ setSelectedProduct,
+ setProducts,
+}) => {
+ const [form] = Form.useForm();
+
+ // Redux
+ const {
+ authenticationReducer: { user },
+ } = useSelector((state) => state);
+
+ //Effects
+ useEffect(() => {
+ if (selectedProduct) {
+ let associatedDomains = [];
+ if (selectedProduct.domains) {
+ // Remove null domains
+ associatedDomains = selectedProduct.domains.filter((d) => d.id !== null).map((d) => d.id);
+ }
+ form.setFieldsValue({
+ name: selectedProduct.name,
+ shortCode: selectedProduct.shortCode,
+ tier: selectedProduct.tier,
+ domainIds: associatedDomains,
+ });
+ }
+ }, [selectedProduct]);
+
+ // When Ok (Save/update) modal on from is clicked
+ const handleOk = async () => {
+ // Validate form
+ try {
+ await form.validateFields();
+ } catch (error) {
+ console.error('Failed to validate form', error);
+ }
+
+ // Create new product
+ try {
+ const formValues = form.getFieldsValue();
+ if (!selectedProduct) {
+ await saveNewProduct(formValues);
+ } else {
+ await updateExistingProduct(formValues);
+ }
+
+ const products = await getProducts();
+ setProducts(products);
+ form.resetFields();
+ setSelectedProduct(null);
+ setProductModalOpen(false);
+ } catch (err) {
+ message.error('Failed to create product', err.message);
+ }
+ };
+
+ // Create new product
+ const saveNewProduct = async (values) => {
+ try {
+ const payload = {
+ ...values,
+ createdBy: { lastName: user.lastName, firstName: user.firstName, email: user.email },
+ };
+ await createNewProduct({ payload });
+ message.success('Product created successfully');
+ } catch (error) {
+ throw new Error('Failed to create product');
+ }
+ };
+
+ // Const update product
+ const updateExistingProduct = async (values) => {
+ try {
+ const payload = {
+ ...values,
+ updatedBy: { lastName: user.lastName, firstName: user.firstName, email: user.email },
+ };
+ await updateProduct({ id: selectedProduct.id, payload });
+ message.success('Product updated successfully');
+ } catch (error) {
+ throw new Error('Failed to update product');
+ }
+ };
+
+ // When cancel is clicked
+ const handleCancel = () => {
+ form.resetFields();
+ setSelectedProduct(null);
+ setProductModalOpen(false);
+ };
+
+ // JSX
+ return (
+