Merge branch 'feature/notify-via-SMS' of https://github.com/bigcapitalhq/client into feature/notify-via-SMS

This commit is contained in:
elforjani13
2021-11-09 16:24:31 +02:00
7 changed files with 57 additions and 26 deletions

View File

@@ -6,11 +6,11 @@ import NotifyInvoiceViaSMSForm from './NotifyInvoiceViaSMSForm';
export default function NotifyInvoiceViaSMSDialogContent({ export default function NotifyInvoiceViaSMSDialogContent({
// #ownProps // #ownProps
dialogName, dialogName,
invoice, invoiceId,
}) { }) {
return ( return (
<NotifyInvoiceViaSMSFormProvider <NotifyInvoiceViaSMSFormProvider
invoiceId={invoice} invoiceId={invoiceId}
dialogName={dialogName} dialogName={dialogName}
> >
<NotifyInvoiceViaSMSForm /> <NotifyInvoiceViaSMSForm />

View File

@@ -33,6 +33,8 @@ function NotifyInvoiceViaSMSForm({
setNotificationType, setNotificationType,
} = useNotifyInvoiceViaSMSContext(); } = useNotifyInvoiceViaSMSContext();
const [calloutCode, setCalloutCode] = React.useState([]);
// Handles the form submit. // Handles the form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
setSubmitting(true); setSubmitting(true);
@@ -46,7 +48,6 @@ function NotifyInvoiceViaSMSForm({
setSubmitting(false); setSubmitting(false);
closeDialog(dialogName); closeDialog(dialogName);
}; };
// Handle request response errors. // Handle request response errors.
const onError = ({ const onError = ({
response: { response: {
@@ -54,13 +55,14 @@ function NotifyInvoiceViaSMSForm({
}, },
}) => { }) => {
if (errors) { if (errors) {
transformErrors(errors, { setErrors }); transformErrors(errors, { setErrors, setCalloutCode });
} }
setSubmitting(false); setSubmitting(false);
}; };
// Transformes the form values to request. // Transformes the form values to request.
const requestValues = transformFormValuesToRequest(values); const requestValues = transformFormValuesToRequest(values);
// Submits invoice SMS notification.
createNotifyInvoiceBySMSMutate([invoiceId, requestValues]) createNotifyInvoiceBySMSMutate([invoiceId, requestValues])
.then(onSuccess) .then(onSuccess)
.catch(onError); .catch(onError);
@@ -74,7 +76,7 @@ function NotifyInvoiceViaSMSForm({
notification_key: notificationType, notification_key: notificationType,
...invoiceSMSDetail, ...invoiceSMSDetail,
}; };
// Handle form values change.
const handleValuesChange = (values) => { const handleValuesChange = (values) => {
if (values.notification_key !== notificationType) { if (values.notification_key !== notificationType) {
setNotificationType(values.notification_key); setNotificationType(values.notification_key);
@@ -88,7 +90,6 @@ function NotifyInvoiceViaSMSForm({
], ],
[], [],
); );
return ( return (
<NotifyViaSMSForm <NotifyViaSMSForm
initialValues={initialValues} initialValues={initialValues}
@@ -96,6 +97,7 @@ function NotifyInvoiceViaSMSForm({
onSubmit={handleFormSubmit} onSubmit={handleFormSubmit}
onCancel={handleFormCancel} onCancel={handleFormCancel}
onValuesChange={handleValuesChange} onValuesChange={handleValuesChange}
calloutCodes={calloutCode}
/> />
); );
} }

View File

@@ -4,6 +4,9 @@ import { useCreateNotifyInvoiceBySMS, useInvoiceSMSDetail } from 'hooks/query';
const NotifyInvoiceViaSMSContext = React.createContext(); const NotifyInvoiceViaSMSContext = React.createContext();
/**
* Invoice SMS notification provider.
*/
function NotifyInvoiceViaSMSFormProvider({ invoiceId, dialogName, ...props }) { function NotifyInvoiceViaSMSFormProvider({ invoiceId, dialogName, ...props }) {
const [notificationType, setNotificationType] = React.useState('details'); const [notificationType, setNotificationType] = React.useState('details');
@@ -16,6 +19,7 @@ function NotifyInvoiceViaSMSFormProvider({ invoiceId, dialogName, ...props }) {
}, },
{ {
enabled: !!invoiceId, enabled: !!invoiceId,
keepPreviousData: true,
}, },
); );
// Create notfiy invoice by sms mutations. // Create notfiy invoice by sms mutations.

View File

@@ -26,7 +26,7 @@ function NotifyInvoiceViaSMSDialog({
<DialogSuspense> <DialogSuspense>
<NotifyInvoiceViaSMSDialogContent <NotifyInvoiceViaSMSDialogContent
dialogName={dialogName} dialogName={dialogName}
invoice={invoiceId} invoiceId={invoiceId}
/> />
</DialogSuspense> </DialogSuspense>
</Dialog> </Dialog>

View File

@@ -1,15 +1,19 @@
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { castArray } from 'lodash';
import intl from 'react-intl-universal';
export const transformErrors = (errors, { setErrors }) => { export const transformErrors = (errors, { setErrors }) => {
if ( let unsupportedVariablesError = errors.find(
errors.find((error) => error.type === 'UNSUPPORTED_SMS_MESSAGE_VARIABLES') (error) => error.type === 'UNSUPPORTED_SMS_MESSAGE_VARIABLES',
) { );
if (unsupportedVariablesError) {
const variables = castArray(
unsupportedVariablesError.data.unsupported_args,
);
const stringifiedVariables = variables.join(', ');
setErrors({ setErrors({
message_text: intl.get( message_text: `The SMS message has unsupported variables - ${stringifiedVariables}`,
'sms_message.dialog.unsupported_variables_error_message', intent: Intent.DANGER,
),
}); });
} }
}; };

View File

@@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { castArray } from 'lodash'; import { castArray, includes } from 'lodash';
import { Formik, Form, useFormikContext } from 'formik'; import { Formik, Form, useFormikContext } from 'formik';
import styled from 'styled-components'; import styled from 'styled-components';
import { Classes } from '@blueprintjs/core'; import { Callout, Classes, Intent } from '@blueprintjs/core';
import 'style/pages/NotifyConactViaSMS/NotifyConactViaSMSDialog.scss'; import 'style/pages/NotifyConactViaSMS/NotifyConactViaSMSDialog.scss';
@@ -57,6 +57,8 @@ function NotifyViaSMSForm({
onSubmit, onSubmit,
onCancel, onCancel,
onValuesChange, onValuesChange,
calloutCodes,
formikProps,
}) { }) {
// Initial form values // Initial form values
const initialValues = { const initialValues = {
@@ -71,6 +73,7 @@ function NotifyViaSMSForm({
return ( return (
<Formik <Formik
enableReinitialize={true}
validationSchema={CreateNotifyViaSMSFormSchema} validationSchema={CreateNotifyViaSMSFormSchema}
initialValues={initialValues} initialValues={initialValues}
onSubmit={onSubmit} onSubmit={onSubmit}
@@ -79,6 +82,7 @@ function NotifyViaSMSForm({
<div className={Classes.DIALOG_BODY}> <div className={Classes.DIALOG_BODY}>
<NotifyContent> <NotifyContent>
<NotifyFieldsSection> <NotifyFieldsSection>
<NotifyViaSMSAlerts calloutCodes={calloutCodes} />
<NotifyViaSMSFormFields <NotifyViaSMSFormFields
notificationTypes={formattedNotificationTypes} notificationTypes={formattedNotificationTypes}
/> />
@@ -108,6 +112,26 @@ function NotifyObserveValuesChange({ onChange }) {
return <FormObserver values={values} onChange={handleChange} />; return <FormObserver values={values} onChange={handleChange} />;
} }
/**
* Notify via SMS form alerts.
*/
function NotifyViaSMSAlerts({ calloutCodes }) {
return [
includes(calloutCodes, 100) && (
<Callout icon={null} intent={Intent.DANGER}>
The customer phone number does not eixst, please enter a personal phone
number to the customer.
</Callout>
),
includes(calloutCodes, 200) && (
<Callout icon={null} intent={Intent.DANGER}>
The customer phone number is invalid, please enter a valid personal
phone number to the customer.
</Callout>
),
];
}
export default NotifyViaSMSForm; export default NotifyViaSMSForm;
const NotifyContent = styled.div` const NotifyContent = styled.div`

View File

@@ -1,16 +1,14 @@
import { Intent } from '@blueprintjs/core';
import { AppToaster } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
export const transformErrors = (errors, { setErrors }) => { export const transformErrors = (errors, { setErrors, setCalloutCode }) => {
if (errors.some((e) => e.type === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID')) { if (errors.some((e) => e.type === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID')) {
AppToaster.show({ setCalloutCode([200]);
message: intl.get('notify_via_sms.dialog.phone_invalid_error_message'), setErrors({
intent: Intent.DANGER, customer_phone_number: 'The personal phone number is invalid.',
}); });
} }
if (errors.find((error) => error.type === 'CUSTOMER_HAS_NO_PHONE_NUMBER')) { if (errors.find((error) => error.type === 'CUSTOMER_HAS_NO_PHONE_NUMBER')) {
setCalloutCode([100]);
setErrors({ setErrors({
customer_phone_number: intl.get( customer_phone_number: intl.get(
'notify_via_sms.dialog.customer_no_phone_error_message', 'notify_via_sms.dialog.customer_no_phone_error_message',
@@ -19,7 +17,6 @@ export const transformErrors = (errors, { setErrors }) => {
} }
}; };
export const getSMSUnits = (message, threshold = 140) => { export const getSMSUnits = (message, threshold = 140) => {
return Math.ceil(message.length / threshold); return Math.ceil(message.length / threshold);
}; };