@bunnyapp/components 1.8.0-beta.5 → 1.8.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/cjs/index.js +435 -381
  2. package/dist/cjs/types/src/ajax.d.ts +1 -1
  3. package/dist/cjs/types/src/components/PandadocPollingModal.d.ts +1 -1
  4. package/dist/cjs/types/src/components/Quote/Quote.d.ts +28 -1
  5. package/dist/cjs/types/src/components/Quote/components/PaymentHoldDisplay.d.ts +18 -0
  6. package/dist/cjs/types/src/components/Quote/components/QuoteButtons.d.ts +12 -4
  7. package/dist/cjs/types/src/components/Quote/hooks/{useSendAcceptQuote.d.ts → useAcceptQuote.d.ts} +6 -3
  8. package/dist/cjs/types/src/components/Quote/hooks/useQuotePaymentHold.d.ts +20 -0
  9. package/dist/cjs/types/src/{graphql → components/Quote}/queries/getFormattedQuote.d.ts +6 -1
  10. package/dist/cjs/types/src/components/Quote/queries/quoteAccept.d.ts +14 -0
  11. package/dist/cjs/types/src/contexts/InvoiceQuoteContext.d.ts +1 -3
  12. package/dist/cjs/types/src/graphql/queries/getFormattedInvoice.d.ts +1 -1
  13. package/dist/cjs/types/src/utils/QueryKeyFactory.d.ts +4 -4
  14. package/dist/esm/index.js +435 -381
  15. package/dist/esm/types/src/ajax.d.ts +1 -1
  16. package/dist/esm/types/src/components/PandadocPollingModal.d.ts +1 -1
  17. package/dist/esm/types/src/components/Quote/Quote.d.ts +28 -1
  18. package/dist/esm/types/src/components/Quote/components/PaymentHoldDisplay.d.ts +18 -0
  19. package/dist/esm/types/src/components/Quote/components/QuoteButtons.d.ts +12 -4
  20. package/dist/esm/types/src/components/Quote/hooks/{useSendAcceptQuote.d.ts → useAcceptQuote.d.ts} +6 -3
  21. package/dist/esm/types/src/components/Quote/hooks/useQuotePaymentHold.d.ts +20 -0
  22. package/dist/esm/types/src/{graphql → components/Quote}/queries/getFormattedQuote.d.ts +6 -1
  23. package/dist/esm/types/src/components/Quote/queries/quoteAccept.d.ts +14 -0
  24. package/dist/esm/types/src/contexts/InvoiceQuoteContext.d.ts +1 -3
  25. package/dist/esm/types/src/graphql/queries/getFormattedInvoice.d.ts +1 -1
  26. package/dist/esm/types/src/utils/QueryKeyFactory.d.ts +4 -4
  27. package/dist/index.d.ts +14 -5
  28. package/package.json +1 -1
package/dist/esm/index.js CHANGED
@@ -1281,7 +1281,7 @@ const DEFAULT_CONFIG = {
1281
1281
  };
1282
1282
 
1283
1283
  // This will be replaced at build time by rollup-plugin-replace
1284
- const PACKAGE_VERSION = '1.8.0-beta.4';
1284
+ const PACKAGE_VERSION = '1.8.0-beta.6';
1285
1285
  const createRequestHeaders = (token) => {
1286
1286
  const headers = createClientDevHeaders({ token });
1287
1287
  // Add the components version header
@@ -19897,7 +19897,7 @@ const usePaymentMethod = ({ accountId, enabled = true, }) => {
19897
19897
  };
19898
19898
  };
19899
19899
 
19900
- const mutation$h = t(`
19900
+ const mutation$i = t(`
19901
19901
  query PaymentPlugins($accountId: ID) {
19902
19902
  paymentPlugins(accountId: $accountId) {
19903
19903
  enabled
@@ -19925,7 +19925,7 @@ const mutation$h = t(`
19925
19925
  // }[];
19926
19926
  // };
19927
19927
  const getPaymentPlugins = async ({ apiHost, token, accountId, }) => {
19928
- const response = await execute(mutation$h, { apiHost, token }, { accountId });
19928
+ const response = await execute(mutation$i, { apiHost, token }, { accountId });
19929
19929
  return response === null || response === void 0 ? void 0 : response.paymentPlugins;
19930
19930
  };
19931
19931
  const usePaymentPlugins = (accountId) => {
@@ -21696,6 +21696,102 @@ function ActualInvoice({ hidePaymentForm, onSavePaymentMethod, onPaymentMethodRe
21696
21696
  } }) }))] }) }));
21697
21697
  }
21698
21698
 
21699
+ const trimGraph = (s) => {
21700
+ return s.replace(/\s+/g, ' ');
21701
+ };
21702
+ const useGraphQL = (navigateOnTokenExpired, apiEndpoint, onError) => {
21703
+ return async (callback, bodyData = null, token, callbackParams) => {
21704
+ bodyData = trimGraph(bodyData);
21705
+ const headers = createClientDevHeaders({ token });
21706
+ const response = await fetch(apiEndpoint + '/graphql', {
21707
+ method: 'post',
21708
+ body: bodyData,
21709
+ headers,
21710
+ });
21711
+ if (response.status !== 200 && response.status !== 201) {
21712
+ return response.json().then((data) => {
21713
+ var _a, _b, _c;
21714
+ if (data.errors) {
21715
+ onError(data.errors[0].message);
21716
+ }
21717
+ else if (((_a = data === null || data === void 0 ? void 0 : data[0]) === null || _a === void 0 ? void 0 : _a.description) === 'Token is expired') {
21718
+ navigateOnTokenExpired();
21719
+ }
21720
+ else if ((_b = data === null || data === void 0 ? void 0 : data[0]) === null || _b === void 0 ? void 0 : _b.description) {
21721
+ throw new Error((_c = data === null || data === void 0 ? void 0 : data[0]) === null || _c === void 0 ? void 0 : _c.description);
21722
+ }
21723
+ return;
21724
+ });
21725
+ }
21726
+ return response
21727
+ .json()
21728
+ .then((data) => callback(data, callbackParams))
21729
+ .catch((err) => {
21730
+ console.error(err);
21731
+ onError(err);
21732
+ });
21733
+ };
21734
+ };
21735
+ const useGraphQLmutation = (navigateOnTokenExpired, apiEndpoint, onError) => {
21736
+ const graphQL = useGraphQL(navigateOnTokenExpired, apiEndpoint, onError);
21737
+ return (mutation, variables, callback, token, callbackParams) => {
21738
+ if (typeof variables === 'object')
21739
+ variables = JSON.stringify(variables);
21740
+ return graphQL(callback, `{ "query": "${mutation}", "variables": ${variables} }`, token, callbackParams);
21741
+ };
21742
+ };
21743
+
21744
+ const POLLING_INTERVAL = 2000;
21745
+ const PandadocPollingModal = ({ isVisible, setVisible, id }) => {
21746
+ const { apiHost, onTokenExpired } = useContext(BunnyContext);
21747
+ const token = useToken();
21748
+ const graphQLMutation = useGraphQLmutation(() => {
21749
+ console.log('graphQLMutation navigateOnTokenExpired not yet implemented');
21750
+ }, apiHost || '', () => {
21751
+ console.log('graphQLMutation onError not yet implemented');
21752
+ });
21753
+ const handleAllErrorFormats = useAllErrorFormats$1(onTokenExpired);
21754
+ const [numberOfPolls, setNumberOfPolls] = useState(0);
21755
+ const [infoMessage, setInfoMessage] = useState('');
21756
+ useEffect(() => {
21757
+ if (!isVisible)
21758
+ return;
21759
+ const pollPandadocMutation = () => {
21760
+ const mutation = `mutation quotePollSigningUrl($id: ID) {
21761
+ quotePollSigningUrl(quoteId: $id) {
21762
+ redirectUri
21763
+ status
21764
+ errors
21765
+ infoMessage
21766
+ }
21767
+ }`;
21768
+ const variables = {
21769
+ id,
21770
+ };
21771
+ graphQLMutation(mutation, variables, (rsp) => {
21772
+ if (rsp.errors)
21773
+ handleAllErrorFormats(rsp.errors[0].message);
21774
+ else if (rsp.data.quotePollSigningUrl.status === 'document.sent') {
21775
+ setVisible(false);
21776
+ window.location.href = rsp.data.quotePollSigningUrl.redirectUri;
21777
+ }
21778
+ setInfoMessage(rsp.data.quotePollSigningUrl.infoMessage || '');
21779
+ }, token);
21780
+ setNumberOfPolls(numberOfPolls + 1);
21781
+ };
21782
+ const interval = setInterval(pollPandadocMutation, POLLING_INTERVAL);
21783
+ return () => clearInterval(interval);
21784
+ }, [
21785
+ graphQLMutation,
21786
+ // handleAllErrorFormats,
21787
+ numberOfPolls,
21788
+ token,
21789
+ isVisible,
21790
+ setVisible,
21791
+ ]);
21792
+ return (jsxs(Modal, { title: "Uploading quote to Pandadoc", open: isVisible, closable: false, footer: null, children: [jsxs("div", { className: "bunny-py-4 bunny-text-center", children: ["This may take a few seconds", '.'.repeat(numberOfPolls)] }), jsx("div", { className: "bunny-text-center", children: infoMessage })] }));
21793
+ };
21794
+
21699
21795
  const usePlugins = ({ apiHost, token }) => {
21700
21796
  const response = useQuery({
21701
21797
  queryKey: QueryKeyFactory.pluginsKey(token),
@@ -21818,76 +21914,7 @@ const AcceptQuoteModal = ({ acceptBoxVisible, formattedQuote: maskedFormattedQuo
21818
21914
  }, open: acceptBoxVisible, title: (signingPlugins === null || signingPlugins === void 0 ? void 0 : signingPlugins.length) ? 'Start signing' : 'Accept quote', width: 400, children: jsx(NoSigningPluginsForm, { isVisible: acceptBoxVisible, formattedQuote: formattedQuote, form: form }) }));
21819
21915
  };
21820
21916
 
21821
- const tagStyleMap = {
21822
- blue: { color: 'var(--bunny-blue-500)', background: 'var(--bunny-blue-200)' },
21823
- green: {
21824
- color: 'var(--bunny-green-600)',
21825
- background: 'var(--bunny-green-200)',
21826
- },
21827
- red: { color: 'var(--bunny-red-500)', background: 'var(--bunny-red-200)' },
21828
- orange: {
21829
- color: 'var(--bunny-orange-500)',
21830
- background: 'var(--bunny-orange-200)',
21831
- },
21832
- yellow: {
21833
- color: 'var(--bunny-yellow-500)',
21834
- background: 'var(--bunny-yellow-200)',
21835
- },
21836
- purple: {
21837
- color: 'var(--bunny-purple-500)',
21838
- background: 'var(--bunny-purple-200)',
21839
- },
21840
- black: { color: 'white', background: 'var(--bunny-black)' },
21841
- };
21842
- // This component provides custom styling for antd Tag components without using antd overwrites.
21843
- // Please use this component instead of the antd Tag component directly to maintain consistent styling.
21844
- const CustomizedTag = ({ children, color, className, style, }) => {
21845
- return (jsx(Tag, { color: color, style: { ...(color ? tagStyleMap[color] : undefined), ...style }, className: `bunny-m-0 bunny-rounded-full bunny-border-none bunny-whitespace-nowrap ${className}`, children: children }));
21846
- };
21847
-
21848
- const useIsExpired = (expiresAt) => dayjs(expiresAt).diff(dayjs(dayjs().format("YYYY-MM-DD"))) < 0;
21849
-
21850
- dayjs.extend(localizedFormat);
21851
- const formatDate = (date) => dayjs(date).format('ll');
21852
-
21853
- const { Text: Text$z } = Typography;
21854
- const QuoteButtons_FormattedQuoteFragment = t(`
21855
- fragment QuoteButtons_FormattedQuoteFragment on FormattedQuote {
21856
- acceptedAt
21857
- acceptedByName
21858
- currency
21859
- amount
21860
- expiresAt
21861
- }
21862
- `);
21863
- function QuoteButtons({ isAccepted, formattedQuote: maskedFormattedQuote, isMobile, hideDownloadButton, id, isAccepting, handleClickAccept, setPaymentHoldModalVisible, shouldDoPaymentHold, paymentHoldCompleted, paymentHold, isSendAcceptPending, }) {
21864
- // Read fragments
21865
- const formattedQuote = readFragment(QuoteButtons_FormattedQuoteFragment, maskedFormattedQuote);
21866
- const { apiHost } = useContext(BunnyContext);
21867
- const token = useToken();
21868
- const { secondaryColor } = useBrand();
21869
- const downloadFile = useDownloadFile(id);
21870
- const isExpired = useIsExpired(formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.expiresAt);
21871
- const signingPlugins = useSigningPlugins({ apiHost, token });
21872
- return (jsxs("div", { className: "flex flex-row justify-end items-center gap-4", id: "acceptance", style: {
21873
- color: secondaryColor,
21874
- }, children: [isAccepted && formattedQuote.acceptedAt ? (jsx(Text$z, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsx(Button, { icon: jsx(DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsx(Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsx(Fragment, { children: !isAccepted ? (jsx(Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
21875
- ? 'Quote is expired'
21876
- : (signingPlugins === null || signingPlugins === void 0 ? void 0 : signingPlugins.length)
21877
- ? 'Start signing'
21878
- : 'Accept quote' })) : null }))] }))] }));
21879
- }
21880
- function PaymentHoldDisplay({ paymentHold, currency, amount, }) {
21881
- var _a, _b, _c, _d;
21882
- const paymentMethod = ((_b = (_a = paymentHold.paymentMethod) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.identifier)
21883
- ? (_d = (_c = paymentHold.paymentMethod) === null || _c === void 0 ? void 0 : _c.metadata) === null || _d === void 0 ? void 0 : _d.identifier
21884
- : 'N/A';
21885
- const formattedAmount = currency ? formatCurrency(amount, currency) : 'N/A';
21886
- const expirationDate = paymentHold.expiresAt ? formatDate(paymentHold.expiresAt) : 'N/A';
21887
- return (jsx(Tooltip$1, { title: `${formattedAmount} will be charged to ${paymentMethod} once the quote is accepted. Hold will be released on ${expirationDate} if not accepted.`, children: jsx(Fragment, { children: jsxs(CustomizedTag, { color: 'orange', className: "rounded-md", style: { padding: 6 }, children: ["Hold of ", formattedAmount, " on ****", paymentMethod] }) }) }));
21888
- }
21889
-
21890
- const { Title: Title$2, Text: Text$y } = Typography;
21917
+ const { Title: Title$2, Text: Text$z } = Typography;
21891
21918
  const showSuccessNotification$2 = useSuccessNotification();
21892
21919
  const showErrorNotification$5 = useErrorNotification();
21893
21920
  const PaymentHoldModal_FormattedQuoteFragment = t(`
@@ -21913,7 +21940,7 @@ const PaymentHoldModal = ({ visible, setVisible, formattedQuote: maskedFormatted
21913
21940
  const [form] = Form.useForm();
21914
21941
  return (jsx(StyledModal$2, { centered: true, onCancel: () => {
21915
21942
  setVisible(false);
21916
- }, footer: null, open: visible, width: 800, className: 'bunny-flex bunny-flex-row bunny-gap-4', children: jsxs("div", { className: "bunny-flex bunny-flex-row", children: [jsxs("div", { className: "bunny-flex bunny-flex-col bunny-w-1/2", children: [jsxs("div", { className: "bunny-mt-5 bunny-mx-4", children: [jsx(Title$2, { className: "bunny-mt-0", level: 5, children: "Pay and sign" }), jsxs(Text$y, { className: "bunny-bt-2 bunny-text-sm/5 bunny-text-gray-500", children: ["To accept this quote, approve a payment hold for", ' ', formatCurrency(formattedQuote.amount, formattedQuote.currency || 'null'), ". This amount will be charged to your payment method once the quote is signed."] })] }), jsx("div", { className: "bunny-p-4", children: noSigningPlugins ? jsx(NoSigningPluginsForm, { isVisible: visible, formattedQuote: formattedQuote, form: form }) : null })] }), jsx(VerticalDivider, { className: "bunny-m-4" }), jsx("div", { className: "bunny-mb-3 bunny-w-1/2 bunny-pt-6", children: jsx(PaymentForm, { quote: formattedQuote.quote, paymentHoldOptions: {
21943
+ }, footer: null, open: visible, width: 800, className: 'bunny-flex bunny-flex-row bunny-gap-4', children: jsxs("div", { className: "bunny-flex bunny-flex-row", children: [jsxs("div", { className: "bunny-flex bunny-flex-col bunny-w-1/2", children: [jsxs("div", { className: "bunny-mt-5 bunny-mx-4", children: [jsx(Title$2, { className: "bunny-mt-0", level: 5, children: "Pay and sign" }), jsxs(Text$z, { className: "bunny-bt-2 bunny-text-sm/5 bunny-text-gray-500", children: ["To accept this quote, approve a payment hold for", ' ', formatCurrency(formattedQuote.amount, formattedQuote.currency || 'null'), ". This amount will be charged to your payment method once the quote is signed."] })] }), jsx("div", { className: "bunny-p-4", children: noSigningPlugins ? jsx(NoSigningPluginsForm, { isVisible: visible, formattedQuote: formattedQuote, form: form }) : null })] }), jsx(VerticalDivider, { className: "bunny-m-4" }), jsx("div", { className: "bunny-mb-3 bunny-w-1/2 bunny-pt-6", children: jsx(PaymentForm, { quote: formattedQuote.quote, paymentHoldOptions: {
21917
21944
  payToAccept: true,
21918
21945
  amountToHold: formattedQuote.amount,
21919
21946
  }, onPaymentSuccess: () => {
@@ -21936,13 +21963,15 @@ const PaymentHoldModal = ({ visible, setVisible, formattedQuote: maskedFormatted
21936
21963
  token,
21937
21964
  }),
21938
21965
  });
21939
- // accept quote automatically
21940
- form
21941
- .validateFields()
21942
- .then(changedFields => {
21943
- sendAccept(changedFields);
21944
- })
21945
- .catch(() => { });
21966
+ // accept quote automatically if no signing plugins are present
21967
+ if (noSigningPlugins) {
21968
+ form
21969
+ .validateFields()
21970
+ .then(changedFields => {
21971
+ sendAccept(changedFields);
21972
+ })
21973
+ .catch(() => { });
21974
+ }
21946
21975
  }, paymentHoldPrecondition: async () => {
21947
21976
  if (!noSigningPlugins)
21948
21977
  return true;
@@ -21988,232 +22017,125 @@ const StyledModal$2 = (props) => {
21988
22017
  return jsx(ModalOverrideBrandStylings, { closable: false, ...props });
21989
22018
  };
21990
22019
 
21991
- const query$7 = t(`
21992
- query formattedQuote($id: ID) {
21993
- formattedQuote(id: $id) {
21994
- quote {
21995
- documentTemplateId
21996
- documents {
21997
- id
21998
- filename
21999
- size
22000
- date
22001
- url
22002
- }
22003
- firstInvoice {
22004
- id
22005
- state
22006
- }
22007
- payableId
22008
- id
22009
- payToAccept
22010
- currentPaymentHold {
22011
- createdAt
22012
- expiresAt
22013
- id
22014
- updatedAt
22015
- paymentMethod {
22016
- accountId
22017
- createdAt
22018
- expirationDate
22019
- failureCode
22020
- id
22021
- isDefault
22022
- lastSuccess
22023
- paymentType
22024
- pluginId
22025
- state
22026
- updatedAt
22027
- metadata {
22028
- description
22029
- expiration
22030
- icon
22031
- identifier
22032
- issuer
22033
- kind
22034
- }
22035
- }
22036
- }
22037
- }
22038
- payableId
22039
- acceptedAt
22040
- acceptedByName
22041
- amount
22042
- amountDue
22043
- amountsByPeriod {
22044
- id
22045
- name
22046
- amount
22047
- }
22048
- billingCity
22049
- billingCountry
22050
- billingState
22051
- billingStreet
22052
- billingZip
22053
- contactName
22054
- currency
22055
- customerBillingCity
22056
- customerBillingCountry
22057
- customerBillingState
22058
- customerBillingStreet
22059
- customerBillingZip
22060
- customerName
22061
- discount
22062
- discountValue
22063
- duration
22064
- endDate
22065
- expiresAt
22066
- html
22067
- formattedLines {
22068
- amount
22069
- amountsByPeriod {
22070
- quantity
22071
- id
22072
- name
22073
- startDate
22074
- endDate
22075
- amount
22076
- amountsByTier {
22077
- id
22078
- tier {
22079
- starts
22080
- ends
22081
- price
22082
- }
22083
- quantity
22084
- amount
22085
- }
22086
- prorationRate
22087
- }
22088
- billingPeriodEnd
22089
- billingPeriodStart
22090
- chargeType
22091
- discount
22092
- frequency
22093
- isRamp
22094
- periods
22095
- planName
22096
- position
22097
- price
22098
- priceDecimals
22099
- priceListChargeId
22100
- priceListChargeName
22101
- priceListId
22102
- priceListName
22103
- priceTiers {
22104
- price
22105
- starts
22106
- }
22107
- pricingModel
22108
- productName
22109
- prorationRate
22110
- quantity
22111
- showProductNameOnLineItem
22112
- taxCode
22113
- trialEndDate
22114
- trialStartDate
22115
- unitOfMeasure
22116
- vatCode
22117
- }
22118
- netPaymentDays
22119
- notes
22120
- number
22121
- poNumberRequired
22122
- salesContactEmail
22123
- sharedAt
22124
- startDate
22125
- state
22126
- subtotal
22127
- taxAmount
22128
- taxNumberLabel
22129
- taxNumberRequired
22130
- vendorName
22131
- ...PaymentHoldModal_FormattedQuoteFragment
22132
- ...AcceptQuoteModal_FormattedQuoteFragment
22133
- ...QuoteButtons_FormattedQuoteFragment
22134
- }
22135
- }
22136
- `, [
22137
- PaymentHoldModal_FormattedQuoteFragment,
22138
- AcceptQuoteModal_FormattedQuoteFragment,
22139
- QuoteButtons_FormattedQuoteFragment,
22140
- ]);
22141
- const getFormattedQuote = async ({ token, apiHost, id, }) => {
22142
- const response = await execute(query$7, { apiHost, token }, { id });
22143
- return response === null || response === void 0 ? void 0 : response.formattedQuote;
22144
- };
22020
+ const useIsExpired = (expiresAt) => dayjs(expiresAt).diff(dayjs(dayjs().format("YYYY-MM-DD"))) < 0;
22145
22021
 
22146
- const trimGraph = (s) => {
22147
- return s.replace(/\s+/g, ' ');
22148
- };
22149
- const useGraphQL = (navigateOnTokenExpired, apiEndpoint, onError) => {
22150
- return async (callback, bodyData = null, token, callbackParams) => {
22151
- bodyData = trimGraph(bodyData);
22152
- const headers = createClientDevHeaders({ token });
22153
- const response = await fetch(apiEndpoint + '/graphql', {
22154
- method: 'post',
22155
- body: bodyData,
22156
- headers,
22157
- });
22158
- if (response.status !== 200 && response.status !== 201) {
22159
- return response.json().then((data) => {
22160
- var _a, _b, _c;
22161
- if (data.errors) {
22162
- onError(data.errors[0].message);
22163
- }
22164
- else if (((_a = data === null || data === void 0 ? void 0 : data[0]) === null || _a === void 0 ? void 0 : _a.description) === 'Token is expired') {
22165
- navigateOnTokenExpired();
22166
- }
22167
- else if ((_b = data === null || data === void 0 ? void 0 : data[0]) === null || _b === void 0 ? void 0 : _b.description) {
22168
- throw new Error((_c = data === null || data === void 0 ? void 0 : data[0]) === null || _c === void 0 ? void 0 : _c.description);
22169
- }
22170
- return;
22171
- });
22172
- }
22173
- return response
22174
- .json()
22175
- .then((data) => callback(data, callbackParams))
22176
- .catch((err) => {
22177
- console.error(err);
22178
- onError(err);
22179
- });
22180
- };
22022
+ dayjs.extend(localizedFormat);
22023
+ const formatDate = (date) => dayjs(date).format('ll');
22024
+
22025
+ const tagStyleMap = {
22026
+ blue: { color: 'var(--bunny-blue-500)', background: 'var(--bunny-blue-200)' },
22027
+ green: {
22028
+ color: 'var(--bunny-green-600)',
22029
+ background: 'var(--bunny-green-200)',
22030
+ },
22031
+ red: { color: 'var(--bunny-red-500)', background: 'var(--bunny-red-200)' },
22032
+ orange: {
22033
+ color: 'var(--bunny-orange-500)',
22034
+ background: 'var(--bunny-orange-200)',
22035
+ },
22036
+ yellow: {
22037
+ color: 'var(--bunny-yellow-500)',
22038
+ background: 'var(--bunny-yellow-200)',
22039
+ },
22040
+ purple: {
22041
+ color: 'var(--bunny-purple-500)',
22042
+ background: 'var(--bunny-purple-200)',
22043
+ },
22044
+ black: { color: 'white', background: 'var(--bunny-black)' },
22181
22045
  };
22182
- const useGraphQLmutation = (navigateOnTokenExpired, apiEndpoint, onError) => {
22183
- const graphQL = useGraphQL(navigateOnTokenExpired, apiEndpoint, onError);
22184
- return (mutation, variables, callback, token, callbackParams) => {
22185
- if (typeof variables === 'object')
22186
- variables = JSON.stringify(variables);
22187
- return graphQL(callback, `{ "query": "${mutation}", "variables": ${variables} }`, token, callbackParams);
22188
- };
22046
+ // This component provides custom styling for antd Tag components without using antd overwrites.
22047
+ // Please use this component instead of the antd Tag component directly to maintain consistent styling.
22048
+ const CustomizedTag = ({ children, color, className, style, }) => {
22049
+ return (jsx(Tag, { color: color, style: { ...(color ? tagStyleMap[color] : undefined), ...style }, className: `bunny-m-0 bunny-rounded-full bunny-border-none bunny-whitespace-nowrap ${className}`, children: children }));
22189
22050
  };
22190
22051
 
22191
- const handleAllErrorFormats = useAllErrorFormats();
22192
- const QUOTE_ACCEPT = `
22193
- mutation quoteAccept($name: String!, $title: String!, $poNumber: String, $taxNumber: String, $quoteId: ID) {
22194
- quoteAccept(name: $name, title: $title, poNumber: $poNumber, taxNumber: $taxNumber, quoteId: $quoteId) {
22052
+ const PaymentHoldDisplay_PaymentHoldFragment = t(`
22053
+ fragment PaymentHoldDisplay_PaymentHoldFragment on PaymentHold {
22054
+ expiresAt
22055
+ paymentMethod {
22056
+ metadata {
22057
+ identifier
22058
+ }
22059
+ }
22060
+ }
22061
+ `);
22062
+ function PaymentHoldDisplay({ paymentHold: maskedPaymentHold, currency, amount, }) {
22063
+ var _a, _b, _c, _d;
22064
+ const paymentHold = readFragment(PaymentHoldDisplay_PaymentHoldFragment, maskedPaymentHold);
22065
+ const paymentMethod = ((_b = (_a = paymentHold.paymentMethod) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.identifier)
22066
+ ? (_d = (_c = paymentHold.paymentMethod) === null || _c === void 0 ? void 0 : _c.metadata) === null || _d === void 0 ? void 0 : _d.identifier
22067
+ : 'N/A';
22068
+ const formattedAmount = currency ? formatCurrency(amount, currency) : 'N/A';
22069
+ const expirationDate = paymentHold.expiresAt ? formatDate(paymentHold.expiresAt) : 'N/A';
22070
+ return (jsx(Tooltip$1, { title: `${formattedAmount} will be charged to ${paymentMethod} once the quote is accepted.Hold will be released on ${expirationDate} if not accepted.`, children: jsx(Fragment, { children: jsxs(CustomizedTag, { color: 'orange', className: "rounded-md", style: { padding: 6 }, children: ["Hold of ", formattedAmount, " on ****", paymentMethod] }) }) }));
22071
+ }
22072
+
22073
+ const { Text: Text$y } = Typography;
22074
+ const QuoteButtons_FormattedQuoteFragment = t(`
22075
+ fragment QuoteButtons_FormattedQuoteFragment on FormattedQuote {
22076
+ acceptedAt
22077
+ acceptedByName
22078
+ currency
22079
+ amount
22080
+ expiresAt
22081
+ }
22082
+ `);
22083
+ const PaymentHoldDisplay_QuoteButtonsFragment = t(`
22084
+ fragment PaymentHoldDisplay_QuoteButtonsFragment on PaymentHold {
22085
+ ...PaymentHoldDisplay_PaymentHoldFragment
22086
+ }
22087
+ `, [PaymentHoldDisplay_PaymentHoldFragment]);
22088
+ function QuoteButtons({ isAccepted, formattedQuote: maskedFormattedQuote, isMobile, hideDownloadButton, id, isAccepting, handleClickAccept, setPaymentHoldModalVisible, shouldDoPaymentHold, paymentHoldCompleted, paymentHold: maskedPaymentHold, isSendAcceptPending, }) {
22089
+ // Read fragments
22090
+ const formattedQuote = readFragment(QuoteButtons_FormattedQuoteFragment, maskedFormattedQuote);
22091
+ const paymentHold = readFragment(PaymentHoldDisplay_QuoteButtonsFragment, maskedPaymentHold);
22092
+ const { apiHost } = useContext(BunnyContext);
22093
+ const token = useToken();
22094
+ const { secondaryColor } = useBrand();
22095
+ const downloadFile = useDownloadFile(id);
22096
+ const isExpired = useIsExpired(formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.expiresAt);
22097
+ const signingPlugins = useSigningPlugins({ apiHost, token });
22098
+ return (jsxs("div", { className: "flex flex-row justify-end items-center gap-4", id: "acceptance", style: {
22099
+ color: secondaryColor,
22100
+ }, children: [isAccepted && formattedQuote.acceptedAt ? (jsx(Text$y, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsx(Button, { icon: jsx(DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsx(Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsx(Fragment, { children: !isAccepted ? (jsx(Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
22101
+ ? 'Quote is expired'
22102
+ : (signingPlugins === null || signingPlugins === void 0 ? void 0 : signingPlugins.length)
22103
+ ? 'Start signing'
22104
+ : 'Accept quote' })) : null }))] }))] }));
22105
+ }
22106
+
22107
+ const mutation$h = t(`
22108
+ mutation QuoteAccept(
22109
+ $name: String!
22110
+ $title: String!
22111
+ $poNumber: String
22112
+ $taxNumber: String
22113
+ $quoteId: ID
22114
+ ) {
22115
+ quoteAccept(
22116
+ name: $name
22117
+ title: $title
22118
+ poNumber: $poNumber
22119
+ taxNumber: $taxNumber
22120
+ quoteId: $quoteId
22121
+ ) {
22195
22122
  errors
22196
22123
  }
22197
22124
  }
22198
- `;
22199
- const quoteAccept = async ({ quoteId, apiHost, token, changedFormItems, }) => {
22125
+ `);
22126
+ const quoteAccept = async ({ quoteId, apiHost, token, changedFormItems }) => {
22200
22127
  var _a, _b;
22201
- const vars = {
22202
- ...changedFormItems,
22203
- quoteId,
22204
- };
22205
- const response = await gqlRequest({
22206
- query: QUOTE_ACCEPT,
22207
- token,
22208
- vars,
22209
- apiHost,
22128
+ return await execute(mutation$h, { apiHost, token }, {
22129
+ name: changedFormItems.name,
22130
+ title: changedFormItems.title,
22131
+ poNumber: (_a = changedFormItems.poNumber) !== null && _a !== void 0 ? _a : null,
22132
+ taxNumber: (_b = changedFormItems.taxNumber) !== null && _b !== void 0 ? _b : null,
22133
+ quoteId: quoteId !== null && quoteId !== void 0 ? quoteId : null,
22210
22134
  });
22211
- const errors = (_a = response === null || response === void 0 ? void 0 : response.quoteAccept) === null || _a === void 0 ? void 0 : _a.errors;
22212
- if (errors)
22213
- throw errors;
22214
- return (_b = response.quoteAccept) === null || _b === void 0 ? void 0 : _b.quote;
22215
22135
  };
22216
- const useSendAcceptQuote = ({ quoteId, apiHost, token, onQuoteAccepted, }) => {
22136
+
22137
+ const handleAllErrorFormats = useAllErrorFormats();
22138
+ const useAcceptQuote = ({ quoteId, apiHost, token, onQuoteAccepted, }) => {
22217
22139
  // Hooks
22218
22140
  const graphQLMutation = useGraphQLmutation(() => {
22219
22141
  console.log('navigate in useGraphQLmutation in useSendAcceptQuote is not yet implemented');
@@ -22305,6 +22227,33 @@ const useSendAcceptQuote = ({ quoteId, apiHost, token, onQuoteAccepted, }) => {
22305
22227
  };
22306
22228
  };
22307
22229
 
22230
+ const useQuotePaymentHold_FormattedQuoteFragment = t(`
22231
+ fragment useQuotePaymentHold_FormattedQuoteFragment on FormattedQuote {
22232
+ quote {
22233
+ payToAccept
22234
+ currentPaymentHold {
22235
+ id
22236
+ }
22237
+ }
22238
+ }
22239
+ `);
22240
+ const useQuotePaymentHold = (maskedFormattedQuote) => {
22241
+ var _a, _b;
22242
+ const [paymentHoldModalVisible, setPaymentHoldModalVisible] = useState(false);
22243
+ const formattedQuote = maskedFormattedQuote
22244
+ ? readFragment(useQuotePaymentHold_FormattedQuoteFragment, maskedFormattedQuote)
22245
+ : undefined;
22246
+ const shouldDoPaymentHold = ((_a = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _a === void 0 ? void 0 : _a.payToAccept) === true;
22247
+ const currentPaymentHold = (_b = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _b === void 0 ? void 0 : _b.currentPaymentHold;
22248
+ return {
22249
+ // paymentHold: currentPaymentHold ?? undefined,
22250
+ paymentHoldModalVisible,
22251
+ setPaymentHoldModalVisible,
22252
+ shouldDoPaymentHold,
22253
+ paymentHoldCompleted: currentPaymentHold ? true : false,
22254
+ };
22255
+ };
22256
+
22308
22257
  const NavigationContext = createContext({});
22309
22258
 
22310
22259
  const useSigningComplete = ({ data, token }) => {
@@ -22320,63 +22269,186 @@ const useSigningComplete = ({ data, token }) => {
22320
22269
  }, [data, eventParam, queryClient, token]);
22321
22270
  };
22322
22271
 
22323
- const POLLING_INTERVAL = 2000;
22324
- const PandadocPollingModal = ({ isVisible, setVisible, id }) => {
22325
- const { apiHost, onTokenExpired } = useContext(BunnyContext);
22326
- const token = useToken();
22327
- const graphQLMutation = useGraphQLmutation(() => {
22328
- console.log('graphQLMutation navigateOnTokenExpired not yet implemented');
22329
- }, apiHost || '', () => {
22330
- console.log('graphQLMutation onError not yet implemented');
22331
- });
22332
- const handleAllErrorFormats = useAllErrorFormats$1(onTokenExpired);
22333
- const [numberOfPolls, setNumberOfPolls] = useState(0);
22334
- const [infoMessage, setInfoMessage] = useState('');
22335
- useEffect(() => {
22336
- if (!isVisible)
22337
- return;
22338
- const pollPandadocMutation = () => {
22339
- const mutation = `mutation quotePollSigningUrl($id: ID) {
22340
- quotePollSigningUrl(quoteId: $id) {
22341
- redirectUri
22342
- status
22343
- errors
22344
- infoMessage
22272
+ const query$7 = t(`
22273
+ query formattedQuote($id: ID) {
22274
+ formattedQuote(id: $id) {
22275
+ quote {
22276
+ documentTemplateId
22277
+ documents {
22278
+ id
22279
+ filename
22280
+ size
22281
+ date
22282
+ url
22283
+ }
22284
+ firstInvoice {
22285
+ id
22286
+ state
22287
+ }
22288
+ payableId
22289
+ id
22290
+ payToAccept
22291
+ currentPaymentHold {
22292
+ createdAt
22293
+ expiresAt
22294
+ id
22295
+ updatedAt
22296
+ paymentMethod {
22297
+ accountId
22298
+ createdAt
22299
+ expirationDate
22300
+ failureCode
22301
+ id
22302
+ isDefault
22303
+ lastSuccess
22304
+ paymentType
22305
+ pluginId
22306
+ state
22307
+ updatedAt
22308
+ metadata {
22309
+ description
22310
+ expiration
22311
+ icon
22312
+ identifier
22313
+ issuer
22314
+ kind
22315
+ }
22316
+ }
22317
+ ...PaymentHoldDisplay_QuoteButtonsFragment
22318
+ }
22345
22319
  }
22346
- }`;
22347
- const variables = {
22348
- id,
22349
- };
22350
- graphQLMutation(mutation, variables, (rsp) => {
22351
- if (rsp.errors)
22352
- handleAllErrorFormats(rsp.errors[0].message);
22353
- else if (rsp.data.quotePollSigningUrl.status === 'document.sent') {
22354
- setVisible(false);
22355
- window.location.href = rsp.data.quotePollSigningUrl.redirectUri;
22356
- }
22357
- setInfoMessage(rsp.data.quotePollSigningUrl.infoMessage || '');
22358
- }, token);
22359
- setNumberOfPolls(numberOfPolls + 1);
22360
- };
22361
- const interval = setInterval(pollPandadocMutation, POLLING_INTERVAL);
22362
- return () => clearInterval(interval);
22363
- }, [
22364
- graphQLMutation,
22365
- // handleAllErrorFormats,
22366
- numberOfPolls,
22367
- token,
22368
- isVisible,
22369
- setVisible,
22370
- ]);
22371
- return (jsxs(Modal, { title: "Uploading quote to Pandadoc", open: isVisible, closable: false, footer: null, children: [jsxs("div", { className: "bunny-py-4 bunny-text-center", children: ["This may take a few seconds", '.'.repeat(numberOfPolls)] }), jsx("div", { className: "bunny-text-center", children: infoMessage })] }));
22320
+ payableId
22321
+ acceptedAt
22322
+ acceptedByName
22323
+ amount
22324
+ amountDue
22325
+ amountsByPeriod {
22326
+ id
22327
+ name
22328
+ amount
22329
+ }
22330
+ billingCity
22331
+ billingCountry
22332
+ billingState
22333
+ billingStreet
22334
+ billingZip
22335
+ contactName
22336
+ currency
22337
+ customerBillingCity
22338
+ customerBillingCountry
22339
+ customerBillingState
22340
+ customerBillingStreet
22341
+ customerBillingZip
22342
+ customerName
22343
+ discount
22344
+ discountValue
22345
+ duration
22346
+ endDate
22347
+ expiresAt
22348
+ html
22349
+ formattedLines {
22350
+ amount
22351
+ amountsByPeriod {
22352
+ quantity
22353
+ id
22354
+ name
22355
+ startDate
22356
+ endDate
22357
+ amount
22358
+ amountsByTier {
22359
+ id
22360
+ tier {
22361
+ starts
22362
+ ends
22363
+ price
22364
+ }
22365
+ quantity
22366
+ amount
22367
+ }
22368
+ prorationRate
22369
+ }
22370
+ billingPeriodEnd
22371
+ billingPeriodStart
22372
+ chargeType
22373
+ discount
22374
+ frequency
22375
+ isRamp
22376
+ periods
22377
+ planName
22378
+ position
22379
+ price
22380
+ priceDecimals
22381
+ priceListChargeId
22382
+ priceListChargeName
22383
+ priceListId
22384
+ priceListName
22385
+ priceTiers {
22386
+ price
22387
+ starts
22388
+ }
22389
+ pricingModel
22390
+ productName
22391
+ prorationRate
22392
+ quantity
22393
+ showProductNameOnLineItem
22394
+ taxCode
22395
+ trialEndDate
22396
+ trialStartDate
22397
+ unitOfMeasure
22398
+ vatCode
22399
+ }
22400
+ netPaymentDays
22401
+ notes
22402
+ number
22403
+ poNumberRequired
22404
+ salesContactEmail
22405
+ sharedAt
22406
+ startDate
22407
+ state
22408
+ subtotal
22409
+ taxAmount
22410
+ taxNumberLabel
22411
+ taxNumberRequired
22412
+ vendorName
22413
+ ...useQuotePaymentHold_FormattedQuoteFragment
22414
+ ...PaymentHoldModal_FormattedQuoteFragment
22415
+ ...AcceptQuoteModal_FormattedQuoteFragment
22416
+ ...QuoteButtons_FormattedQuoteFragment
22417
+ }
22418
+ }
22419
+ `, [
22420
+ useQuotePaymentHold_FormattedQuoteFragment,
22421
+ PaymentHoldModal_FormattedQuoteFragment,
22422
+ AcceptQuoteModal_FormattedQuoteFragment,
22423
+ QuoteButtons_FormattedQuoteFragment,
22424
+ PaymentHoldDisplay_QuoteButtonsFragment,
22425
+ ]);
22426
+ const getFormattedQuote = async ({ token, apiHost, id, }) => {
22427
+ const response = await execute(query$7, { apiHost, token }, { id });
22428
+ return response === null || response === void 0 ? void 0 : response.formattedQuote;
22372
22429
  };
22373
22430
 
22374
22431
  const showErrorNotification$4 = useErrorNotification();
22375
- defaultStyled.div `
22376
- Text {
22377
- width: 100%;
22378
- }
22379
- `;
22432
+ t(`
22433
+ fragment Quote_PaymentHoldFragment on FormattedQuote {
22434
+ quote {
22435
+ currentPaymentHold {
22436
+ ...PaymentHoldDisplay_QuoteButtonsFragment
22437
+ }
22438
+ firstInvoice {
22439
+ id
22440
+ }
22441
+ }
22442
+ }
22443
+ `, [PaymentHoldDisplay_QuoteButtonsFragment]);
22444
+ t(`
22445
+ fragment OnQuoteLoadedFragment on FormattedQuote {
22446
+ vendorName
22447
+ quote {
22448
+ id
22449
+ }
22450
+ }
22451
+ `);
22380
22452
  function Quote({ id, invoiceQuoteViewComponent, onInvoiceDownloadError, onPaymentSuccess, shadow = 'shadow-md', className, hideDownloadButton = false, onQuoteLoaded, onQuoteAccepted, onQuoteUnavailableError, suppressQuoteUnavailableErrorNotification = false, }) {
22381
22453
  return (jsx(InvoiceQuoteContext.Provider, { value: {
22382
22454
  id,
@@ -22386,30 +22458,16 @@ function Quote({ id, invoiceQuoteViewComponent, onInvoiceDownloadError, onPaymen
22386
22458
  shadow,
22387
22459
  className,
22388
22460
  hideDownloadButton,
22389
- onQuoteLoaded,
22390
22461
  onQuoteUnavailableError,
22391
22462
  suppressQuoteUnavailableErrorNotification,
22392
- }, children: jsx(ActualQuote, { onQuoteAccepted: onQuoteAccepted }) }));
22463
+ }, children: jsx(ActualQuote, { onQuoteAccepted: onQuoteAccepted, onQuoteLoaded: onQuoteLoaded }) }));
22393
22464
  }
22394
- const useQuotePaymentHold = (formattedQuote) => {
22395
- var _a, _b;
22396
- const [paymentHoldModalVisible, setPaymentHoldModalVisible] = useState(false);
22397
- const shouldDoPaymentHold = ((_a = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _a === void 0 ? void 0 : _a.payToAccept) == true;
22398
- const currentPaymentHold = (_b = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _b === void 0 ? void 0 : _b.currentPaymentHold;
22399
- return {
22400
- paymentHold: currentPaymentHold,
22401
- paymentHoldModalVisible,
22402
- setPaymentHoldModalVisible,
22403
- shouldDoPaymentHold,
22404
- paymentHoldCompleted: currentPaymentHold ? true : false,
22405
- };
22406
- };
22407
- function ActualQuote({ onQuoteAccepted }) {
22408
- var _a, _b, _c, _d, _e, _f;
22465
+ function ActualQuote({ onQuoteAccepted, onQuoteLoaded }) {
22466
+ var _a, _b, _c, _d, _e, _f, _g;
22409
22467
  // Context
22410
22468
  const { apiHost } = useContext(BunnyContext);
22411
22469
  const token = useToken();
22412
- const { className, id, hideDownloadButton, onQuoteLoaded, onQuoteUnavailableError, suppressQuoteUnavailableErrorNotification } = useContext(InvoiceQuoteContext);
22470
+ const { className, id, hideDownloadButton, onQuoteUnavailableError, suppressQuoteUnavailableErrorNotification } = useContext(InvoiceQuoteContext);
22413
22471
  // Queries
22414
22472
  const { data: formattedQuote, isLoading, error } = useQuery({
22415
22473
  queryKey: QueryKeyFactory.createQuoteKey({ id, token }),
@@ -22419,7 +22477,7 @@ function ActualQuote({ onQuoteAccepted }) {
22419
22477
  placeholderData: keepPreviousData,
22420
22478
  });
22421
22479
  // Hooks
22422
- const { acceptBoxVisible, isAccepting, sendAccept, setAcceptBoxVisible, setIsAccepting, startAcceptance, pandadocPollingModalVisible, setPandadocPollingModalVisible, isSendAcceptPending, } = useSendAcceptQuote({
22480
+ const { acceptBoxVisible, isAccepting, sendAccept, setAcceptBoxVisible, setIsAccepting, startAcceptance, pandadocPollingModalVisible, setPandadocPollingModalVisible, isSendAcceptPending, } = useAcceptQuote({
22423
22481
  token,
22424
22482
  apiHost,
22425
22483
  quoteId: id,
@@ -22429,7 +22487,7 @@ function ActualQuote({ onQuoteAccepted }) {
22429
22487
  const isMobile = useIsMobile();
22430
22488
  useEffect(() => {
22431
22489
  if (formattedQuote) {
22432
- onQuoteLoaded === null || onQuoteLoaded === void 0 ? void 0 : onQuoteLoaded(formattedQuote); // TODO: fix to use the correct type
22490
+ onQuoteLoaded === null || onQuoteLoaded === void 0 ? void 0 : onQuoteLoaded(formattedQuote);
22433
22491
  }
22434
22492
  }, [formattedQuote]);
22435
22493
  useEffect(() => {
@@ -22445,7 +22503,8 @@ function ActualQuote({ onQuoteAccepted }) {
22445
22503
  }
22446
22504
  }, [error]);
22447
22505
  // Payment hold stuff here
22448
- const { paymentHoldModalVisible, setPaymentHoldModalVisible, shouldDoPaymentHold, paymentHoldCompleted, paymentHold, } = useQuotePaymentHold(formattedQuote); // TODO: fix to use the correct type
22506
+ const { paymentHoldModalVisible, setPaymentHoldModalVisible, shouldDoPaymentHold, paymentHoldCompleted, } = useQuotePaymentHold(formattedQuote);
22507
+ const paymentHold = (_a = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _a === void 0 ? void 0 : _a.currentPaymentHold;
22449
22508
  const handleClickAccept = () => {
22450
22509
  if (shouldDoPaymentHold && !paymentHoldCompleted) {
22451
22510
  setPaymentHoldModalVisible(true);
@@ -22459,12 +22518,12 @@ function ActualQuote({ onQuoteAccepted }) {
22459
22518
  }
22460
22519
  // Derived state
22461
22520
  const isAccepted = formattedQuote.state === 'ACCEPTED';
22462
- const firstInvoice = (_a = formattedQuote.quote) === null || _a === void 0 ? void 0 : _a.firstInvoice;
22521
+ const firstInvoice = (_b = formattedQuote.quote) === null || _b === void 0 ? void 0 : _b.firstInvoice;
22463
22522
  if ((firstInvoice === null || firstInvoice === void 0 ? void 0 : firstInvoice.state) === 'PAID' && paymentHoldCompleted) {
22464
22523
  return jsx(Invoice, { id: firstInvoice.id });
22465
22524
  }
22466
- return (jsxs(Fragment, { children: [jsxs("div", { className: `bunny-flex bunny-flex-col bunny-gap-4 ${isMobile ? 'bunny-w-full bunny-overflow-hidden' : ''} ${className}`, children: [jsx(QuoteButtons, { isAccepted: isAccepted, formattedQuote: formattedQuote, isMobile: isMobile, hideDownloadButton: hideDownloadButton, id: id, isAccepting: isAccepting, handleClickAccept: handleClickAccept, setPaymentHoldModalVisible: setPaymentHoldModalVisible, shouldDoPaymentHold: shouldDoPaymentHold, paymentHoldCompleted: paymentHoldCompleted, paymentHold: paymentHold, isSendAcceptPending: isSendAcceptPending }), jsx(InvoiceQuoteView, { html: formattedQuote.html, targetUrl: ((_b = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _b === void 0 ? void 0 : _b.documentTemplateId) ? `/pdf/quote` : undefined, children: ((_d = (_c = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _c === void 0 ? void 0 : _c.documents) === null || _d === void 0 ? void 0 : _d.length) &&
22467
- ((_f = (_e = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _e === void 0 ? void 0 : _e.documents) === null || _f === void 0 ? void 0 : _f.length) > 0 ? (jsx("div", { className: "bunny-flex bunny-flex-col bunny-items-end", children: formattedQuote.quote.documents.map((doc, index) => {
22525
+ return (jsxs(Fragment, { children: [jsxs("div", { className: `bunny-flex bunny-flex-col bunny-gap-4 ${isMobile ? 'bunny-w-full bunny-overflow-hidden' : ''} ${className}`, children: [jsx(QuoteButtons, { isAccepted: isAccepted, formattedQuote: formattedQuote, isMobile: isMobile, hideDownloadButton: hideDownloadButton, id: id, isAccepting: isAccepting, handleClickAccept: handleClickAccept, setPaymentHoldModalVisible: setPaymentHoldModalVisible, shouldDoPaymentHold: shouldDoPaymentHold, paymentHoldCompleted: paymentHoldCompleted, paymentHold: paymentHold, isSendAcceptPending: isSendAcceptPending }), jsx(InvoiceQuoteView, { html: formattedQuote.html, targetUrl: ((_c = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _c === void 0 ? void 0 : _c.documentTemplateId) ? `/pdf/quote` : undefined, children: ((_e = (_d = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _d === void 0 ? void 0 : _d.documents) === null || _e === void 0 ? void 0 : _e.length) &&
22526
+ ((_g = (_f = formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.quote) === null || _f === void 0 ? void 0 : _f.documents) === null || _g === void 0 ? void 0 : _g.length) > 0 ? (jsx("div", { className: "bunny-flex bunny-flex-col bunny-items-end", children: formattedQuote.quote.documents.map((doc, index) => {
22468
22527
  return (jsx(Button, { download: doc.filename, href: doc.url, type: "link", children: doc.filename }, index));
22469
22528
  }) })) : null })] }), jsx(AcceptQuoteModal, { acceptBoxVisible: acceptBoxVisible, formattedQuote: formattedQuote, setAcceptBoxVisible: setAcceptBoxVisible, setIsAccepting: setIsAccepting, sendAccept: sendAccept, isSendAcceptPending: isSendAcceptPending }), jsx(PaymentHoldModal, { visible: paymentHoldModalVisible, setVisible: setPaymentHoldModalVisible, formattedQuote: formattedQuote, sendAccept: sendAccept }), jsx(PandadocPollingModal, { isVisible: pandadocPollingModalVisible, setVisible: setPandadocPollingModalVisible, id: id })] }));
22470
22529
  }
@@ -22992,7 +23051,6 @@ function canApplyCoupons(maskedQuote, activeCouponsExist, maskedUpgradingSubscri
22992
23051
  if (quoteKindIsValid) {
22993
23052
  const result = activeCouponsExist &&
22994
23053
  (upgradingFromTrial || upgradingFromFree() || signingUpForNewSubscription);
22995
- console.log('returning result', result);
22996
23054
  return result;
22997
23055
  }
22998
23056
  return false;
@@ -30185,11 +30243,7 @@ function BillingDetailsSection({ hidePaymentMethodForm, countryListFilter, }) {
30185
30243
  return countryListFilter ? COUNTRY_LIST.filter(countryListFilter) : COUNTRY_LIST;
30186
30244
  }, [countryListFilter]);
30187
30245
  const isLoading = isLoadingAccount || isLoadingContacts;
30188
- return (jsxs("div", { className: `${isMobile || hidePaymentMethodForm ? 'bunny-w-full' : 'bunny-w-1/2'}`, children: [jsxs("div", { className: "bunny-px-4", children: [jsxs(Skeleton, { loading: isLoading || account === undefined, children: [jsx("div", { className: "bunny-mb-2 bunny-pl-1", children: jsx(Text, { className: "bunny-font-medium bunny-text-lg", children: (account === null || account === void 0 ? void 0 : account.name) || 'No company name' }) }), jsxs(Form, { className: "bunny-flex bunny-flex-col bunny-gap-2", form: form, layout: "vertical", disabled: isUpdatingAccount, autoComplete: "off", requiredMark: false, children: [jsx(Form.Item, { label: "Street address", name: "billingStreet", rules: [{ required: true, message: 'Street address is required' }], children: jsx(Input, {}) }), jsxs("div", { className: "bunny-flex bunny-gap-4", children: [jsx(Form.Item, { label: "City", name: "billingCity", rules: [{ required: true, message: 'City is required' }], className: "bunny-flex-1", children: jsx(Input, {}) }), jsx(Form.Item, { label: "Zipcode", name: "billingZip", rules: [{ required: true, message: 'Zipcode is required' }], className: "bunny-flex-1", children: jsx(Input, {}) })] }), jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-row bunny-pb-2' : 'bunny-flex-row'} bunny-gap-4`, children: [jsx("div", { className: "bunny-flex-1 bunny-w-1/2", children: jsx(Form.Item, { label: "State", name: "billingState", rules: [
30189
- {
30190
- required: false,
30191
- },
30192
- ], children: jsx(Input, {}) }) }), jsx("div", { className: "bunny-flex-1 bunny-w-1/2", children: jsx(Form.Item, { label: "Country", name: "billingCountry", rules: [{ required: true, message: 'Country is required' }], children: jsx(Select, { className: "bunny-w-full", options: filteredCountryList, placeholder: "Select a country", popupMatchSelectWidth: false, showSearch: true, filterOption: (input, option) => {
30246
+ return (jsxs("div", { className: `${isMobile || hidePaymentMethodForm ? 'bunny-w-full' : 'bunny-w-1/2'}`, children: [jsxs("div", { className: "bunny-px-4", children: [jsxs(Skeleton, { loading: isLoading || account === undefined, children: [jsx("div", { className: "bunny-mb-2 bunny-pl-1", children: jsx(Text, { className: "bunny-font-medium bunny-text-lg", children: (account === null || account === void 0 ? void 0 : account.name) || 'No company name' }) }), jsxs(Form, { className: "bunny-flex bunny-flex-col bunny-gap-2", form: form, layout: "vertical", disabled: isUpdatingAccount, autoComplete: "off", children: [jsx(Form.Item, { label: "Street address", name: "billingStreet", children: jsx(Input, {}) }), jsxs("div", { className: "bunny-flex bunny-gap-4", children: [jsx(Form.Item, { label: "City", name: "billingCity", className: "bunny-flex-1", children: jsx(Input, {}) }), jsx(Form.Item, { label: "Zipcode", name: "billingZip", className: "bunny-flex-1", children: jsx(Input, {}) })] }), jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-row bunny-pb-2' : 'bunny-flex-row'} bunny-gap-4`, children: [jsx("div", { className: "bunny-flex-1 bunny-w-1/2", children: jsx(Form.Item, { label: "State", name: "billingState", children: jsx(Input, {}) }) }), jsx("div", { className: "bunny-flex-1 bunny-w-1/2", children: jsx(Form.Item, { label: "Country", name: "billingCountry", children: jsx(Select, { className: "bunny-w-full", options: filteredCountryList, placeholder: "Select a country", popupMatchSelectWidth: false, showSearch: true, filterOption: (input, option) => {
30193
30247
  var _a, _b;
30194
30248
  return ((_a = option === null || option === void 0 ? void 0 : option.label) !== null && _a !== void 0 ? _a : '').toLowerCase().includes(input.toLowerCase()) ||
30195
30249
  ((_b = option === null || option === void 0 ? void 0 : option.value) !== null && _b !== void 0 ? _b : '').toLowerCase().includes(input.toLowerCase());
@@ -30214,7 +30268,7 @@ function BillingDetailsSection({ hidePaymentMethodForm, countryListFilter, }) {
30214
30268
  })) !== null && _c !== void 0 ? _c : [], popupRender: menu => (jsxs(Fragment, { children: [menu, jsx(AddContactButton, { onClick: () => {
30215
30269
  setContactFieldType('secondary');
30216
30270
  setIsAddContactModalOpen(true);
30217
- } })] })) }) }), jsx(Form.Item, { label: "Tax ID", name: "taxNumber", tooltip: "Tax ID will be printed on quotes and invoices below the account's address", rules: [{ required: false }], children: jsx(Input, {}) })] })] }), jsx(Button, { disabled: !isFormEdited || isUpdatingAccount || isLoading, className: "bunny-w-full bunny-mt-4", type: "primary", onClick: saveBillingDetails, children: "Save" })] }), jsx(AddContactModal, { open: isAddContactModalOpen, onClose: () => {
30271
+ } })] })) }) }), jsx(Form.Item, { label: "Tax ID", name: "taxNumber", tooltip: "Tax ID will be printed on quotes and invoices below the account's address", children: jsx(Input, {}) })] })] }), jsx(Button, { disabled: !isFormEdited || isUpdatingAccount || isLoading, className: "bunny-w-full bunny-mt-4", type: "primary", onClick: saveBillingDetails, children: "Save" })] }), jsx(AddContactModal, { open: isAddContactModalOpen, onClose: () => {
30218
30272
  setIsAddContactModalOpen(false);
30219
30273
  setContactFieldType(null);
30220
30274
  }, accountId: accountId, onContactCreated: handleContactCreated })] }));