@usethrottle/quotes 0.6.0 → 0.8.0
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.
- package/README.md +11 -1
- package/dist/index.cjs +93 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +83 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { CurrencyCode } from '@usethrottle/money';
|
|
2
|
+
import * as money from '@usethrottle/money';
|
|
3
|
+
export { money };
|
|
4
|
+
export { CURRENCIES, CurrencyCode, MoneyValue, UnknownCurrencyError, currencySymbol, isKnownCurrency, minorUnitsOf, moneyValue, parseMoney, toDecimalString, toMinor } from '@usethrottle/money';
|
|
1
5
|
import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
|
|
2
6
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
7
|
import { ReactNode } from 'react';
|
|
@@ -96,7 +100,7 @@ interface BuyerQuote {
|
|
|
96
100
|
quoteNumber: string;
|
|
97
101
|
status: BuyerQuoteStatus;
|
|
98
102
|
buyerReference: string | null;
|
|
99
|
-
currency:
|
|
103
|
+
currency: CurrencyCode;
|
|
100
104
|
expiresAt: string | null;
|
|
101
105
|
currentRevision: QuoteRevision | null;
|
|
102
106
|
revisionHistory: QuoteRevision[];
|
|
@@ -133,6 +137,8 @@ interface RequestFormConfig {
|
|
|
133
137
|
fields: {
|
|
134
138
|
companyName?: boolean;
|
|
135
139
|
phone?: boolean;
|
|
140
|
+
/** Show an optional shipping address section. */
|
|
141
|
+
shippingAddress?: boolean;
|
|
136
142
|
buyerReference?: boolean;
|
|
137
143
|
lineItems?: boolean;
|
|
138
144
|
targetPrice?: boolean;
|
|
@@ -174,6 +180,19 @@ interface SubmitQuoteRequestInput {
|
|
|
174
180
|
companyName?: string | null;
|
|
175
181
|
phone?: string | null;
|
|
176
182
|
buyerReference?: string | null;
|
|
183
|
+
/**
|
|
184
|
+
* Optional. All blank = no address; otherwise `addressLine1`, `city` and a
|
|
185
|
+
* 2-letter `countryCode` are required. Stored on the quote and prefilled
|
|
186
|
+
* into checkout when the buyer accepts.
|
|
187
|
+
*/
|
|
188
|
+
shippingAddress?: {
|
|
189
|
+
addressLine1?: string | null;
|
|
190
|
+
addressLine2?: string | null;
|
|
191
|
+
city?: string | null;
|
|
192
|
+
stateProvince?: string | null;
|
|
193
|
+
postalCode?: string | null;
|
|
194
|
+
countryCode?: string | null;
|
|
195
|
+
} | null;
|
|
177
196
|
/** Honeypot — leave empty. The component wires this for you. */
|
|
178
197
|
website?: string | null;
|
|
179
198
|
/** Client mount time in ms; the API enforces a minimum fill duration. */
|
|
@@ -268,7 +287,16 @@ declare class QuotesClient {
|
|
|
268
287
|
}>;
|
|
269
288
|
}
|
|
270
289
|
declare function createQuotesClient(opts?: QuotesClientOptions): QuotesClient;
|
|
271
|
-
/**
|
|
290
|
+
/**
|
|
291
|
+
* Minor units → a display string, e.g. (104000, 'USD') → "$1,040.00".
|
|
292
|
+
*
|
|
293
|
+
* Digits are en-US on every surface and runtime, so `locale` no longer changes
|
|
294
|
+
* them (it is kept so existing calls compile); the exponent is the currency's
|
|
295
|
+
* own (JPY has none, KWD has three).
|
|
296
|
+
*
|
|
297
|
+
* @deprecated Use `money.formatMoney` from this package or `formatMoney` from
|
|
298
|
+
* `@usethrottle/money`.
|
|
299
|
+
*/
|
|
272
300
|
declare function formatMoney(minorUnits: number, currency: string, locale?: string): string;
|
|
273
301
|
/**
|
|
274
302
|
* Scale a line's quoted tax/discount to an edited quantity.
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { formatMoney as formatMinor } from "@usethrottle/money";
|
|
3
|
+
|
|
1
4
|
// src/errors.ts
|
|
2
5
|
import { ThrottleError } from "@usethrottle/errors";
|
|
3
6
|
var ThrottleQuotesError = class extends ThrottleError {
|
|
@@ -151,7 +154,8 @@ function createQuotesClient(opts = {}) {
|
|
|
151
154
|
return new QuotesClient(opts);
|
|
152
155
|
}
|
|
153
156
|
function formatMoney(minorUnits, currency, locale) {
|
|
154
|
-
|
|
157
|
+
void locale;
|
|
158
|
+
return formatMinor(minorUnits, currency);
|
|
155
159
|
}
|
|
156
160
|
function scaleLineCharges(item, quantity) {
|
|
157
161
|
const base = item.quantity;
|
|
@@ -563,12 +567,12 @@ function cadenceNoun(cadence) {
|
|
|
563
567
|
}
|
|
564
568
|
return cadence.interval;
|
|
565
569
|
}
|
|
566
|
-
function recurringTermsLabel(terms, price,
|
|
570
|
+
function recurringTermsLabel(terms, price, money2) {
|
|
567
571
|
const quantity = price.quantity ?? 1;
|
|
568
572
|
if (terms.schedule && terms.schedule.length > 0) {
|
|
569
|
-
return `${
|
|
573
|
+
return `${money2(scheduleUnitTotal(terms.schedule) * quantity)} total \xB7 ${terms.schedule.length} payments`;
|
|
570
574
|
}
|
|
571
|
-
const each =
|
|
575
|
+
const each = money2(price.unitPrice * quantity);
|
|
572
576
|
const noun = cadenceNoun(terms);
|
|
573
577
|
const trialDays = terms.trialDays ?? 0;
|
|
574
578
|
if (trialDays > 0) return `Free for ${trialDays} day${trialDays === 1 ? "" : "s"}, then ${each} / ${noun}`;
|
|
@@ -576,6 +580,7 @@ function recurringTermsLabel(terms, price, money) {
|
|
|
576
580
|
}
|
|
577
581
|
|
|
578
582
|
// src/QuoteView.tsx
|
|
583
|
+
import { formatMoney as formatMoney2 } from "@usethrottle/money";
|
|
579
584
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
580
585
|
var row = { display: "flex", justifyContent: "space-between", gap: 16, padding: "8px 0" };
|
|
581
586
|
var muted = { color: "#666", fontSize: 13 };
|
|
@@ -657,10 +662,10 @@ function QuoteView({ token, options, onCheckout, loadingFallback, className }) {
|
|
|
657
662
|
item.description ? /* @__PURE__ */ jsx("div", { style: muted, children: item.description }) : null,
|
|
658
663
|
item.recurring ? /* @__PURE__ */ jsxs("div", { style: muted, children: [
|
|
659
664
|
"Subscription \xB7 ",
|
|
660
|
-
recurringTermsLabel(item.recurring, { unitPrice: item.unitPrice, quantity: state.quantity }, (m) =>
|
|
665
|
+
recurringTermsLabel(item.recurring, { unitPrice: item.unitPrice, quantity: state.quantity }, (m) => formatMoney2(m, currency))
|
|
661
666
|
] }) : null
|
|
662
667
|
] }),
|
|
663
|
-
/* @__PURE__ */ jsx("td", { align: "right", children:
|
|
668
|
+
/* @__PURE__ */ jsx("td", { align: "right", children: formatMoney2(item.unitPrice, currency) }),
|
|
664
669
|
/* @__PURE__ */ jsx("td", { align: "right", children: item.qtyEditable && canAct ? /* @__PURE__ */ jsx(
|
|
665
670
|
"input",
|
|
666
671
|
{
|
|
@@ -673,21 +678,21 @@ function QuoteView({ token, options, onCheckout, loadingFallback, className }) {
|
|
|
673
678
|
style: { width: 64 }
|
|
674
679
|
}
|
|
675
680
|
) : state.quantity }),
|
|
676
|
-
/* @__PURE__ */ jsx("td", { align: "right", children:
|
|
681
|
+
/* @__PURE__ */ jsx("td", { align: "right", children: formatMoney2(included ? lineDueAtAcceptance(item, state.quantity) : 0, currency) })
|
|
677
682
|
] }, item.id);
|
|
678
683
|
}) })
|
|
679
684
|
] }) : null,
|
|
680
685
|
rev ? /* @__PURE__ */ jsxs("section", { children: [
|
|
681
686
|
/* @__PURE__ */ jsxs("div", { style: row, children: [
|
|
682
687
|
/* @__PURE__ */ jsx("strong", { children: recurringKept.length > 0 ? "Due at acceptance" : "Total" }),
|
|
683
|
-
/* @__PURE__ */ jsx("strong", { children:
|
|
688
|
+
/* @__PURE__ */ jsx("strong", { children: formatMoney2(q.total, currency) })
|
|
684
689
|
] }),
|
|
685
690
|
recurringKept.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
686
691
|
/* @__PURE__ */ jsx("p", { style: muted, children: "Recurring after" }),
|
|
687
692
|
recurringKept.map((i) => /* @__PURE__ */ jsxs("p", { style: muted, children: [
|
|
688
693
|
i.name,
|
|
689
694
|
": ",
|
|
690
|
-
recurringTermsLabel(i.recurring, { unitPrice: i.unitPrice, quantity: q.selections[i.id]?.quantity ?? i.quantity }, (m) =>
|
|
695
|
+
recurringTermsLabel(i.recurring, { unitPrice: i.unitPrice, quantity: q.selections[i.id]?.quantity ?? i.quantity }, (m) => formatMoney2(m, currency))
|
|
691
696
|
] }, i.id))
|
|
692
697
|
] }) : null,
|
|
693
698
|
/* @__PURE__ */ jsx("p", { style: muted, children: termsLabel(rev.paymentTerms, rev.depositAmount, currency) }),
|
|
@@ -751,7 +756,7 @@ function QuoteView({ token, options, onCheckout, loadingFallback, className }) {
|
|
|
751
756
|
"Revision ",
|
|
752
757
|
r.revisionNumber,
|
|
753
758
|
" \u2014 ",
|
|
754
|
-
|
|
759
|
+
formatMoney2(r.total, currency),
|
|
755
760
|
r.changeSummary ? ` \xB7 ${r.changeSummary}` : ""
|
|
756
761
|
] }, r.id)) })
|
|
757
762
|
] }) : null,
|
|
@@ -815,7 +820,7 @@ function statusLabel(status) {
|
|
|
815
820
|
function termsLabel(terms, depositAmount, currency) {
|
|
816
821
|
if (terms.mode === "net_terms") return `Payment terms: Net ${terms.netN}`;
|
|
817
822
|
if (terms.mode === "deposit_balance") {
|
|
818
|
-
const dep = depositAmount != null ?
|
|
823
|
+
const dep = depositAmount != null ? formatMoney2(depositAmount, currency) : "a deposit";
|
|
819
824
|
return `${dep} due today, balance Net ${terms.balanceNetN}`;
|
|
820
825
|
}
|
|
821
826
|
return "Payment in full";
|
|
@@ -852,6 +857,12 @@ function QuoteRequestForm({
|
|
|
852
857
|
companyName: "",
|
|
853
858
|
phone: "",
|
|
854
859
|
buyerReference: "",
|
|
860
|
+
addressLine1: "",
|
|
861
|
+
addressLine2: "",
|
|
862
|
+
city: "",
|
|
863
|
+
stateProvince: "",
|
|
864
|
+
postalCode: "",
|
|
865
|
+
countryCode: "",
|
|
855
866
|
message: "",
|
|
856
867
|
website: ""
|
|
857
868
|
// honeypot
|
|
@@ -881,6 +892,16 @@ function QuoteRequestForm({
|
|
|
881
892
|
companyName: fields.companyName ? values.companyName || null : null,
|
|
882
893
|
phone: fields.phone ? values.phone || null : null,
|
|
883
894
|
buyerReference: fields.buyerReference ? values.buyerReference || null : null,
|
|
895
|
+
...fields.shippingAddress ? {
|
|
896
|
+
shippingAddress: {
|
|
897
|
+
addressLine1: values.addressLine1 || null,
|
|
898
|
+
addressLine2: values.addressLine2 || null,
|
|
899
|
+
city: values.city || null,
|
|
900
|
+
stateProvince: values.stateProvince || null,
|
|
901
|
+
postalCode: values.postalCode || null,
|
|
902
|
+
countryCode: values.countryCode || null
|
|
903
|
+
}
|
|
904
|
+
} : {},
|
|
884
905
|
website: values.website || null,
|
|
885
906
|
...turnstileToken ? { turnstileToken } : {}
|
|
886
907
|
}).then(() => onSubmitted?.()).catch(() => {
|
|
@@ -906,6 +927,33 @@ function QuoteRequestForm({
|
|
|
906
927
|
"Phone",
|
|
907
928
|
/* @__PURE__ */ jsx2("input", { value: values.phone, onChange: set("phone") })
|
|
908
929
|
] }) : null,
|
|
930
|
+
fields.shippingAddress ? /* @__PURE__ */ jsxs2("fieldset", { children: [
|
|
931
|
+
/* @__PURE__ */ jsx2("legend", { children: "Shipping address (optional)" }),
|
|
932
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
933
|
+
"Address line 1",
|
|
934
|
+
/* @__PURE__ */ jsx2("input", { value: values.addressLine1, onChange: set("addressLine1") })
|
|
935
|
+
] }),
|
|
936
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
937
|
+
"Address line 2",
|
|
938
|
+
/* @__PURE__ */ jsx2("input", { value: values.addressLine2, onChange: set("addressLine2") })
|
|
939
|
+
] }),
|
|
940
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
941
|
+
"City",
|
|
942
|
+
/* @__PURE__ */ jsx2("input", { value: values.city, onChange: set("city") })
|
|
943
|
+
] }),
|
|
944
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
945
|
+
"State / province",
|
|
946
|
+
/* @__PURE__ */ jsx2("input", { value: values.stateProvince, onChange: set("stateProvince") })
|
|
947
|
+
] }),
|
|
948
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
949
|
+
"Postal code",
|
|
950
|
+
/* @__PURE__ */ jsx2("input", { value: values.postalCode, onChange: set("postalCode") })
|
|
951
|
+
] }),
|
|
952
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
953
|
+
"Country code (e.g. US)",
|
|
954
|
+
/* @__PURE__ */ jsx2("input", { value: values.countryCode, onChange: set("countryCode"), maxLength: 2 })
|
|
955
|
+
] })
|
|
956
|
+
] }) : null,
|
|
909
957
|
fields.buyerReference ? /* @__PURE__ */ jsxs2("label", { children: [
|
|
910
958
|
"Your reference #",
|
|
911
959
|
/* @__PURE__ */ jsx2("input", { value: values.buyerReference, onChange: set("buyerReference") })
|
|
@@ -953,18 +1001,42 @@ function QuoteRequestForm({
|
|
|
953
1001
|
}
|
|
954
1002
|
);
|
|
955
1003
|
}
|
|
1004
|
+
|
|
1005
|
+
// src/index.tsx
|
|
1006
|
+
import * as money from "@usethrottle/money";
|
|
1007
|
+
import {
|
|
1008
|
+
currencySymbol,
|
|
1009
|
+
minorUnitsOf,
|
|
1010
|
+
toDecimalString,
|
|
1011
|
+
toMinor,
|
|
1012
|
+
parseMoney,
|
|
1013
|
+
moneyValue,
|
|
1014
|
+
CURRENCIES,
|
|
1015
|
+
isKnownCurrency,
|
|
1016
|
+
UnknownCurrencyError
|
|
1017
|
+
} from "@usethrottle/money";
|
|
956
1018
|
export {
|
|
1019
|
+
CURRENCIES,
|
|
957
1020
|
QuoteRequestForm,
|
|
958
1021
|
QuoteView,
|
|
959
1022
|
QuotesClient,
|
|
960
1023
|
ThrottleQuotesError,
|
|
1024
|
+
UnknownCurrencyError,
|
|
961
1025
|
computeSelectionTotal,
|
|
962
1026
|
createQuoteCart,
|
|
963
1027
|
createQuotesClient,
|
|
1028
|
+
currencySymbol,
|
|
964
1029
|
formatMoney,
|
|
965
1030
|
isFreeTrialLine,
|
|
1031
|
+
isKnownCurrency,
|
|
966
1032
|
lineDueAtAcceptance,
|
|
1033
|
+
minorUnitsOf,
|
|
1034
|
+
money,
|
|
1035
|
+
moneyValue,
|
|
1036
|
+
parseMoney,
|
|
967
1037
|
scaleLineCharges,
|
|
1038
|
+
toDecimalString,
|
|
1039
|
+
toMinor,
|
|
968
1040
|
useQuote,
|
|
969
1041
|
useQuoteCart,
|
|
970
1042
|
useQuoteRequestForm
|