@stackframe/react 2.8.78 → 2.8.80
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/dist/components/api-key-dialogs.d.ts +1 -1
- package/dist/components-page/account-settings/payments/payments-panel.d.ts.map +1 -1
- package/dist/components-page/account-settings/payments/payments-panel.js +3 -2
- package/dist/components-page/account-settings/payments/payments-panel.js.map +1 -1
- package/dist/components-page/oauth-callback.d.ts.map +1 -1
- package/dist/components-page/oauth-callback.js +4 -1
- package/dist/components-page/oauth-callback.js.map +1 -1
- package/dist/components-page/stack-handler-client.d.ts.map +1 -1
- package/dist/components-page/stack-handler-client.js +34 -8
- package/dist/components-page/stack-handler-client.js.map +1 -1
- package/dist/esm/components/api-key-dialogs.d.ts +1 -1
- package/dist/esm/components-page/account-settings/payments/payments-panel.d.ts.map +1 -1
- package/dist/esm/components-page/account-settings/payments/payments-panel.js +3 -2
- package/dist/esm/components-page/account-settings/payments/payments-panel.js.map +1 -1
- package/dist/esm/components-page/oauth-callback.d.ts.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +4 -1
- package/dist/esm/components-page/oauth-callback.js.map +1 -1
- package/dist/esm/components-page/stack-handler-client.d.ts.map +1 -1
- package/dist/esm/components-page/stack-handler-client.js +34 -8
- package/dist/esm/components-page/stack-handler-client.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/lib/auth.d.ts.map +1 -1
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/env.d.ts +36 -0
- package/dist/esm/lib/env.d.ts.map +1 -0
- package/dist/esm/lib/env.js +85 -0
- package/dist/esm/lib/env.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts +2 -2
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts +19 -4
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +133 -20
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.d.ts +9 -7
- package/dist/esm/lib/stack-app/apps/implementations/common.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +17 -36
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js +30 -13
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js +187 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts +7 -3
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/stack-app/common.d.ts +17 -20
- package/dist/esm/lib/stack-app/common.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/common.js.map +1 -1
- package/dist/esm/lib/stack-app/index.d.ts +2 -2
- package/dist/esm/lib/stack-app/url-targets.d.ts +29 -0
- package/dist/esm/lib/stack-app/url-targets.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/url-targets.js +317 -0
- package/dist/esm/lib/stack-app/url-targets.js.map +1 -0
- package/dist/esm/lib/stack-app/url-targets.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/url-targets.test.js +135 -0
- package/dist/esm/lib/stack-app/url-targets.test.js.map +1 -0
- package/dist/esm/providers/stack-provider-client.js +1 -1
- package/dist/generated/quetzal-translations.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/env.d.ts +36 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +87 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts +3 -3
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts +19 -4
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +132 -19
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.d.ts +9 -7
- package/dist/lib/stack-app/apps/implementations/common.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +17 -36
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/event-tracker.js +30 -13
- package/dist/lib/stack-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js +191 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/client-app.d.ts +7 -3
- package/dist/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/stack-app/common.d.ts +17 -20
- package/dist/lib/stack-app/common.d.ts.map +1 -1
- package/dist/lib/stack-app/common.js.map +1 -1
- package/dist/lib/stack-app/index.d.ts +2 -2
- package/dist/lib/stack-app/url-targets.d.ts +29 -0
- package/dist/lib/stack-app/url-targets.d.ts.map +1 -0
- package/dist/lib/stack-app/url-targets.js +324 -0
- package/dist/lib/stack-app/url-targets.js.map +1 -0
- package/dist/lib/stack-app/url-targets.test.d.ts +1 -0
- package/dist/lib/stack-app/url-targets.test.js +135 -0
- package/dist/lib/stack-app/url-targets.test.js.map +1 -0
- package/dist/providers/stack-provider-client.js +1 -1
- package/package.json +3 -3
|
@@ -4,7 +4,7 @@ import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
|
4
4
|
//#region src/components/api-key-dialogs.d.ts
|
|
5
5
|
declare const neverInMs: number;
|
|
6
6
|
declare const expiresInOptions: {
|
|
7
|
-
readonly [x: number]: "1 day" | "7 days" | "30 days" | "90 days" | "1 year"
|
|
7
|
+
readonly [x: number]: "Never" | "1 day" | "7 days" | "30 days" | "90 days" | "1 year";
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* Dialog for creating a new API key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAoBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -13,6 +13,7 @@ let ___section_js = require("../section.js");
|
|
|
13
13
|
let _________index_js = require("../../../index.js");
|
|
14
14
|
let _stripe_react_stripe_js = require("@stripe/react-stripe-js");
|
|
15
15
|
let _stripe_stripe_js = require("@stripe/stripe-js");
|
|
16
|
+
let _________lib_env_js = require("../../../lib/env.js");
|
|
16
17
|
|
|
17
18
|
//#region src/components-page/account-settings/payments/payments-panel.tsx
|
|
18
19
|
function formatPaymentMethod(pm) {
|
|
@@ -191,7 +192,7 @@ function RealPaymentsPanel(props) {
|
|
|
191
192
|
const [switchToProductId, setSwitchToProductId] = (0, react.useState)(null);
|
|
192
193
|
const stripePromise = (0, react.useMemo)(() => {
|
|
193
194
|
if (!setupIntentStripeAccountId) return null;
|
|
194
|
-
const publishableKey =
|
|
195
|
+
const publishableKey = _________lib_env_js.envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
|
|
195
196
|
if (!publishableKey) return null;
|
|
196
197
|
return (0, _stripe_stripe_js.loadStripe)(publishableKey, { stripeAccount: setupIntentStripeAccountId });
|
|
197
198
|
}, [setupIntentStripeAccountId]);
|
|
@@ -204,7 +205,7 @@ function RealPaymentsPanel(props) {
|
|
|
204
205
|
});
|
|
205
206
|
return;
|
|
206
207
|
}
|
|
207
|
-
alert(`An unhandled error occurred. Please ${
|
|
208
|
+
alert(`An unhandled error occurred. Please ${_________lib_env_js.envVars.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
|
|
208
209
|
};
|
|
209
210
|
const openPaymentDialog = () => {
|
|
210
211
|
(0, _stackframe_stack_shared_dist_utils_promises.runAsynchronously)(async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments-panel.js","names":["Typography","CardElement","Button","Section","KnownErrors","ActionDialog","Skeleton","Elements","Result","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Separator","Table","TableHeader","TableRow","TableHead","TableBody","TableCell"],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionDialog, Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, Typography } from \"@stackframe/stack-ui\";\nimport { CardElement, Elements, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { useMemo, useState } from \"react\";\nimport { useStackApp } from \"../../..\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport type { CustomerInvoiceStatus, CustomerInvoicesList, CustomerInvoicesListOptions } from \"../../../lib/stack-app/customers\";\n\ntype PaymentMethodSummary = {\n id: string,\n brand: string | null,\n last4: string | null,\n exp_month: number | null,\n exp_year: number | null,\n} | null;\n\nfunction formatPaymentMethod(pm: NonNullable<PaymentMethodSummary>) {\n const details = [\n pm.brand ? pm.brand.toUpperCase() : null,\n pm.last4 ? `•••• ${pm.last4}` : null,\n pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null,\n ].filter(Boolean);\n return details.join(\" · \");\n}\n\nconst formatInvoiceStatus = (status: CustomerInvoiceStatus, t: (value: string) => string) => {\n if (!status) {\n return t(\"Unknown\");\n }\n switch (status) {\n case \"draft\": {\n return t(\"Draft\");\n }\n case \"open\": {\n return t(\"Open\");\n }\n case \"paid\": {\n return t(\"Paid\");\n }\n case \"uncollectible\": {\n return t(\"Uncollectible\");\n }\n case \"void\": {\n return t(\"Void\");\n }\n default: {\n return t(\"Unknown\");\n }\n }\n};\n\nconst formatInvoiceAmount = (amountTotal: number | null | undefined, t: (value: string) => string) => {\n if (typeof amountTotal !== \"number\" || Number.isNaN(amountTotal)) {\n return t(\"Unknown\");\n }\n const normalized = amountTotal / 100;\n const formatted = new Intl.NumberFormat(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(normalized);\n return `$${formatted}`;\n};\n\nconst formatInvoiceDate = (date: Date | null | undefined, t: (value: string) => string) => {\n if (!date || Number.isNaN(date.getTime())) {\n return t(\"Unknown\");\n }\n return new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(date);\n};\n\ntype CustomerBilling = {\n hasCustomer: boolean,\n defaultPaymentMethod: PaymentMethodSummary,\n};\n\ntype CustomerPaymentMethodSetupIntent = {\n clientSecret: string,\n stripeAccountId: string,\n};\n\ntype CustomerLike = {\n id: string,\n useBilling: () => CustomerBilling,\n useProducts: () => Array<{\n id: string | null,\n quantity: number,\n displayName: string,\n customerType: \"user\" | \"team\" | \"custom\",\n type: \"one_time\" | \"subscription\",\n switchOptions?: Array<{\n productId: string,\n displayName: string,\n prices: Record<string, { interval?: [number, \"day\" | \"week\" | \"month\" | \"year\"] }>,\n }>,\n subscription: null | {\n subscriptionId: string | null,\n currentPeriodEnd: Date | null,\n cancelAtPeriodEnd: boolean,\n isCancelable: boolean,\n },\n }>,\n useInvoices: (options?: CustomerInvoicesListOptions) => CustomerInvoicesList,\n createPaymentMethodSetupIntent: () => Promise<CustomerPaymentMethodSetupIntent>,\n setDefaultPaymentMethodFromSetupIntent: (setupIntentId: string) => Promise<PaymentMethodSummary>,\n switchSubscription: (options: { fromProductId: string, toProductId: string, priceId?: string, quantity?: number }) => Promise<void>,\n};\n\nfunction SetDefaultPaymentMethodForm(props: {\n clientSecret: string,\n onSetupIntentSucceeded: (setupIntentId: string) => Promise<void>,\n}) {\n const stripe = useStripe();\n const elements = useElements();\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const darkMode = \"color-scheme\" in document.documentElement.style && document.documentElement.style[\"color-scheme\"] === \"dark\";\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Typography className=\"font-medium\">Card details</Typography>\n <div className=\"rounded-md border border-input p-3\">\n <CardElement options={{ hidePostalCode: true, style: { base: { color: darkMode ? \"white\" : \"black\" } } }} />\n </div>\n </div>\n {errorMessage && (\n <Typography variant=\"secondary\" type=\"footnote\">\n {errorMessage}\n </Typography>\n )}\n <Button\n onClick={async () => {\n if (!stripe || !elements) {\n setErrorMessage(\"Stripe is still loading. Please try again.\");\n return;\n }\n const card = elements.getElement(CardElement);\n if (!card) {\n setErrorMessage(\"Card element not found.\");\n return;\n }\n\n const result = await stripe.confirmCardSetup(props.clientSecret, {\n payment_method: { card },\n });\n if (result.error) {\n setErrorMessage(result.error.message ?? \"Failed to save payment method.\");\n return;\n }\n if (!result.setupIntent.id) {\n setErrorMessage(\"No setup intent returned from Stripe.\");\n return;\n }\n await props.onSetupIntentSucceeded(result.setupIntent.id);\n }}\n >\n Save payment method\n </Button>\n </div>\n );\n}\n\nexport function PaymentsPanel(props: {\n title?: string,\n customer?: CustomerLike,\n customerType?: \"user\" | \"team\",\n mockMode?: boolean,\n}) {\n if (props.mockMode) {\n return <MockPaymentsPanel title={props.title} />;\n }\n if (!props.customer) {\n return null;\n }\n return <RealPaymentsPanel title={props.title} customer={props.customer} customerType={props.customerType ?? \"user\"} />;\n}\n\nfunction MockPaymentsPanel(props: { title?: string }) {\n const { t } = useTranslation();\n const defaultPaymentMethod: PaymentMethodSummary = {\n id: \"pm_mock\",\n brand: \"visa\",\n last4: \"4242\",\n exp_month: 12,\n exp_year: 2030,\n };\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n <Button disabled>\n {t(\"Update payment method\")}\n </Button>\n </Section>\n\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Pro\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Renews on\")} Jan 1, 2030</Typography>\n </div>\n <Button disabled variant=\"secondary\" color=\"neutral\">\n {t(\"Cancel subscription\")}\n </Button>\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Credits pack\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"One-time purchase\")}</Typography>\n </div>\n </div>\n </div>\n </Section>\n </div>\n );\n}\n\nfunction RealPaymentsPanel(props: { title?: string, customer: CustomerLike, customerType: \"user\" | \"team\" }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const billing = props.customer.useBilling();\n const defaultPaymentMethod = billing.defaultPaymentMethod;\n const products = props.customer.useProducts();\n const invoices = props.customer.useInvoices({ limit: 10 });\n const productsForCustomerType = products.filter(product => product.customerType === props.customerType);\n\n const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);\n const [setupIntentClientSecret, setSetupIntentClientSecret] = useState<string | null>(null);\n const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = useState<string | null>(null);\n const [cancelTarget, setCancelTarget] = useState<{ productId: string, subscriptionId?: string } | null>(null);\n const [switchFromProductId, setSwitchFromProductId] = useState<string | null>(null);\n const [switchToProductId, setSwitchToProductId] = useState<string | null>(null);\n\n const stripePromise = useMemo(() => {\n if (!setupIntentStripeAccountId) return null;\n const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;\n if (!publishableKey) return null;\n return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });\n }, [setupIntentStripeAccountId]);\n\n const handleAsyncError = (error: unknown) => {\n if (error instanceof KnownErrors.DefaultPaymentMethodRequired) {\n toast({\n title: t(\"No default payment method\"),\n description: t(\"Add a payment method before switching plans.\"),\n variant: \"destructive\",\n });\n return;\n }\n alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === \"development\" ? \"check the browser console for the full error.\" : \"report this to the developer.\"}\\n\\n${error}`);\n };\n\n const openPaymentDialog = () => {\n runAsynchronously(async () => {\n setPaymentDialogOpen(true);\n const res = await props.customer.createPaymentMethodSetupIntent();\n setSetupIntentClientSecret(res.clientSecret);\n setSetupIntentStripeAccountId(res.stripeAccountId);\n }, { onError: handleAsyncError });\n };\n\n const closePaymentDialog = () => {\n setPaymentDialogOpen(false);\n setSetupIntentClientSecret(null);\n setSetupIntentStripeAccountId(null);\n };\n\n const openSwitchDialog = (productId: string, firstOptionId: string | null) => {\n setSwitchFromProductId(productId);\n setSwitchToProductId(firstOptionId);\n };\n\n const closeSwitchDialog = () => {\n setSwitchFromProductId(null);\n setSwitchToProductId(null);\n };\n\n const switchSourceProduct = switchFromProductId\n ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null\n : null;\n const switchOptions = switchSourceProduct?.switchOptions ?? [];\n const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;\n const selectedPriceId = selectedSwitchOption ? (Object.keys(selectedSwitchOption.prices)[0] ?? null) : null;\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n\n {defaultPaymentMethod && (\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n\n <Button onClick={openPaymentDialog}>\n {t(\"Update payment method\")}\n </Button>\n\n <ActionDialog\n open={paymentDialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n closePaymentDialog();\n } else {\n setPaymentDialogOpen(true);\n }\n }}\n title={t(\"Update payment method\")}\n >\n {!setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : (\n <Elements\n stripe={stripePromise}\n options={{\n clientSecret: setupIntentClientSecret,\n }}\n >\n <SetDefaultPaymentMethodForm\n clientSecret={setupIntentClientSecret}\n onSetupIntentSucceeded={async (setupIntentId) => {\n await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);\n closePaymentDialog();\n }}\n />\n </Elements>\n )}\n </ActionDialog>\n </Section>\n )}\n\n {productsForCustomerType.length > 0 && (\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n {productsForCustomerType.map((product, index) => {\n const quantitySuffix = product.quantity !== 1 ? ` ×${product.quantity}` : \"\";\n const isSubscription = product.type === \"subscription\";\n const isCancelable = isSubscription && !!product.subscription?.isCancelable;\n const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;\n const renewsAt = isSubscription ? (product.subscription?.currentPeriodEnd ?? null) : null;\n const subtitle =\n product.type === \"one_time\"\n ? t(\"One-time purchase\")\n : renewsAt\n ? `${t(\"Renews on\")} ${new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(renewsAt)}`\n : t(\"Subscription\");\n\n return (\n <div key={product.id ?? `${product.displayName}-${index}`} className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{product.displayName}{quantitySuffix}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{subtitle}</Typography>\n </div>\n\n <div className=\"flex flex-col items-end gap-2\">\n {canSwitchPlans && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => openSwitchDialog(product.id!, product.switchOptions?.[0]?.productId ?? null)}\n >\n {t(\"Change plan\")}\n </Button>\n )}\n {isCancelable && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => setCancelTarget({ productId: product.id ?? \"_inline\", subscriptionId: product.subscription?.subscriptionId ?? undefined })}\n >\n {t(\"Cancel subscription\")}\n </Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n <ActionDialog\n open={cancelTarget !== null}\n onOpenChange={(open) => {\n if (!open) setCancelTarget(null);\n }}\n title={t(\"Cancel subscription\")}\n description={t(\"Canceling will stop future renewals for this subscription.\")}\n danger\n cancelButton\n okButton={{\n label: t(\"Cancel subscription\"),\n onClick: async () => {\n if (!cancelTarget) return;\n const { productId, subscriptionId } = cancelTarget;\n if (props.customerType === \"team\") {\n await stackApp.cancelSubscription({ teamId: props.customer.id, productId, subscriptionId });\n } else {\n await stackApp.cancelSubscription({ productId, subscriptionId });\n }\n setCancelTarget(null);\n },\n }}\n />\n\n <ActionDialog\n open={switchFromProductId !== null}\n onOpenChange={(open) => {\n if (!open) closeSwitchDialog();\n }}\n title={t(\"Change plan\")}\n description={t(\"Select a new plan from the same product line.\")}\n cancelButton\n okButton={{\n label: t(\"Switch plan\"),\n onClick: async () => {\n const fromProductId = switchFromProductId;\n const toProductId = switchToProductId;\n if (!fromProductId || !toProductId) return;\n if (!selectedPriceId) return;\n const result = await Result.fromThrowingAsync(() => props.customer.switchSubscription({\n fromProductId,\n toProductId,\n priceId: selectedPriceId,\n }));\n if (result.status === \"error\") {\n handleAsyncError(result.error);\n return \"prevent-close\";\n }\n closeSwitchDialog();\n },\n props: {\n disabled: !switchFromProductId || !switchToProductId || !selectedPriceId,\n },\n }}\n >\n <div className=\"space-y-2\">\n {switchOptions.length === 0 ? (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"No other plans available for this subscription.\")}\n </Typography>\n ) : (\n <>\n <Typography type=\"footnote\">{t(\"Choose a plan\")}</Typography>\n <Select\n value={switchToProductId ?? undefined}\n onValueChange={(value) => setSwitchToProductId(value || null)}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder={t(\"Choose a plan\")} />\n </SelectTrigger>\n <SelectContent>\n {switchOptions.map((option: NonNullable<typeof switchOptions>[number]) => (\n <SelectItem key={option.productId} value={option.productId}>\n {option.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )}\n </div>\n </ActionDialog>\n </Section>\n )\n }\n {invoices.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Typography className=\"font-medium\">{t(\"Invoices\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Review past invoices and receipts.\")}</Typography>\n </div>\n <div className=\"border rounded-md\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[140px]\">{t(\"Date\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Status\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Amount\")}</TableHead>\n <TableHead className=\"w-[120px] text-right\">{t(\"Invoice\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice, index) => {\n const createdAtTime = invoice.createdAt.getTime();\n const invoiceKey = Number.isNaN(createdAtTime) ? `invoice-${index}` : `invoice-${createdAtTime}-${index}`;\n return (\n <TableRow key={invoiceKey}>\n <TableCell>\n <Typography>{formatInvoiceDate(invoice.createdAt, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceStatus(invoice.status, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceAmount(invoice.amountTotal, t)}</Typography>\n </TableCell>\n <TableCell align=\"right\">\n {invoice.hostedInvoiceUrl ? (\n <Button asChild variant=\"secondary\" color=\"neutral\" size=\"sm\">\n <a href={invoice.hostedInvoiceUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"View\")}\n </a>\n </Button>\n ) : (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"Unavailable\")}\n </Typography>\n )}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n </>\n )}\n </div >\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"payments-panel.js","names":["Typography","CardElement","Button","Section","envVars","KnownErrors","ActionDialog","Skeleton","Elements","Result","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Separator","Table","TableHeader","TableRow","TableHead","TableBody","TableCell"],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionDialog, Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, Typography } from \"@stackframe/stack-ui\";\nimport { CardElement, Elements, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { useMemo, useState } from \"react\";\nimport { useStackApp } from \"../../..\";\nimport { envVars } from \"../../../lib/env\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport type { CustomerInvoiceStatus, CustomerInvoicesList, CustomerInvoicesListOptions } from \"../../../lib/stack-app/customers\";\n\ntype PaymentMethodSummary = {\n id: string,\n brand: string | null,\n last4: string | null,\n exp_month: number | null,\n exp_year: number | null,\n} | null;\n\nfunction formatPaymentMethod(pm: NonNullable<PaymentMethodSummary>) {\n const details = [\n pm.brand ? pm.brand.toUpperCase() : null,\n pm.last4 ? `•••• ${pm.last4}` : null,\n pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null,\n ].filter(Boolean);\n return details.join(\" · \");\n}\n\nconst formatInvoiceStatus = (status: CustomerInvoiceStatus, t: (value: string) => string) => {\n if (!status) {\n return t(\"Unknown\");\n }\n switch (status) {\n case \"draft\": {\n return t(\"Draft\");\n }\n case \"open\": {\n return t(\"Open\");\n }\n case \"paid\": {\n return t(\"Paid\");\n }\n case \"uncollectible\": {\n return t(\"Uncollectible\");\n }\n case \"void\": {\n return t(\"Void\");\n }\n default: {\n return t(\"Unknown\");\n }\n }\n};\n\nconst formatInvoiceAmount = (amountTotal: number | null | undefined, t: (value: string) => string) => {\n if (typeof amountTotal !== \"number\" || Number.isNaN(amountTotal)) {\n return t(\"Unknown\");\n }\n const normalized = amountTotal / 100;\n const formatted = new Intl.NumberFormat(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(normalized);\n return `$${formatted}`;\n};\n\nconst formatInvoiceDate = (date: Date | null | undefined, t: (value: string) => string) => {\n if (!date || Number.isNaN(date.getTime())) {\n return t(\"Unknown\");\n }\n return new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(date);\n};\n\ntype CustomerBilling = {\n hasCustomer: boolean,\n defaultPaymentMethod: PaymentMethodSummary,\n};\n\ntype CustomerPaymentMethodSetupIntent = {\n clientSecret: string,\n stripeAccountId: string,\n};\n\ntype CustomerLike = {\n id: string,\n useBilling: () => CustomerBilling,\n useProducts: () => Array<{\n id: string | null,\n quantity: number,\n displayName: string,\n customerType: \"user\" | \"team\" | \"custom\",\n type: \"one_time\" | \"subscription\",\n switchOptions?: Array<{\n productId: string,\n displayName: string,\n prices: Record<string, { interval?: [number, \"day\" | \"week\" | \"month\" | \"year\"] }>,\n }>,\n subscription: null | {\n subscriptionId: string | null,\n currentPeriodEnd: Date | null,\n cancelAtPeriodEnd: boolean,\n isCancelable: boolean,\n },\n }>,\n useInvoices: (options?: CustomerInvoicesListOptions) => CustomerInvoicesList,\n createPaymentMethodSetupIntent: () => Promise<CustomerPaymentMethodSetupIntent>,\n setDefaultPaymentMethodFromSetupIntent: (setupIntentId: string) => Promise<PaymentMethodSummary>,\n switchSubscription: (options: { fromProductId: string, toProductId: string, priceId?: string, quantity?: number }) => Promise<void>,\n};\n\nfunction SetDefaultPaymentMethodForm(props: {\n clientSecret: string,\n onSetupIntentSucceeded: (setupIntentId: string) => Promise<void>,\n}) {\n const stripe = useStripe();\n const elements = useElements();\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const darkMode = \"color-scheme\" in document.documentElement.style && document.documentElement.style[\"color-scheme\"] === \"dark\";\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Typography className=\"font-medium\">Card details</Typography>\n <div className=\"rounded-md border border-input p-3\">\n <CardElement options={{ hidePostalCode: true, style: { base: { color: darkMode ? \"white\" : \"black\" } } }} />\n </div>\n </div>\n {errorMessage && (\n <Typography variant=\"secondary\" type=\"footnote\">\n {errorMessage}\n </Typography>\n )}\n <Button\n onClick={async () => {\n if (!stripe || !elements) {\n setErrorMessage(\"Stripe is still loading. Please try again.\");\n return;\n }\n const card = elements.getElement(CardElement);\n if (!card) {\n setErrorMessage(\"Card element not found.\");\n return;\n }\n\n const result = await stripe.confirmCardSetup(props.clientSecret, {\n payment_method: { card },\n });\n if (result.error) {\n setErrorMessage(result.error.message ?? \"Failed to save payment method.\");\n return;\n }\n if (!result.setupIntent.id) {\n setErrorMessage(\"No setup intent returned from Stripe.\");\n return;\n }\n await props.onSetupIntentSucceeded(result.setupIntent.id);\n }}\n >\n Save payment method\n </Button>\n </div>\n );\n}\n\nexport function PaymentsPanel(props: {\n title?: string,\n customer?: CustomerLike,\n customerType?: \"user\" | \"team\",\n mockMode?: boolean,\n}) {\n if (props.mockMode) {\n return <MockPaymentsPanel title={props.title} />;\n }\n if (!props.customer) {\n return null;\n }\n return <RealPaymentsPanel title={props.title} customer={props.customer} customerType={props.customerType ?? \"user\"} />;\n}\n\nfunction MockPaymentsPanel(props: { title?: string }) {\n const { t } = useTranslation();\n const defaultPaymentMethod: PaymentMethodSummary = {\n id: \"pm_mock\",\n brand: \"visa\",\n last4: \"4242\",\n exp_month: 12,\n exp_year: 2030,\n };\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n <Button disabled>\n {t(\"Update payment method\")}\n </Button>\n </Section>\n\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Pro\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Renews on\")} Jan 1, 2030</Typography>\n </div>\n <Button disabled variant=\"secondary\" color=\"neutral\">\n {t(\"Cancel subscription\")}\n </Button>\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Credits pack\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"One-time purchase\")}</Typography>\n </div>\n </div>\n </div>\n </Section>\n </div>\n );\n}\n\nfunction RealPaymentsPanel(props: { title?: string, customer: CustomerLike, customerType: \"user\" | \"team\" }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const billing = props.customer.useBilling();\n const defaultPaymentMethod = billing.defaultPaymentMethod;\n const products = props.customer.useProducts();\n const invoices = props.customer.useInvoices({ limit: 10 });\n const productsForCustomerType = products.filter(product => product.customerType === props.customerType);\n\n const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);\n const [setupIntentClientSecret, setSetupIntentClientSecret] = useState<string | null>(null);\n const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = useState<string | null>(null);\n const [cancelTarget, setCancelTarget] = useState<{ productId: string, subscriptionId?: string } | null>(null);\n const [switchFromProductId, setSwitchFromProductId] = useState<string | null>(null);\n const [switchToProductId, setSwitchToProductId] = useState<string | null>(null);\n\n const stripePromise = useMemo(() => {\n if (!setupIntentStripeAccountId) return null;\n const publishableKey = envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;\n if (!publishableKey) return null;\n return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });\n }, [setupIntentStripeAccountId]);\n\n const handleAsyncError = (error: unknown) => {\n if (error instanceof KnownErrors.DefaultPaymentMethodRequired) {\n toast({\n title: t(\"No default payment method\"),\n description: t(\"Add a payment method before switching plans.\"),\n variant: \"destructive\",\n });\n return;\n }\n alert(`An unhandled error occurred. Please ${envVars.NODE_ENV === \"development\" ? \"check the browser console for the full error.\" : \"report this to the developer.\"}\\n\\n${error}`);\n };\n\n const openPaymentDialog = () => {\n runAsynchronously(async () => {\n setPaymentDialogOpen(true);\n const res = await props.customer.createPaymentMethodSetupIntent();\n setSetupIntentClientSecret(res.clientSecret);\n setSetupIntentStripeAccountId(res.stripeAccountId);\n }, { onError: handleAsyncError });\n };\n\n const closePaymentDialog = () => {\n setPaymentDialogOpen(false);\n setSetupIntentClientSecret(null);\n setSetupIntentStripeAccountId(null);\n };\n\n const openSwitchDialog = (productId: string, firstOptionId: string | null) => {\n setSwitchFromProductId(productId);\n setSwitchToProductId(firstOptionId);\n };\n\n const closeSwitchDialog = () => {\n setSwitchFromProductId(null);\n setSwitchToProductId(null);\n };\n\n const switchSourceProduct = switchFromProductId\n ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null\n : null;\n const switchOptions = switchSourceProduct?.switchOptions ?? [];\n const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;\n const selectedPriceId = selectedSwitchOption ? (Object.keys(selectedSwitchOption.prices)[0] ?? null) : null;\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n\n {defaultPaymentMethod && (\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n\n <Button onClick={openPaymentDialog}>\n {t(\"Update payment method\")}\n </Button>\n\n <ActionDialog\n open={paymentDialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n closePaymentDialog();\n } else {\n setPaymentDialogOpen(true);\n }\n }}\n title={t(\"Update payment method\")}\n >\n {!setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : (\n <Elements\n stripe={stripePromise}\n options={{\n clientSecret: setupIntentClientSecret,\n }}\n >\n <SetDefaultPaymentMethodForm\n clientSecret={setupIntentClientSecret}\n onSetupIntentSucceeded={async (setupIntentId) => {\n await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);\n closePaymentDialog();\n }}\n />\n </Elements>\n )}\n </ActionDialog>\n </Section>\n )}\n\n {productsForCustomerType.length > 0 && (\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n {productsForCustomerType.map((product, index) => {\n const quantitySuffix = product.quantity !== 1 ? ` ×${product.quantity}` : \"\";\n const isSubscription = product.type === \"subscription\";\n const isCancelable = isSubscription && !!product.subscription?.isCancelable;\n const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;\n const renewsAt = isSubscription ? (product.subscription?.currentPeriodEnd ?? null) : null;\n const subtitle =\n product.type === \"one_time\"\n ? t(\"One-time purchase\")\n : renewsAt\n ? `${t(\"Renews on\")} ${new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(renewsAt)}`\n : t(\"Subscription\");\n\n return (\n <div key={product.id ?? `${product.displayName}-${index}`} className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{product.displayName}{quantitySuffix}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{subtitle}</Typography>\n </div>\n\n <div className=\"flex flex-col items-end gap-2\">\n {canSwitchPlans && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => openSwitchDialog(product.id!, product.switchOptions?.[0]?.productId ?? null)}\n >\n {t(\"Change plan\")}\n </Button>\n )}\n {isCancelable && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => setCancelTarget({ productId: product.id ?? \"_inline\", subscriptionId: product.subscription?.subscriptionId ?? undefined })}\n >\n {t(\"Cancel subscription\")}\n </Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n <ActionDialog\n open={cancelTarget !== null}\n onOpenChange={(open) => {\n if (!open) setCancelTarget(null);\n }}\n title={t(\"Cancel subscription\")}\n description={t(\"Canceling will stop future renewals for this subscription.\")}\n danger\n cancelButton\n okButton={{\n label: t(\"Cancel subscription\"),\n onClick: async () => {\n if (!cancelTarget) return;\n const { productId, subscriptionId } = cancelTarget;\n if (props.customerType === \"team\") {\n await stackApp.cancelSubscription({ teamId: props.customer.id, productId, subscriptionId });\n } else {\n await stackApp.cancelSubscription({ productId, subscriptionId });\n }\n setCancelTarget(null);\n },\n }}\n />\n\n <ActionDialog\n open={switchFromProductId !== null}\n onOpenChange={(open) => {\n if (!open) closeSwitchDialog();\n }}\n title={t(\"Change plan\")}\n description={t(\"Select a new plan from the same product line.\")}\n cancelButton\n okButton={{\n label: t(\"Switch plan\"),\n onClick: async () => {\n const fromProductId = switchFromProductId;\n const toProductId = switchToProductId;\n if (!fromProductId || !toProductId) return;\n if (!selectedPriceId) return;\n const result = await Result.fromThrowingAsync(() => props.customer.switchSubscription({\n fromProductId,\n toProductId,\n priceId: selectedPriceId,\n }));\n if (result.status === \"error\") {\n handleAsyncError(result.error);\n return \"prevent-close\";\n }\n closeSwitchDialog();\n },\n props: {\n disabled: !switchFromProductId || !switchToProductId || !selectedPriceId,\n },\n }}\n >\n <div className=\"space-y-2\">\n {switchOptions.length === 0 ? (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"No other plans available for this subscription.\")}\n </Typography>\n ) : (\n <>\n <Typography type=\"footnote\">{t(\"Choose a plan\")}</Typography>\n <Select\n value={switchToProductId ?? undefined}\n onValueChange={(value) => setSwitchToProductId(value || null)}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder={t(\"Choose a plan\")} />\n </SelectTrigger>\n <SelectContent>\n {switchOptions.map((option: NonNullable<typeof switchOptions>[number]) => (\n <SelectItem key={option.productId} value={option.productId}>\n {option.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )}\n </div>\n </ActionDialog>\n </Section>\n )\n }\n {invoices.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Typography className=\"font-medium\">{t(\"Invoices\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Review past invoices and receipts.\")}</Typography>\n </div>\n <div className=\"border rounded-md\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[140px]\">{t(\"Date\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Status\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Amount\")}</TableHead>\n <TableHead className=\"w-[120px] text-right\">{t(\"Invoice\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice, index) => {\n const createdAtTime = invoice.createdAt.getTime();\n const invoiceKey = Number.isNaN(createdAtTime) ? `invoice-${index}` : `invoice-${createdAtTime}-${index}`;\n return (\n <TableRow key={invoiceKey}>\n <TableCell>\n <Typography>{formatInvoiceDate(invoice.createdAt, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceStatus(invoice.status, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceAmount(invoice.amountTotal, t)}</Typography>\n </TableCell>\n <TableCell align=\"right\">\n {invoice.hostedInvoiceUrl ? (\n <Button asChild variant=\"secondary\" color=\"neutral\" size=\"sm\">\n <a href={invoice.hostedInvoiceUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"View\")}\n </a>\n </Button>\n ) : (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"Unavailable\")}\n </Typography>\n )}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n </>\n )}\n </div >\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-callback.d.ts","names":[],"sources":["../../src/components-page/oauth-callback.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"oauth-callback.d.ts","names":[],"sources":["../../src/components-page/oauth-callback.tsx"],"mappings":";;;iBAiBgB,aAAA,CAAA;EAAgB;AAAA;EAAc,QAAA;AAAA,IAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -11,6 +11,7 @@ let ___lib_translations_js = require("../lib/translations.js");
|
|
|
11
11
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
12
12
|
let ___components_elements_maybe_full_page_js = require("../components/elements/maybe-full-page.js");
|
|
13
13
|
let ___components_link_js = require("../components/link.js");
|
|
14
|
+
let ___lib_env_js = require("../lib/env.js");
|
|
14
15
|
|
|
15
16
|
//#region src/components-page/oauth-callback.tsx
|
|
16
17
|
function OAuthCallback({ fullPage }) {
|
|
@@ -23,13 +24,15 @@ function OAuthCallback({ fullPage }) {
|
|
|
23
24
|
if (called.current) return;
|
|
24
25
|
called.current = true;
|
|
25
26
|
let hasRedirected = false;
|
|
27
|
+
let callbackError = null;
|
|
26
28
|
try {
|
|
27
29
|
hasRedirected = await app.callOAuthCallback();
|
|
28
30
|
} catch (e) {
|
|
31
|
+
callbackError = e;
|
|
29
32
|
(0, _stackframe_stack_shared_dist_utils_errors.captureError)("<OAuthCallback />", e);
|
|
30
33
|
setError(e);
|
|
31
34
|
}
|
|
32
|
-
if (!hasRedirected && (
|
|
35
|
+
if (!hasRedirected && (callbackError == null || ___lib_env_js.envVars.NODE_ENV === "production")) await app.redirectToSignIn({ noRedirectBack: true });
|
|
33
36
|
}), []);
|
|
34
37
|
(0, react.useEffect)(() => {
|
|
35
38
|
setTimeout(() => setShowRedirectLink(true), 3e3);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-callback.js","names":["MaybeFullPage","Spinner","StyledLink"],"sources":["../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (
|
|
1
|
+
{"version":3,"file":"oauth-callback.js","names":["envVars","MaybeFullPage","Spinner","StyledLink"],"sources":["../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { envVars } from \"../lib/env\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n let callbackError: unknown = null;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n callbackError = e;\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (callbackError == null || envVars.NODE_ENV === \"production\")) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n }), []);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink className=\"whitespace-nowrap\" href={app.urls.home}>{t(\"click here\")}</StyledLink></p> : null}\n {error ? <div>\n <p>{t(\"Something went wrong while processing the OAuth callback:\")}</p>\n <pre>{JSON.stringify(error, null, 2)}</pre>\n <p>{t(\"This is most likely an error in Stack. Please report it.\")}</p>\n </div> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,EAAE,YAAoC;CAClE,MAAM,EAAE,kDAAsB;CAC9B,MAAM,oCAAmB;CACzB,MAAM,2BAAgB,MAAM;CAC5B,MAAM,CAAC,OAAO,gCAA8B,KAAK;CACjD,MAAM,CAAC,kBAAkB,2CAAgC,MAAM;AAE/D,gGAAkC,YAAY;AAC5C,MAAI,OAAO,QAAS;AACpB,SAAO,UAAU;EACjB,IAAI,gBAAgB;EACpB,IAAI,gBAAyB;AAC7B,MAAI;AACF,mBAAgB,MAAM,IAAI,mBAAmB;WACtC,GAAG;AACV,mBAAgB;AAChB,gEAAa,qBAAqB,EAAE;AACpC,YAAS,EAAE;;AAEb,MAAI,CAAC,kBAAkB,iBAAiB,QAAQA,sBAAQ,aAAa,cACnE,OAAM,IAAI,iBAAiB,EAAE,gBAAgB,MAAM,CAAC;GAEtD,EAAE,EAAE,CAAC;AAEP,4BAAgB;AACd,mBAAiB,oBAAoB,KAAK,EAAE,IAAK;IAChD,EAAE,CAAC;AAEN,QACE,2CAACC;EACC,UAAU,YAAY;EACtB,oBAAmB;YAEnB,4CAAC;GACC,wCACE,yFACA,WAAW,QAAQ,MACpB;;IAED,2CAAC;KAAI,WAAU;eACb,2CAACC,gCAAQ,MAAM,KAAM;MACjB;IACL,mBAAmB,4CAAC,kBAAG,EAAE,4CAA4C,EAAC,2CAACC;KAAW,WAAU;KAAoB,MAAM,IAAI,KAAK;eAAO,EAAE,aAAa;MAAc,IAAI,GAAG;IAC1K,QAAQ,4CAAC;KACR,2CAAC,iBAAG,EAAE,4DAA4D,GAAK;KACvE,2CAAC,mBAAK,KAAK,UAAU,OAAO,MAAM,EAAE,GAAO;KAC3C,2CAAC,iBAAG,EAAE,2DAA2D,GAAK;QAClE,GAAG;;IACL;GACQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-handler-client.d.ts","names":[],"sources":["../../src/components-page/stack-handler-client.tsx"],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"stack-handler-client.d.ts","names":[],"sources":["../../src/components-page/stack-handler-client.tsx"],"mappings":";;;;;;;;;;;;;;;;KA8BK,UAAA;EACH,MAAA,SAAe,MAAA;EACf,MAAA,SAAe,MAAA;EACf,iBAAA,SAA0B,iBAAA;EAC1B,aAAA,SAAsB,aAAA;EACtB,cAAA,SAAuB,cAAA;EACvB,OAAA,SAAgB,OAAA;EAChB,aAAA,SAAsB,aAAA;EACtB,iBAAA,SAA0B,iBAAA;EAC1B,cAAA,SAAuB,cAAA;EACvB,SAAA,SAAkB,SAAA;EAClB,eAAA,SAAwB,eAAA;EACxB,mBAAA,SAA4B,mBAAA;EAC5B,GAAA,SAAY,GAAA;EACZ,UAAA,SAAmB,UAAA;AAAA;AAAA,KAGhB,UAAA;EACH,MAAA,EAAQ,OAAA;IAAU,KAAA;EAAA;IAAwB,KAAA;EAAA;EAC1C,YAAA,EAAc,OAAA,CAAQ,MAAA,oBAA0B,MAAA;AAAA;AAAA,KA6BtC,gBAAA;EACV,QAAA;EACA,cAAA,iBACc,UAAA,IAAc,UAAA,CAAW,UAAA,CAAW,CAAA;AAAA;AAAA,iBA8IpC,kBAAA,CAAmB,KAAA,EAAO,gBAAA,GAAmB,OAAA,CAAQ,UAAA;EAAgB,QAAA;AAAA"}
|
|
@@ -10,6 +10,8 @@ let ___lib_hooks_js = require("../lib/hooks.js");
|
|
|
10
10
|
let ___components_message_cards_message_card_js = require("../components/message-cards/message-card.js");
|
|
11
11
|
let _stackframe_stack_shared_dist_utils_objects = require("@stackframe/stack-shared/dist/utils/objects");
|
|
12
12
|
let _stackframe_stack_shared_dist_utils_urls = require("@stackframe/stack-shared/dist/utils/urls");
|
|
13
|
+
let ___lib_stack_app_index_js = require("../lib/stack-app/index.js");
|
|
14
|
+
let ___lib_stack_app_url_targets_js = require("../lib/stack-app/url-targets.js");
|
|
13
15
|
let __account_settings_js = require("./account-settings.js");
|
|
14
16
|
let __cli_auth_confirm_js = require("./cli-auth-confirm.js");
|
|
15
17
|
let __email_verification_js = require("./email-verification.js");
|
|
@@ -40,13 +42,14 @@ const availablePaths = {
|
|
|
40
42
|
error: "error",
|
|
41
43
|
onboarding: "onboarding"
|
|
42
44
|
};
|
|
45
|
+
const placeholderOrigin = "http://example.com";
|
|
43
46
|
const pathAliases = {
|
|
44
47
|
...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),
|
|
45
48
|
"log-in": availablePaths.signIn,
|
|
46
49
|
"register": availablePaths.signUp
|
|
47
50
|
};
|
|
48
51
|
function renderComponent(props) {
|
|
49
|
-
const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, onNotFound, app } = props;
|
|
52
|
+
const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, getDefaultUnknownPathUrl, onNotFound, app } = props;
|
|
50
53
|
switch (path) {
|
|
51
54
|
case availablePaths.signIn:
|
|
52
55
|
redirectIfNotHandler?.("signIn");
|
|
@@ -133,34 +136,53 @@ function renderComponent(props) {
|
|
|
133
136
|
fullPage,
|
|
134
137
|
...filterUndefinedINU(componentProps?.Onboarding)
|
|
135
138
|
});
|
|
136
|
-
default:
|
|
139
|
+
default: {
|
|
137
140
|
if (Object.values(availablePaths).includes(path)) throw new _stackframe_stack_shared_dist_utils_errors.StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });
|
|
138
141
|
for (const [key, value] of Object.entries(pathAliases)) if (path.toLowerCase().replaceAll("-", "") === key.toLowerCase().replaceAll("-", "")) return { redirect: `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}` };
|
|
142
|
+
const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);
|
|
143
|
+
if (defaultUnknownPathUrl != null) {
|
|
144
|
+
const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, "http://example.com");
|
|
145
|
+
for (const [key, value] of Object.entries(searchParams)) defaultUnknownPathUrlObject.searchParams.set(key, value);
|
|
146
|
+
return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };
|
|
147
|
+
}
|
|
139
148
|
return onNotFound();
|
|
149
|
+
}
|
|
140
150
|
}
|
|
141
151
|
}
|
|
142
152
|
function StackHandlerClient(props) {
|
|
143
153
|
const stackApp = (0, ___lib_hooks_js.useStackApp)();
|
|
144
154
|
const currentLocation = props.location ?? window.location.pathname;
|
|
145
155
|
const searchParamsSource = new URLSearchParams(window.location.search);
|
|
146
|
-
const { path, searchParams } = (0, react.useMemo)(() => {
|
|
156
|
+
const { path, searchParams, handlerPath } = (0, react.useMemo)(() => {
|
|
147
157
|
const handlerPath = new URL(stackApp.urls.handler, "http://example.com").pathname;
|
|
148
158
|
return {
|
|
149
159
|
path: currentLocation.startsWith(handlerPath) ? currentLocation.slice(handlerPath.length).replace(/^\/+/, "") : currentLocation.replace(/^\/+/, ""),
|
|
150
|
-
searchParams: Object.fromEntries(searchParamsSource.entries())
|
|
160
|
+
searchParams: Object.fromEntries(searchParamsSource.entries()),
|
|
161
|
+
handlerPath
|
|
151
162
|
};
|
|
152
163
|
}, [
|
|
153
164
|
currentLocation,
|
|
154
165
|
searchParamsSource,
|
|
155
166
|
stackApp.urls.handler
|
|
156
167
|
]);
|
|
168
|
+
const getDefaultUnknownPathUrl = (unknownPath) => {
|
|
169
|
+
return (0, ___lib_stack_app_url_targets_js.resolveUnknownHandlerPathFallbackUrl)({
|
|
170
|
+
defaultTarget: stackApp[___lib_stack_app_index_js.stackAppInternalsSymbol].getConstructorOptions().urls?.default,
|
|
171
|
+
projectId: stackApp.projectId,
|
|
172
|
+
unknownPath
|
|
173
|
+
});
|
|
174
|
+
};
|
|
157
175
|
const redirectIfNotHandler = (name) => {
|
|
158
176
|
const url = stackApp.urls[name];
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
|
|
177
|
+
if (name === "oauthCallback" && searchParams.stack_cross_domain_auth === "1") return;
|
|
178
|
+
if ((0, ___lib_stack_app_url_targets_js.isLocalHandlerUrlTarget)({
|
|
179
|
+
targetUrl: url,
|
|
180
|
+
handlerPath,
|
|
181
|
+
currentOrigin: typeof window === "undefined" ? void 0 : window.location.origin
|
|
182
|
+
})) return;
|
|
183
|
+
const urlObj = new URL(url, placeholderOrigin);
|
|
162
184
|
for (const [key, value] of Object.entries(searchParams)) urlObj.searchParams.set(key, value);
|
|
163
|
-
window.location.href = (
|
|
185
|
+
window.location.href = toAbsoluteOrRelativeRedirectTarget(urlObj);
|
|
164
186
|
};
|
|
165
187
|
const result = renderComponent({
|
|
166
188
|
path,
|
|
@@ -168,6 +190,7 @@ function StackHandlerClient(props) {
|
|
|
168
190
|
fullPage: props.fullPage,
|
|
169
191
|
componentProps: props.componentProps,
|
|
170
192
|
redirectIfNotHandler,
|
|
193
|
+
getDefaultUnknownPathUrl,
|
|
171
194
|
onNotFound: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_message_cards_message_card_js.MessageCard, {
|
|
172
195
|
title: "Page does not exist",
|
|
173
196
|
fullPage: props.fullPage,
|
|
@@ -186,6 +209,9 @@ function StackHandlerClient(props) {
|
|
|
186
209
|
function filterUndefinedINU(value) {
|
|
187
210
|
return value === void 0 ? value : (0, _stackframe_stack_shared_dist_utils_objects.filterUndefined)(value);
|
|
188
211
|
}
|
|
212
|
+
function toAbsoluteOrRelativeRedirectTarget(url) {
|
|
213
|
+
return url.origin === "http://example.com" ? (0, _stackframe_stack_shared_dist_utils_urls.getRelativePart)(url) : url.toString();
|
|
214
|
+
}
|
|
189
215
|
|
|
190
216
|
//#endregion
|
|
191
217
|
exports.StackHandlerClient = StackHandlerClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","StackAssertionError","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\nimport { useMemo } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp } from \"../lib/stack-app\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n redirectIfNotHandler?: (name: keyof HandlerUrls) => void,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler?.('signIn');\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler?.('signUp');\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler?.('emailVerification');\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler?.('passwordReset');\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler?.('forgotPassword');\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler?.('signOut');\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler?.('oauthCallback');\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler?.('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler?.('teamInvitation');\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n redirectIfNotHandler?.('mfa');\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n redirectIfNotHandler?.('onboarding');\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const currentLocation = props.location ?? window.location.pathname;\n const searchParamsSource = new URLSearchParams(window.location.search);\n\n const { path, searchParams } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries())\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const redirectIfNotHandler = (name: keyof HandlerUrls) => {\n const url = stackApp.urls[name];\n const handlerUrl = stackApp.urls.handler;\n\n if (url !== handlerUrl && url.startsWith(handlerUrl + \"/\")) {\n return;\n }\n\n const urlObj = new URL(url, 'http://example.com');\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n window.location.href = getRelativePart(urlObj);\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n redirectIfNotHandler,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n if (result && 'redirect' in result) {\n window.location.href = result.redirect;\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","StackAssertionError","stackAppInternalsSymbol","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\nimport { useMemo } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n redirectIfNotHandler?: (name: keyof HandlerUrls) => void,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler?.('signIn');\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler?.('signUp');\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler?.('emailVerification');\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler?.('passwordReset');\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler?.('forgotPassword');\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler?.('signOut');\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler?.('oauthCallback');\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler?.('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler?.('teamInvitation');\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n redirectIfNotHandler?.('mfa');\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n redirectIfNotHandler?.('onboarding');\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const currentLocation = props.location ?? window.location.pathname;\n const searchParamsSource = new URLSearchParams(window.location.search);\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const redirectIfNotHandler = (name: keyof HandlerUrls) => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.stack_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return;\n }\n const isLocalHandlerTarget = isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: typeof window === \"undefined\" ? undefined : window.location.origin,\n });\n if (isLocalHandlerTarget) {\n return;\n }\n\n const urlObj = new URL(url, placeholderOrigin);\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n window.location.href = toAbsoluteOrRelativeRedirectTarget(urlObj);\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n redirectIfNotHandler,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n if (result && 'redirect' in result) {\n window.location.href = result.redirect;\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { ApiKey, ApiKeyCreationOptions, ApiKeyType } from "../lib/stack-app/api-
|
|
|
4
4
|
//#region src/components/api-key-dialogs.d.ts
|
|
5
5
|
declare const neverInMs: number;
|
|
6
6
|
declare const expiresInOptions: {
|
|
7
|
-
readonly [x: number]: "1 day" | "7 days" | "30 days" | "90 days" | "1 year"
|
|
7
|
+
readonly [x: number]: "Never" | "1 day" | "7 days" | "30 days" | "90 days" | "1 year";
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* Dialog for creating a new API key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAoBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -11,6 +11,7 @@ import { Section } from "../section.js";
|
|
|
11
11
|
import { useStackApp } from "../../../index.js";
|
|
12
12
|
import { CardElement, Elements, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
13
13
|
import { loadStripe } from "@stripe/stripe-js";
|
|
14
|
+
import { envVars } from "../../../lib/env.js";
|
|
14
15
|
|
|
15
16
|
//#region src/components-page/account-settings/payments/payments-panel.tsx
|
|
16
17
|
function formatPaymentMethod(pm) {
|
|
@@ -189,7 +190,7 @@ function RealPaymentsPanel(props) {
|
|
|
189
190
|
const [switchToProductId, setSwitchToProductId] = useState(null);
|
|
190
191
|
const stripePromise = useMemo(() => {
|
|
191
192
|
if (!setupIntentStripeAccountId) return null;
|
|
192
|
-
const publishableKey =
|
|
193
|
+
const publishableKey = envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
|
|
193
194
|
if (!publishableKey) return null;
|
|
194
195
|
return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });
|
|
195
196
|
}, [setupIntentStripeAccountId]);
|
|
@@ -202,7 +203,7 @@ function RealPaymentsPanel(props) {
|
|
|
202
203
|
});
|
|
203
204
|
return;
|
|
204
205
|
}
|
|
205
|
-
alert(`An unhandled error occurred. Please ${
|
|
206
|
+
alert(`An unhandled error occurred. Please ${envVars.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
|
|
206
207
|
};
|
|
207
208
|
const openPaymentDialog = () => {
|
|
208
209
|
runAsynchronously(async () => {
|