From c5c85bdfbe27462fd2f309c7c5df7d81a2b11c53 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Thu, 21 Nov 2024 11:29:52 +0200 Subject: [PATCH] feat: wip estimate send mail --- .../EstimateSendMailBoot.tsx | 4 +- .../EstimateSendMailPdfPreview.tsx | 0 .../EstimateSendMailPreviewHeader.tsx | 20 +++++-- .../EstimateSnedMailFields.tsx | 13 +++-- .../EstimateSendMailDrawer/_interfaces.ts | 6 +- .../Estimates/EstimateSendMailDrawer/hooks.ts | 55 ++++++++++++++++++ .../Estimates/SendMailViewDrawer/_types.ts | 9 ++- .../Estimates/SendMailViewDrawer/hooks.ts | 56 +++++++++++++++++++ packages/webapp/src/hooks/query/estimates.tsx | 39 +++++++++++-- 9 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPdfPreview.tsx create mode 100644 packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/hooks.ts create mode 100644 packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/hooks.ts diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailBoot.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailBoot.tsx index 79355668c..41473192b 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailBoot.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailBoot.tsx @@ -1,12 +1,12 @@ import React, { createContext, useContext } from 'react'; import { Spinner } from '@blueprintjs/core'; import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; -import { useSaleEstimateMailState } from '@/hooks/query'; +import { SaleEstimateMailStateResponse, useSaleEstimateMailState } from '@/hooks/query'; interface EstimateSendMailBootValues { estimateId: number; - estimateMailState: any; + estimateMailState: SaleEstimateMailStateResponse | undefined; isEstimateMailState: boolean; } interface EstimateSendMailBootProps { diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPdfPreview.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPdfPreview.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreviewHeader.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreviewHeader.tsx index 182094bcd..65584e54e 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreviewHeader.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreviewHeader.tsx @@ -1,13 +1,23 @@ +import { useFormikContext } from 'formik'; import { SendViewPreviewHeader } from '../SendMailViewDrawer/SendMailViewPreviewHeader'; +import { useEstimateSendMailBoot } from './EstimateSendMailBoot'; +import { useSendEstimateMailSubject } from './hooks'; +import { EstimateSendMailFormValues } from './_interfaces'; export function EstimateSendMailPreviewHeader() { + const subject = useSendEstimateMailSubject(); + const { estimateMailState } = useEstimateSendMailBoot(); + const { + values: { to, from }, + } = useFormikContext(); + return ( ); } diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSnedMailFields.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSnedMailFields.tsx index 9922574f5..6cd0672b8 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSnedMailFields.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSnedMailFields.tsx @@ -1,17 +1,20 @@ import { useFormikContext } from 'formik'; +import { Button, Intent } from '@blueprintjs/core'; import { FCheckbox, FFormGroup, FInputGroup, Group, Stack } from '@/components'; import { SendMailViewToAddressField } from '../SendMailViewDrawer/SendMailViewToAddressField'; import { SendMailViewMessageField } from '../SendMailViewDrawer/SendMailViewMessageField'; -import { Button, Intent } from '@blueprintjs/core'; import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; import { useDrawerActions } from '@/hooks/state'; +import { useSendEstimateFormatArgsOptions } from './hooks'; +import { useSendMailItems } from '../SendMailViewDrawer/hooks'; -const items: Array = []; -const argsOptions: Array = []; export function EstimateSendMailFields() { + const argOptions = useSendEstimateFormatArgsOptions(); + const items = useSendMailItems(); + return ( - + - + diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/_interfaces.ts b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/_interfaces.ts index b302170db..f8ba75639 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/_interfaces.ts +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/_interfaces.ts @@ -1 +1,5 @@ -export interface EstimateSendMailFormValues {} +import { SendMailViewFormValues } from '../SendMailViewDrawer/_types'; + +export interface EstimateSendMailFormValues extends SendMailViewFormValues { + attachPdf?: boolean; +} diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/hooks.ts b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/hooks.ts new file mode 100644 index 000000000..27d927ccc --- /dev/null +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/hooks.ts @@ -0,0 +1,55 @@ +import { useMemo } from 'react'; +import { useFormikContext } from 'formik'; +import { SelectOptionProps } from '@blueprintjs-formik/select'; +import { useEstimateSendMailBoot } from './EstimateSendMailBoot'; +import { + formatMailMessage, + transformEmailArgs, + transformFormatArgsToOptions, +} from '../SendMailViewDrawer/hooks'; +import { EstimateSendMailFormValues } from './_interfaces'; + +/** + * Retrieves the mail format arguments of estimate mail. + * @returns {Record} + */ +export const useSendEstimateMailFormatArgs = (): Record => { + const { estimateMailState } = useEstimateSendMailBoot(); + + return useMemo(() => { + return transformEmailArgs(estimateMailState?.formatArgs || {}); + }, [estimateMailState]); +}; + +/** + * Retrieves the formatted estimate subject. + * @returns {string} + */ +export const useSendEstimateMailSubject = (): string => { + const { values } = useFormikContext(); + const formatArgs = useSendEstimateMailFormatArgs(); + + return formatMailMessage(values?.subject, formatArgs); +}; + +/** + * Retrieves the estimate format options. + * @returns {Array} + */ +export const useSendEstimateFormatArgsOptions = + (): Array => { + const formatArgs = useSendEstimateMailFormatArgs(); + + return transformFormatArgsToOptions(formatArgs); + }; + +/** + * Retrieves the formatted estimate message. + * @returns {string} + */ +export const useSendEstimateMailMessage = (): string => { + const { values } = useFormikContext(); + const formatArgs = useSendEstimateMailFormatArgs(); + + return formatMailMessage(values?.message, formatArgs); +}; diff --git a/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/_types.ts b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/_types.ts index fadeb3575..043f606f6 100644 --- a/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/_types.ts +++ b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/_types.ts @@ -1 +1,8 @@ -export interface SendMailViewFormValues {} +export interface SendMailViewFormValues { + from: Array; + to: Array; + cc: Array; + bcc: Array; + subject: string; + message: string; +} diff --git a/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/hooks.ts b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/hooks.ts new file mode 100644 index 000000000..a3e01e6ef --- /dev/null +++ b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/hooks.ts @@ -0,0 +1,56 @@ +import { useFormikContext } from 'formik'; +import { chain, defaultTo, mapKeys, snakeCase, startCase } from 'lodash'; +import { SendMailViewFormValues } from './_types'; + +export const useSendInvoiceMailForm = () => { + return useFormikContext(); +}; + +/** + * Retrieves the suggest items of to, cc and bcc fields. + * @returns {Array<{ value: string, text: string }>} + */ +export const useSendMailItems = (): Array<{ value: string; text: string }> => { + const { values } = useSendInvoiceMailForm(); + const cc = values?.cc || []; + const bcc = values?.bcc || []; + + return chain([...values?.to, ...cc, ...bcc]) + .filter((email) => !!email?.trim()) + .uniq() + .map((email) => ({ + value: email, + text: email, + })) + .value(); +}; + +export const transformEmailArgs = (formatArgs: Record) => { + return mapKeys(formatArgs, (_, key) => + startCase(snakeCase(key).replace('_', ' ')), + ); +}; + +export const transformFormatArgsToOptions = ( + formatArgs: Record, +) => { + return Object.keys(formatArgs).map((key) => ({ + value: key, + text: key, + })); +}; + +export const formatMailMessage = ( + message: string, + args: Record, +) => { + let formattedMessage = message; + + Object.keys(args).forEach((key) => { + const variable = `{${key}}`; + const value = defaultTo(args[key], ''); + + formattedMessage = formattedMessage.replace(variable, value); + }); + return formattedMessage; +}; diff --git a/packages/webapp/src/hooks/query/estimates.tsx b/packages/webapp/src/hooks/query/estimates.tsx index abbabc8fa..82255c4b3 100644 --- a/packages/webapp/src/hooks/query/estimates.tsx +++ b/packages/webapp/src/hooks/query/estimates.tsx @@ -1,5 +1,11 @@ // @ts-nocheck -import { useQueryClient, useMutation, useQuery } from 'react-query'; +import { + useQueryClient, + useMutation, + useQuery, + UseQueryOptions, + UseQueryResult, +} from 'react-query'; import { useRequestQuery } from '../useQueryRequest'; import useApiRequest from '../useRequest'; import { transformPagination, transformToCamelCase } from '@/utils'; @@ -257,13 +263,36 @@ export function useSendSaleEstimateMail(props = {}) { ); } +export interface SaleEstimateMailStateResponse { + attachEstimate: boolean; + companyLogoUri: string; + companyName: string; + customerName: string; + entries: Array; + estimateDate: string; + formatArgs: { + customerName: string; + estimateAmount: string; + }; + formattedEstimateDate: string; + from: Array; + fromOptions: Array; + message: string; + subject: string; + to: Array; + toOptions: Array; +} + /** - * + * Retrieves the sale estimate mail state. * @param {number} estimateId - * @param props - * @returns + * @param {UseQueryOptions} props + * @returns {UseQueryResult} */ -export function useSaleEstimateMailState(estimateId: number, props?= {}) { +export function useSaleEstimateMailState( + estimateId: number, + props?: UseQueryOptions, +): UseQueryResult { const apiRequest = useApiRequest(); return useQuery([t.SALE_ESTIMATE_MAIL_OPTIONS, estimateId], () => apiRequest