diff --git a/src/components/common/PaymentConfirmationModal/PaymentConfirmationModal.tsx b/src/components/common/PaymentConfirmationModal/PaymentConfirmationModal.tsx
new file mode 100644
index 00000000..3dfbc07d
--- /dev/null
+++ b/src/components/common/PaymentConfirmationModal/PaymentConfirmationModal.tsx
@@ -0,0 +1,59 @@
+import React, { PropsWithChildren } from 'react';
+import { Stack } from '@mui/system';
+import { BaseModal } from '../BaseModal'; // Assuming you have a BaseModal component
+import IconButton from '../IconButton2'; // Assuming you have an IconButton2 component
+import { useCreateModal } from '../useCreateModal'; // Assuming you have a custom hook useCreateModal
+
+export type PaymentConfirmationModalProps = PropsWithChildren<{
+ onClose: () => void;
+ onConfirmPayment: () => void;
+ onCancel?: () => void;
+}>;
+
+export const PaymentConfirmationModal = ({
+ onClose,
+ children,
+ onCancel,
+ onConfirmPayment
+}: PaymentConfirmationModalProps) => {
+ const closeHandler = () => {
+ onClose();
+ onCancel?.();
+ };
+
+ const confirmPaymentHandler = () => {
+ onConfirmPayment();
+ onClose();
+ };
+
+ return (
+
+
+ {children}
+
+
+
+
+
+
+ );
+};
+
+export const usePaymentConfirmationModal = () => {
+ const openModal = useCreateModal();
+
+ const openPaymentConfirmation = (props: Omit) => {
+ openModal({
+ Component: PaymentConfirmationModal,
+ props
+ });
+ };
+
+ return { openPaymentConfirmation };
+};
diff --git a/src/components/common/PaymentConfirmationModal/__tests__/PaymentConfirmationModal.spec.tsx b/src/components/common/PaymentConfirmationModal/__tests__/PaymentConfirmationModal.spec.tsx
new file mode 100644
index 00000000..0b15ae57
--- /dev/null
+++ b/src/components/common/PaymentConfirmationModal/__tests__/PaymentConfirmationModal.spec.tsx
@@ -0,0 +1,46 @@
+import '@testing-library/jest-dom';
+import { fireEvent, render, waitFor } from '@testing-library/react';
+import React from 'react';
+import { PaymentConfirmationModal } from '../PaymentConfirmationModal';
+
+describe('PaymentConfirmationModal', () => {
+ it('renders correctly', () => {
+ const onCloseMock = jest.fn();
+ const onConfirmPaymentMock = jest.fn();
+ const { getByText } = render(
+
+ Are you sure you want to pay this bounty?
+
+ );
+
+ expect(getByText('Are you sure you want to pay this bounty?')).toBeInTheDocument();
+ });
+
+ it('calls onClose when Cancel button is clicked', async () => {
+ const onCloseMock = jest.fn();
+ const onConfirmPaymentMock = jest.fn();
+ const { getByText } = render(
+
+ Are you sure you want to pay this bounty?
+
+ );
+
+ fireEvent.click(getByText('Cancel'));
+ await waitFor(() => expect(onCloseMock).toHaveBeenCalledTimes(1));
+ expect(onConfirmPaymentMock).not.toHaveBeenCalled();
+ });
+
+ it('calls onConfirmPayment and onClose when Confirm button is clicked', async () => {
+ const onCloseMock = jest.fn();
+ const onConfirmPaymentMock = jest.fn();
+ const { getByText } = render(
+
+ Are you sure you want to pay this bounty?
+
+ );
+
+ fireEvent.click(getByText('Confirm'));
+ await waitFor(() => expect(onCloseMock).toHaveBeenCalledTimes(1));
+ expect(onConfirmPaymentMock).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/src/components/common/PaymentConfirmationModal/index.ts b/src/components/common/PaymentConfirmationModal/index.ts
new file mode 100644
index 00000000..1ad32cab
--- /dev/null
+++ b/src/components/common/PaymentConfirmationModal/index.ts
@@ -0,0 +1 @@
+export * from './PaymentConfirmationModal';
diff --git a/src/components/common/index.tsx b/src/components/common/index.tsx
index 29fe297c..7f046d03 100644
--- a/src/components/common/index.tsx
+++ b/src/components/common/index.tsx
@@ -22,6 +22,7 @@ export * from './BaseModal';
export * from './DeleteConfirmationModal';
export * from './AfterDeleteNotification';
export * from './ButtonContainer';
+export * from './PaymentConfirmationModal';
export {
SearchableSelect,
diff --git a/src/components/form/inputs/TextAreaInput.tsx b/src/components/form/inputs/TextAreaInput.tsx
index 0a9239fe..d1867240 100644
--- a/src/components/form/inputs/TextAreaInput.tsx
+++ b/src/components/form/inputs/TextAreaInput.tsx
@@ -92,9 +92,7 @@ export default function TextAreaInput({
const color = colors['light'];
if (error) labeltext = `${labeltext} (${error})`;
const [active, setActive] = useState(false);
- const normalizeAndTrimText = (text: string) => {
- return text.split('\n').join('\n');
- };
+ const normalizeAndTrimText = (text: string) => text.split('\n').join('\n');
const handleTextChange = (e: any) => {
const newText = normalizeAndTrimText(e.target.value.trimStart());
diff --git a/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx b/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx
index 00bf2854..53557195 100644
--- a/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx
+++ b/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx
@@ -5,7 +5,8 @@ import { observer } from 'mobx-react-lite';
import moment from 'moment';
import { isInvoiceExpired, userCanManageBounty } from 'helpers';
import { SOCKET_MSG, createSocketInstance } from 'config/socket';
-import { Button, Divider, Modal } from '../../../../components/common';
+import { Box } from '@mui/system';
+import { Button, Divider, Modal, usePaymentConfirmationModal } from '../../../../components/common';
import { colors } from '../../../../config/colors';
import { renderMarkdown } from '../../../utils/RenderMarkdown';
import { satToUsd } from '../../../../helpers';
@@ -380,6 +381,22 @@ function MobileView(props: CodingBountiesProps) {
const hasAccess = isOwner || userBountyRole;
const payBountyDisable = !isOwner && !userBountyRole;
+ const { openPaymentConfirmation } = usePaymentConfirmationModal();
+
+ const confirmPaymentHandler = () => {
+ openPaymentConfirmation({
+ onConfirmPayment: makePayment,
+ children: (
+
+ Are you sure you want to
+
+ Pay this Bounty?
+
+
+ )
+ });
+ };
+
useEffect(() => {
setPaidStatus(paid);
}, [paid]);
@@ -445,7 +462,7 @@ function MobileView(props: CodingBountiesProps) {
}}
hovercolor={color.button_secondary.hover}
shadowcolor={color.button_secondary.shadow}
- onClick={makePayment}
+ onClick={confirmPaymentHandler}
/>
)
}
@@ -740,7 +757,7 @@ function MobileView(props: CodingBountiesProps) {
iconSize={14}
width={220}
height={48}
- onClick={makePayment}
+ onClick={confirmPaymentHandler}
style={{ marginTop: '30px', marginBottom: '-20px', textAlign: 'left' }}
text="Pay Bounty"
ButtonTextStyle={{ padding: 0 }}