diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContent.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContent.tsx index 53cfe7642..57cc0398c 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContent.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContent.tsx @@ -1,4 +1,4 @@ -import { Group, Stack } from '@/components'; +import { Stack } from '@/components'; import { Classes } from '@blueprintjs/core'; import { InvoiceSendMailBoot } from './InvoiceSendMailContentBoot'; import { InvoiceSendMailForm } from './InvoiceSendMailForm'; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormDialogs.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormDialogs.tsx index 30477aee6..4fe2cb947 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormDialogs.tsx +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormDialogs.tsx @@ -2,8 +2,6 @@ import React from 'react'; import { useFormikContext } from 'formik'; import ReceiptNumberDialog from '@/containers/Dialogs/ReceiptNumberDialog'; -import ReceiptFormMailDeliverDialog from './Dialogs/ReceiptFormMailDeliverDialog'; -import { DialogsName } from '@/constants/dialogs'; /** * Receipt form dialogs. @@ -29,9 +27,6 @@ export default function ReceiptFormDialogs() { dialogName={'receipt-number-form'} onConfirm={handleReceiptNumberFormConfirm} /> - > ); } diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog.tsx deleted file mode 100644 index 69a0e64a9..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog.tsx +++ /dev/null @@ -1,34 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { Dialog, DialogSuspense } from '@/components'; -import withDialogRedux from '@/components/DialogReduxConnect'; -import { compose } from '@/utils'; - -const ReceiptMailDialogBody = React.lazy( - () => import('./ReceiptMailDialogBody'), -); - -/** - * Receipt mail dialog. - */ -function ReceiptMailDialog({ - dialogName, - payload: { receiptId = null }, - isOpen, -}) { - return ( - - - - - - ); -} -export default compose(withDialogRedux())(ReceiptMailDialog); diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBody.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBody.tsx deleted file mode 100644 index fbd379b84..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBody.tsx +++ /dev/null @@ -1,33 +0,0 @@ -// @ts-nocheck -import * as R from 'ramda'; -import withDialogActions from '@/containers/Dialog/withDialogActions'; -import ReceiptMailDialogContent, { - ReceiptMailDialogContentProps, -} from './ReceiptMailDialogContent'; -import { DialogsName } from '@/constants/dialogs'; - -interface ReceiptMailDialogBodyProps extends ReceiptMailDialogContentProps {} - -function ReceiptMailDialogBodyRoot({ - receiptId, - - // #withDialogActions - closeDialog, -}: ReceiptMailDialogBodyProps) { - const handleCancelClick = () => { - closeDialog(DialogsName.ReceiptMail); - }; - const handleSubmitClick = () => { - closeDialog(DialogsName.ReceiptMail); - }; - - return ( - - ); -} - -export default R.compose(withDialogActions)(ReceiptMailDialogBodyRoot); diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBoot.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBoot.tsx deleted file mode 100644 index 54f7200db..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogBoot.tsx +++ /dev/null @@ -1,49 +0,0 @@ -// @ts-nocheck -import React, { createContext } from 'react'; -import { useSaleReceiptDefaultOptions } from '@/hooks/query'; -import { DialogContent } from '@/components'; - -interface ReceiptMailDialogBootValues { - receiptId: number; - mailOptions: any; - redirectToReceiptsList: boolean; -} - -const ReceiptMailDialogBootContext = - createContext(); - -interface ReceiptMailDialogBootProps { - receiptId: number; - children: React.ReactNode; - redirectToReceiptsList?: boolean; -} - -/** - * Receipt mail dialog boot provider. - */ -function ReceiptMailDialogBoot({ - receiptId, - redirectToReceiptsList = false, - ...props -}: ReceiptMailDialogBootProps) { - const { data: mailOptions, isLoading: isMailOptionsLoading } = - useSaleReceiptDefaultOptions(receiptId); - - const provider = { - saleReceiptId: receiptId, - mailOptions, - isMailOptionsLoading, - redirectToReceiptsList, - }; - - return ( - - - - ); -} - -const useReceiptMailDialogBoot = () => - React.useContext(ReceiptMailDialogBootContext); - -export { ReceiptMailDialogBoot, useReceiptMailDialogBoot }; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogContent.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogContent.tsx deleted file mode 100644 index a02966a1c..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogContent.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { ReceiptMailDialogBoot } from './ReceiptMailDialogBoot'; -import { ReceiptMailDialogForm } from './ReceiptMailDialogForm'; - -export interface ReceiptMailDialogContentProps { - receiptId: number; - onFormSubmit?: () => void; - onCancelClick?: () => void; -} -export default function ReceiptMailDialogContent({ - receiptId, - onFormSubmit, - onCancelClick -}: ReceiptMailDialogContentProps) { - return ( - - - - ); -} diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogForm.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogForm.tsx deleted file mode 100644 index db2808f4c..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogForm.tsx +++ /dev/null @@ -1,79 +0,0 @@ -// @ts-nocheck -import { Formik, FormikBag } from 'formik'; -import * as R from 'ramda'; -import { Intent } from '@blueprintjs/core'; -import { useReceiptMailDialogBoot } from './ReceiptMailDialogBoot'; -import withDialogActions from '@/containers/Dialog/withDialogActions'; -import { DialogsName } from '@/constants/dialogs'; -import { useSendSaleReceiptMail } from '@/hooks/query'; -import { ReceiptMailDialogFormContent } from './ReceiptMailDialogFormContent'; -import { - initialMailNotificationValues, - MailNotificationFormValues, - transformMailFormToInitialValues, - transformMailFormToRequest, -} from '@/containers/SendMailNotification/utils'; -import { AppToaster } from '@/components'; - -const initialFormValues = { - ...initialMailNotificationValues, - attachReceipt: true, -}; -interface ReceiptMailFormValues extends MailNotificationFormValues { - attachReceipt: boolean; -} - -interface ReceiptMailDialogFormProps { - onFormSubmit?: () => void; - onCancelClick?: () => void; -} - -export function ReceiptMailDialogForm({ - // #props - onFormSubmit, - onCancelClick, -}: ReceiptMailDialogFormProps) { - const { mailOptions, saleReceiptId } = useReceiptMailDialogBoot(); - const { mutateAsync: sendReceiptMail } = useSendSaleReceiptMail(); - - // Transformes mail options to initial form values. - const initialValues = transformMailFormToInitialValues( - mailOptions, - initialFormValues, - ); - // Handle the form submitting. - const handleSubmit = ( - values: ReceiptMailFormValues, - { setSubmitting }: FormikBag, - ) => { - const reqValues = transformMailFormToRequest(values); - - setSubmitting(true); - sendReceiptMail([saleReceiptId, reqValues]) - .then(() => { - AppToaster.show({ - message: 'The mail notification has been sent successfully.', - intent: Intent.SUCCESS, - }); - setSubmitting(false); - onFormSubmit && onFormSubmit(values); - }) - .catch(() => { - AppToaster.show({ - message: 'Something went wrong.', - intent: Intent.DANGER, - }); - setSubmitting(false); - }); - }; - // Handle the close button click. - const handleClose = () => { - onCancelClick && onCancelClick(); - }; - - return ( - - - - ); -} diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogFormContent.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogFormContent.tsx deleted file mode 100644 index fed55f094..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialogFormContent.tsx +++ /dev/null @@ -1,66 +0,0 @@ -// @ts-nocheck -import { Form, useFormikContext } from 'formik'; -import { Button, Classes, Intent } from '@blueprintjs/core'; -import styled from 'styled-components'; -import { FFormGroup, FSwitch } from '@/components'; -import { MailNotificationForm } from '@/containers/SendMailNotification'; -import { useReceiptMailDialogBoot } from './ReceiptMailDialogBoot'; -import { saveInvoke } from '@/utils'; - -interface SendMailNotificationFormProps { - onClose?: () => void; -} - -export function ReceiptMailDialogFormContent({ - onClose, -}: SendMailNotificationFormProps) { - const { mailOptions } = useReceiptMailDialogBoot(); - const { isSubmitting } = useFormikContext(); - - const handleClose = () => { - saveInvoke(onClose); - }; - - return ( - - - - - - - - - - - - Close - - - - Send - - - - - ); -} - -const AttachFormGroup = styled(FFormGroup)` - background: #f8f9fb; - margin-top: 0.6rem; - padding: 4px 14px; - border-radius: 5px; - border: 1px solid #dcdcdd; -`; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/index.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/index.tsx deleted file mode 100644 index 575fb462b..000000000 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptMailDialog/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './ReceiptMailDialog'; \ No newline at end of file diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailBoot.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailBoot.tsx new file mode 100644 index 000000000..25fef6d71 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailBoot.tsx @@ -0,0 +1,55 @@ +import React, { createContext, useContext } from 'react'; +import { Spinner } from '@blueprintjs/core'; +import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; +import { useSaleReceiptMailState } from '@/hooks/query'; + +interface ReceiptSendMailBootValues { + receiptId: number; + + receiptMailState: any; + isReceiptMailState: boolean; +} +interface ReceiptSendMailBootProps { + children: React.ReactNode; +} + +const ReceiptSendMailContentBootContext = + createContext({} as ReceiptSendMailBootValues); + +export const ReceiptSendMailBoot = ({ + children, +}: ReceiptSendMailBootProps) => { + const { + payload: { receiptId }, + } = useDrawerContext(); + + // Receipt mail options. + const { data: receiptMailState, isLoading: isReceiptMailState } = + useSaleReceiptMailState(receiptId); + + const isLoading = isReceiptMailState; + + if (isLoading) { + return ; + } + const value = { + receiptId, + + // # Receipt mail options + isReceiptMailState, + receiptMailState, + }; + + return ( + + {children} + + ); +}; +ReceiptSendMailBoot.displayName = 'ReceiptSendMailBoot'; + +export const useReceiptSendMailBoot = () => { + return useContext( + ReceiptSendMailContentBootContext, + ); +}; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailContent.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailContent.tsx new file mode 100644 index 000000000..8e8dd7f79 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailContent.tsx @@ -0,0 +1,24 @@ +import { Stack } from '@/components'; +import { Classes } from '@blueprintjs/core'; +import { SendMailViewHeader } from '../../Estimates/SendMailViewDrawer/SendMailViewHeader'; +import { SendMailViewLayout } from '../../Estimates/SendMailViewDrawer/SendMailViewLayout'; +import { ReceiptSendMailBoot } from './ReceiptSendMailBoot'; +import { ReceiptSendMailForm } from './ReceiptSendMailForm'; +import { ReceiptSendMailFormFields } from './ReceiptSendMailFormFields'; +import { ReceiptSendMailPreviewTabs } from './ReceiptSendMailPreviewTabs'; + +export function InvoiceSendMailContent() { + return ( + + + + } + fields={} + preview={} + /> + + + + ); +} diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailDrawer.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailDrawer.tsx new file mode 100644 index 000000000..f8e7255d1 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailDrawer.tsx @@ -0,0 +1,42 @@ +// @ts-nocheck +import React from 'react'; +import * as R from 'ramda'; +import { Drawer, DrawerSuspense } from '@/components'; +import withDrawers from '@/containers/Drawer/withDrawers'; + +const ReceiptSendMailContent = React.lazy(() => + import('./ReceiptSendMailContent').then((module) => ({ + default: module.ReceiptSendMailContent, + })), +); + +interface ReceiptSendMailDrawerProps { + name: string; + isOpen?: boolean; + payload?: any; +} + +function ReceiptSendMailDrawerRoot({ + name, + + // #withDrawer + isOpen, + payload, +}: ReceiptSendMailDrawerProps) { + return ( + + + + + + ); +} + +export const ReceiptSendMailDrawer = R.compose(withDrawers())( + ReceiptSendMailDrawerRoot, +); diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.schema.ts b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.schema.ts new file mode 100644 index 000000000..75b656186 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.schema.ts @@ -0,0 +1,11 @@ +import * as Yup from 'yup'; + +export const ReceiptSendMailFormSchema = Yup.object().shape({ + subject: Yup.string().required('Subject is required'), + message: Yup.string().required('Message is required'), + to: Yup.array() + .of(Yup.string().email('Invalid email address')) + .required('To address is required'), + cc: Yup.array().of(Yup.string().email('Invalid email address')), + bcc: Yup.array().of(Yup.string().email('Invalid email address')), +}); diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.tsx new file mode 100644 index 000000000..999a9c69b --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailForm.tsx @@ -0,0 +1,78 @@ +import { Form, Formik, FormikHelpers } from 'formik'; +import { css } from '@emotion/css'; +import { Intent } from '@blueprintjs/core'; +import { ReceiptSendMailFormValues } from './_types'; +import { ReceiptSendMailFormSchema } from './ReceiptSendMailForm.schema'; +import { useSendSaleReceiptMail } from '@/hooks/query'; +import { AppToaster } from '@/components'; +import { useReceiptSendMailBoot } from './ReceiptSendMailBoot'; +import { useDrawerActions } from '@/hooks/state'; +import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; +import { transformToForm } from '@/utils'; + +const initialValues: ReceiptSendMailFormValues = { + subject: '', + message: '', + to: [], + cc: [], + bcc: [], + attachPdf: true, +}; + +interface ReceiptSendMailFormProps { + children: React.ReactNode; +} + +export function ReceiptSendMailForm({ children }: ReceiptSendMailFormProps) { + const { mutateAsync: sendReceiptMail } = useSendSaleReceiptMail(); + const { receiptId, receiptMailState } = useReceiptSendMailBoot(); + + const { name } = useDrawerContext(); + const { closeDrawer } = useDrawerActions(); + + const _initialValues: ReceiptSendMailFormValues = { + ...initialValues, + ...transformToForm(receiptMailState, initialValues), + }; + const handleSubmit = ( + values: ReceiptSendMailFormValues, + { setSubmitting }: FormikHelpers, + ) => { + setSubmitting(true); + sendReceiptMail({ id: receiptId, values: { ...values } }) + .then(() => { + AppToaster.show({ + message: 'The receipt mail has been sent to the customer.', + intent: Intent.SUCCESS, + }); + setSubmitting(false); + closeDrawer(name); + }) + .catch((error) => { + setSubmitting(false); + AppToaster.show({ + message: 'Something went wrong!', + intent: Intent.SUCCESS, + }); + }); + }; + + return ( + + + {children} + + + ); +} diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailFormFields.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailFormFields.tsx new file mode 100644 index 000000000..b28ae160c --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailFormFields.tsx @@ -0,0 +1,6 @@ + + + +export function ReceiptSendMailFormFields() { + return null; +} \ No newline at end of file diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailPreviewTabs.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailPreviewTabs.tsx new file mode 100644 index 000000000..e4f0f8c2e --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/ReceiptSendMailPreviewTabs.tsx @@ -0,0 +1,6 @@ + + +export function ReceiptSendMailPreviewTabs() { + + return null; +} \ No newline at end of file diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/_types.ts b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/_types.ts new file mode 100644 index 000000000..839328a34 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/_types.ts @@ -0,0 +1 @@ +export interface ReceiptSendMailFormValues {} diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/index.ts b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/index.ts new file mode 100644 index 000000000..d5b3d2cae --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptSendMailDrawer/index.ts @@ -0,0 +1 @@ +export * from './ReceiptSendMailDrawer';