diff --git a/src/shared/components/Forms/FormTabs/DeleteFormModal/DeleteFormModal.tsx b/src/shared/components/Forms/FormTabs/DeleteFormModal/DeleteFormModal.tsx
new file mode 100644
index 0000000..47bd25e
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteFormModal/DeleteFormModal.tsx
@@ -0,0 +1,50 @@
+import React, { memo } from 'react';
+import { areEqual } from 'Utils/equalityChecks';
+import { Modal } from 'Components/Modal';
+import { Button } from 'Components/Button';
+
+import classes from './deleteFormModal.module.css';
+
+interface Props {
+ id: number;
+ isOpen: boolean;
+ modalCloseClick: (e: any) => void;
+ onDelete: (id: number) => void;
+}
+
+const DeleteFormModal = ({ id, isOpen, modalCloseClick, onDelete }: Props) => (
+
+
{
+ e.preventDefault();
+ onDelete(id);
+ }}
+ >
+ Delete
+
+ }
+ modalFooter
+ closeButtonText="Cancel"
+ dataBsBackdrop="static"
+ dataBsKeyboard="false"
+ modalCloseClick={modalCloseClick}
+ >
+
+
Are you sure you want to delete this form?
+
+
+
+);
+
+const DeleteFormModalMemo = memo(DeleteFormModal, areEqual);
+
+export { DeleteFormModalMemo as DeleteFormModal };
diff --git a/src/shared/components/Forms/FormTabs/DeleteFormModal/deleteFormModal.module.css b/src/shared/components/Forms/FormTabs/DeleteFormModal/deleteFormModal.module.css
new file mode 100644
index 0000000..94d73a4
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteFormModal/deleteFormModal.module.css
@@ -0,0 +1,86 @@
+.modalContent {
+ padding: 1.3em 1.5em;
+ box-shadow: 0px 24px 44px rgba(119, 113, 133, 0.2);
+ border-radius: 5px;
+}
+.modalDialog {
+ max-width: 648px;
+}
+.modalHeader {
+ padding: 0 0 0.5em 0;
+ border-color: #e8e7ed;
+ height: 40px;
+}
+
+.modalTitle {
+ font-family: IBM Plex Sans;
+ font-style: normal;
+ font-weight: 600;
+ font-size: 18px;
+ text-transform: capitalize;
+ line-height: 24px;
+ color: #5b476b;
+ text-align: center;
+ flex: 1;
+}
+.modalBody {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ padding: 1.3rem 0 1.1rem 0;
+}
+.modalBody {
+ font-family: IBM Plex Sans;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 16px;
+ line-height: 24px;
+ color: #000000;
+}
+.deleteModalHeader {
+ width: 100%;
+ max-width: 343px;
+ border-bottom: 1px solid #d2cfda;
+}
+.deleteModalCopy {
+ width: 350px;
+ text-transform: capitalize;
+ font-weight: 500;
+}
+
+.modalFooter {
+ padding: 1rem 0 0 0;
+ border: none;
+ flex-direction: row-reverse;
+ justify-content: center;
+}
+.modalFooter button {
+ font-family: IBM Plex Sans;
+ font-style: normal;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 24px;
+ color: #5b476b;
+ background-color: #ffffff;
+ border: 1px solid #5b476b;
+ border-radius: 5px;
+ width: 151px;
+ height: 44px;
+}
+
+.modalFooter .closeButtonClass:hover,
+.modalFooter .closeButtonClass:focus {
+ background-color: #f3f3f6;
+ border-color: #d2cfda;
+ color: #777185;
+}
+.modalFooter .delete {
+ border-color: #e82828 !important;
+ color: #e82828 !important;
+}
+.modalFooter .delete:hover,
+.modalFooter .delete:focus {
+ background-color: #e82828 !important;
+ color: #ffffff !important;
+}
diff --git a/src/shared/components/Forms/FormTabs/DeleteFormModal/index.ts b/src/shared/components/Forms/FormTabs/DeleteFormModal/index.ts
new file mode 100644
index 0000000..d5bccb5
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteFormModal/index.ts
@@ -0,0 +1 @@
+export { DeleteFormModal } from './DeleteFormModal';
diff --git a/src/shared/components/Forms/FormTabs/DeleteToast/DeleteToast.tsx b/src/shared/components/Forms/FormTabs/DeleteToast/DeleteToast.tsx
new file mode 100644
index 0000000..e507b9c
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteToast/DeleteToast.tsx
@@ -0,0 +1,46 @@
+import React, { memo } from 'react';
+
+import { areEqual } from 'Utils/equalityChecks';
+import { CheckedMarkSvg } from 'Components/Icons/CheckedMark';
+import { Button } from 'Components/Button';
+
+import classes from './deleteToast.module.css';
+
+export interface Props {
+ isDisplayed: boolean;
+ message: string;
+ closeToast: (e: any) => void;
+}
+
+const DeleteToast = ({ isDisplayed = false, message, closeToast }: Props) => (
+
+
+ {message}
+
+
+
+
+
+
+
+
+);
+
+DeleteToast.defaultProps = {};
+
+const DeleteToastMemo = memo(DeleteToast, areEqual);
+
+export { DeleteToastMemo as DeleteToast };
diff --git a/src/shared/components/Forms/FormTabs/DeleteToast/deleteToast.module.css b/src/shared/components/Forms/FormTabs/DeleteToast/deleteToast.module.css
new file mode 100644
index 0000000..e724271
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteToast/deleteToast.module.css
@@ -0,0 +1,77 @@
+.toastBase {
+ height: 40px !important;
+ width: calc(100% - (315px + 1.5rem)) !important;
+ z-index: 1000;
+ box-shadow: none;
+ border-radius: 0;
+ padding-left: 0.5rem !important;
+ padding-right: 0.5rem !important;
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ transition: opacity 0.15s linear;
+ left: calc(290px + 0.75rem);
+ text-align: center;
+}
+.toast-body-override {
+ width: 95%;
+ padding: unset ip !important;
+}
+.toastCloseButtonContainer {
+ display: flex;
+ justify-content: flex-end;
+ width: 10%;
+}
+.toastCloseButton {
+ border-radius: 50% !important;
+ color: #5b476b !important;
+ background-color: #fff !important;
+ padding: 0.25rem !important;
+ opacity: unset !important;
+ /* This is the actual svg pulled from bootstrap. not the 0.5em beside center on the 2nd line. This is what has changed */
+ background: transparent
+ url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e")
+ center/0.5em auto no-repeat;
+}
+.toastIcon {
+ padding-left: 10px;
+}
+.toastCloseButton:hover {
+ color: #000;
+ text-decoration: none;
+ opacity: unset !important;
+}
+.toastText {
+ font-family: IBM Plex Sans !important;
+ font-style: normal !important;
+ font-weight: 600 !important;
+ font-size: 16px !important;
+ line-height: 24px !important;
+ color: #5b476b !important;
+}
+
+.toastSuccess {
+ background-color: #dcf5f0;
+ border-bottom: 1px solid #40c9ae !important;
+}
+
+.toastWarning {
+ background-color: #fff0f0;
+ border-bottom: 1px solid #e82828;
+}
+
+.toastCloseIcon {
+ position: absolute;
+ right: 22px;
+}
+
+@media (max-width: 768px) {
+ .toastBase {
+ width: 100%;
+ /* height: auto; */
+ padding: 12px 66px 12px 22px;
+ }
+
+ .toastText {
+ font-size: 14px;
+ }
+}
diff --git a/src/shared/components/Forms/FormTabs/DeleteToast/index.ts b/src/shared/components/Forms/FormTabs/DeleteToast/index.ts
new file mode 100644
index 0000000..fd0faf6
--- /dev/null
+++ b/src/shared/components/Forms/FormTabs/DeleteToast/index.ts
@@ -0,0 +1 @@
+export { DeleteToast } from './DeleteToast';
diff --git a/src/shared/components/Forms/FormTabs/index.ts b/src/shared/components/Forms/FormTabs/index.ts
index 6b5814f..1f42edd 100644
--- a/src/shared/components/Forms/FormTabs/index.ts
+++ b/src/shared/components/Forms/FormTabs/index.ts
@@ -1,2 +1,4 @@
export { ContractForms } from './ContractForms';
export { FormsList } from './FormsList';
+export { DeleteFormModal } from './DeleteFormModal';
+export { DeleteToast } from './DeleteToast';
diff --git a/src/shared/containers/Forms/FormTabs/ContractForms/ContractForms.tsx b/src/shared/containers/Forms/FormTabs/ContractForms/ContractForms.tsx
index 4599f65..2be84a0 100644
--- a/src/shared/containers/Forms/FormTabs/ContractForms/ContractForms.tsx
+++ b/src/shared/containers/Forms/FormTabs/ContractForms/ContractForms.tsx
@@ -1,15 +1,29 @@
-import React, { memo, useEffect, useCallback } from 'react';
+import React, { memo, useEffect, useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { areEqual } from 'Utils/equalityChecks';
-import { contractFormsSelector, fetchingContractFormsSelector, companyIdSelector } from 'Containers/Forms/selectors';
+import {
+ contractFormsSelector,
+ fetchingContractFormsSelector,
+ companyIdSelector,
+ deletingContractFormSelector,
+ contractFormDeletedSelector,
+} from 'Containers/Forms/selectors';
import { ContractForms } from 'Components/Forms';
-import { listCompanyContractForms } from 'Containers/Forms/actions';
+import { DeleteFormModal, DeleteToast } from 'Components/Forms/FormTabs';
+import { listCompanyContractForms, deleteContractForm, setDeletedFormId } from '../../actions';
const ContractFormsContainer = () => {
const dispatch = useDispatch();
const contractForms = useSelector(contractFormsSelector, areEqual);
const fetching = useSelector(fetchingContractFormsSelector, areEqual);
const companyId = useSelector(companyIdSelector, areEqual);
+ const deleting = useSelector(deletingContractFormSelector, areEqual);
+ const deletedId = useSelector(contractFormDeletedSelector, areEqual);
+ const [deleteModal, setDeleteModal] = useState({
+ isOpen: false,
+ id: null,
+ });
+ const [showDeletedToast, setShowDeletedToast] = useState(false);
const getContractForms = useCallback(() => {
if (companyId) {
@@ -17,18 +31,70 @@ const ContractFormsContainer = () => {
}
}, [dispatch, companyId]);
+ const deleteButtonClick = useCallback((id: number) => {
+ setDeleteModal({
+ isOpen: true,
+ id,
+ });
+ }, []);
+
+ const handleDelete = useCallback(
+ (id: number) => {
+ dispatch(deleteContractForm(id));
+ setDeleteModal({
+ isOpen: false,
+ id: null,
+ });
+ },
+ [dispatch]
+ );
+
+ const closeToast = useCallback((e: any) => {
+ e.preventDefault();
+ setShowDeletedToast(false);
+ }, []);
+
+ useEffect(() => {
+ if (deletedId) {
+ dispatch(listCompanyContractForms(companyId));
+
+ setShowDeletedToast(true);
+
+ setTimeout(() => setShowDeletedToast(false), 1500);
+
+ dispatch(setDeletedFormId(null));
+ }
+ }, [deletedId]);
+
useEffect(() => {
getContractForms();
}, [getContractForms]);
return (
-
+ <>
+ {}}
+ onDelete={deleteButtonClick}
+ onClickRow={() => {}}
+ // deleting={deleting}
+ // deletedId={deletedId}
+ />
+
+
+ setDeleteModal({
+ isOpen: false,
+ id: null,
+ })
+ }
+ onDelete={handleDelete}
+ />
+ {deletedId && }
+ >
);
};
diff --git a/src/shared/containers/Forms/actions.ts b/src/shared/containers/Forms/actions.ts
index 6710554..a70ec5d 100644
--- a/src/shared/containers/Forms/actions.ts
+++ b/src/shared/containers/Forms/actions.ts
@@ -4,10 +4,14 @@ import { FormTemplateResponse } from 'Containers/Forms/Models';
export const CONTRACT_FORMS = 'CONTRACT_FORMS';
export const FETCHING_CONTRACT_FORMS = 'FETCHING_CONTRACT_FORMS';
+export const DELETING_CONTRACT_FORM = 'DELETING_CONTRACT_FORM';
+export const CONTRACT_FORM_DELETED = 'CONTRACT_FORM_DELETED';
interface FormsActionTypes {
CONTRACT_FORMS: FormTemplateResponse;
FETCHING_CONTRACT_FORMS: boolean;
+ DELETING_CONTRACT_FORM: boolean;
+ CONTRACT_FORM_DELETED: number;
}
interface MessageAction {
@@ -31,3 +35,19 @@ export const listCompanyContractForms = (companyId: number) => async (dispatch:
payload: response,
});
};
+
+// Thunk to delete a contract form by id
+export const deleteContractForm = (contractFormId: number) => async (dispatch: any) => {
+ dispatch({ type: DELETING_CONTRACT_FORM, payload: true });
+ try {
+ await handleApiRequest(dispatch, Api.delete(`/contract-forms/${contractFormId}`), '', DELETING_CONTRACT_FORM);
+ dispatch({ type: CONTRACT_FORM_DELETED, payload: contractFormId });
+ } catch (error) {
+ // handle error if needed
+ dispatch({ type: DELETING_CONTRACT_FORM, payload: false });
+ }
+};
+
+export const setDeletedFormId = (value: number | null) => async (dispatch: any) => {
+ dispatch({ type: CONTRACT_FORM_DELETED, payload: value });
+};
diff --git a/src/shared/containers/Forms/reducer.ts b/src/shared/containers/Forms/reducer.ts
index 6165e3b..bd19395 100644
--- a/src/shared/containers/Forms/reducer.ts
+++ b/src/shared/containers/Forms/reducer.ts
@@ -1,8 +1,16 @@
-import { CONTRACT_FORMS, FETCHING_CONTRACT_FORMS, SetFormsActionTypes } from './actions';
+import {
+ CONTRACT_FORMS,
+ FETCHING_CONTRACT_FORMS,
+ SetFormsActionTypes,
+ DELETING_CONTRACT_FORM,
+ CONTRACT_FORM_DELETED,
+} from './actions';
const initialState = {
data: [],
fetchingContractForms: false,
+ deletingContractForm: false,
+ contractFormDeleted: null,
};
export const formsReducer = (state = initialState, action: SetFormsActionTypes) => {
@@ -19,6 +27,18 @@ export const formsReducer = (state = initialState, action: SetFormsActionTypes)
fetchingContractForms: action.payload,
};
}
+ case DELETING_CONTRACT_FORM: {
+ return {
+ ...state,
+ deletingContractForm: action.payload,
+ };
+ }
+ case CONTRACT_FORM_DELETED: {
+ return {
+ ...state,
+ contractFormDeleted: action.payload,
+ };
+ }
default:
return state;
}
diff --git a/src/shared/containers/Forms/selectors.ts b/src/shared/containers/Forms/selectors.ts
index 5dbe34a..7df602a 100644
--- a/src/shared/containers/Forms/selectors.ts
+++ b/src/shared/containers/Forms/selectors.ts
@@ -2,3 +2,5 @@
export const contractFormsSelector = ({ forms }: any) => forms?.data || [];
export const fetchingContractFormsSelector = ({ forms }: any) => forms?.fetchingContractForms || false;
export { firstCompanyIdSelector as companyIdSelector } from '../Projects/selectors';
+export const deletingContractFormSelector = ({ forms }: any) => forms?.deletingContractForm || false;
+export const contractFormDeletedSelector = ({ forms }: any) => forms?.contractFormDeleted || null;