JezK
Edit File: sc-upcoming-invoice.entry.js.map
{"file":"sc-upcoming-invoice.entry.js","mappings":";;;;;;;;;;AAAA,MAAM,oBAAoB,GAAG,+RAA+R,CAAC;AAC7T,gCAAe,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sPCwDoC,UAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oFA4DlC,UAAE;;;;;;;;;;;;;;8EAaR,UAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8EA2BF,UAAE;;;;;;;;eASxB,UAAE;;;;;mCAOF,UAAE,wEAEA,UAAE;;;+BAQN,UAAE,wEAA0D,UAAE;;;4CAMxC,UAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EAuEG,UAAE,2OAMA,UAAE,2PAOF,UAAE,qpBAkBF,UAAE,wWAQvB,UAAE,kIAIG,UAAE,qPAMgB,UAAE,+7BA2BN,UAAE;;2hBAgBR,UAAE;;;6SAaA,UAAE,4LAMM,UAAE,qPAIF,UAAE,4aAKzB,UAAE;;;;;;;;","names":[],"sources":["src/components/controllers/dashboard/upcoming-invoice/sc-upcoming-invoice.scss?tag=sc-upcoming-invoice&encapsulation=shadow","src/components/controllers/dashboard/upcoming-invoice/sc-upcoming-invoice.tsx"],"sourcesContent":[":host {\n display: block;\n position: relative;\n}\n\n.upcoming-invoice {\n display: grid;\n gap: var(--sc-spacing-large);\n\n\n > * {\n display: grid;\n gap: var(--sc-spacing-medium);\n }\n}\n\n.new-plan {\n display: grid;\n gap: 0.25em;\n color: var(--sc-input-label-color);\n\n &__heading {\n font-weight: var(--sc-font-weight-bold);\n }\n}\n","import { Component, Element, Fragment, h, Prop, State } from '@stencil/core';\nimport { __ } from '@wordpress/i18n';\nimport { addQueryArgs } from '@wordpress/url';\n\nimport apiFetch from '../../../../functions/fetch';\nimport { onFirstVisible } from '../../../../functions/lazy';\nimport { formatTaxDisplay } from '../../../../functions/tax';\nimport { Checkout, PaymentMethod, Period, Price, Product, ManualPaymentMethod } from '../../../../types';\nimport { productNameWithPrice } from '../../../../functions/price';\n@Component({\n tag: 'sc-upcoming-invoice',\n styleUrl: 'sc-upcoming-invoice.scss',\n shadow: true,\n})\nexport class ScUpcomingInvoice {\n @Element() el: HTMLScUpcomingInvoiceElement;\n\n @Prop() heading: string;\n @Prop() successUrl: string;\n @Prop() subscriptionId: string;\n @Prop() priceId: string;\n @Prop() variantId: string;\n @Prop() quantity: number;\n @Prop({ mutable: true }) discount: {\n promotion_code?: string;\n coupon?: string;\n };\n @Prop({ mutable: true }) payment_method: PaymentMethod;\n @Prop() quantityUpdatesEnabled: boolean = true;\n @Prop() adHocAmount: number;\n\n /** Loading state */\n @State() loading: boolean;\n @State() busy: boolean;\n\n /** Error message */\n @State() error: string;\n @State() price: Price;\n @State() invoice: Period;\n @State() couponError: string;\n\n componentWillLoad() {\n onFirstVisible(this.el, () => {\n this.fetchItems();\n });\n }\n\n isFutureInvoice() {\n return this.invoice.start_at >= new Date().getTime() / 1000;\n }\n\n async fetchItems() {\n try {\n this.loading = true;\n await Promise.all([this.getInvoice(), this.getPrice()]);\n } catch (e) {\n console.error(e);\n this.error = e?.additional_errors?.[0]?.message || e?.message || __('Something went wrong', 'surecart');\n } finally {\n this.loading = false;\n }\n }\n\n async getPrice() {\n if (!this.priceId) return;\n this.price = (await apiFetch({\n path: addQueryArgs(`surecart/v1/prices/${this.priceId}`, {\n expand: ['product'],\n }),\n })) as Price;\n }\n\n async getInvoice() {\n if (!this.subscriptionId) return;\n\n this.invoice = (await apiFetch({\n method: 'PATCH',\n path: addQueryArgs(`surecart/v1/subscriptions/${this.subscriptionId}/upcoming_period/`, {\n expand: [\n 'period.checkout',\n 'checkout.line_items',\n 'checkout.checkout_fees',\n 'checkout.shipping_fees',\n 'line_item.price',\n 'line_item.fees',\n 'price.product',\n 'checkout.payment_method',\n 'checkout.manual_payment_method',\n 'checkout.discount',\n 'discount.promotion',\n 'discount.coupon',\n 'payment_method.card',\n 'payment_method.payment_instrument',\n 'payment_method.paypal_account',\n 'payment_method.bank_account',\n ],\n }),\n data: {\n price: this.priceId,\n variant: this.variantId,\n quantity: this.quantity,\n ...(this.adHocAmount ? { ad_hoc_amount: this.adHocAmount } : {}),\n ...(this.discount ? { discount: this.discount } : {}),\n },\n })) as Period;\n return this.invoice;\n }\n\n async applyCoupon(e) {\n try {\n this.couponError = '';\n this.busy = true;\n this.discount = {\n promotion_code: e.detail,\n };\n await this.getInvoice();\n } catch (e) {\n this.couponError = e?.message || __('Something went wrong', 'surecart');\n } finally {\n this.busy = false;\n }\n }\n\n async updateQuantity(e) {\n try {\n this.error = '';\n this.busy = true;\n this.quantity = e.detail;\n await this.getInvoice();\n } catch (e) {\n this.error = e?.message || __('Something went wrong', 'surecart');\n } finally {\n this.busy = false;\n }\n }\n\n async onSubmit() {\n try {\n this.error = '';\n this.busy = true;\n await apiFetch({\n path: `surecart/v1/subscriptions/${this.subscriptionId}`,\n method: 'PATCH',\n data: {\n price: this.priceId,\n quantity: this.quantity,\n variant: this.variantId,\n ...(this.adHocAmount ? { ad_hoc_amount: this.adHocAmount } : {}),\n ...(this.discount ? { discount: this.discount } : {}),\n },\n });\n if (this.successUrl) {\n window.location.assign(this.successUrl);\n } else {\n this.busy = false;\n }\n } catch (e) {\n this.error = e?.message || __('Something went wrong', 'surecart');\n this.busy = false;\n }\n }\n\n renderName(price: Price) {\n if (typeof price?.product !== 'string') {\n return productNameWithPrice(price);\n }\n return __('Plan', 'surecart');\n }\n\n renderRenewalText() {\n if (this.isFutureInvoice()) {\n return (\n <div>\n {__(\"You'll be switched to this plan\", 'surecart')}{' '}\n <strong>\n {__('at the end of your billing cycle on', 'surecart')} {this.invoice?.start_at_date}\n </strong>\n </div>\n );\n }\n\n return (\n <div>\n {__(\"You'll be switched to this plan\", 'surecart')} <strong>{__('immediately', 'surecart')}</strong>\n </div>\n );\n }\n\n renderEmpty() {\n return <slot name=\"empty\">{__('Something went wrong.', 'surecart')}</slot>;\n }\n\n renderLoading() {\n return (\n <div>\n <sc-skeleton style={{ width: '30%', marginBottom: '0.75em' }}></sc-skeleton>\n <sc-skeleton style={{ width: '20%', marginBottom: '0.75em' }}></sc-skeleton>\n <sc-skeleton style={{ width: '40%' }}></sc-skeleton>\n </div>\n );\n }\n\n renderContent() {\n if (this.loading) {\n return this.renderLoading();\n }\n\n if (!this.invoice?.checkout) {\n return this.renderEmpty();\n }\n\n const checkout = this.invoice.checkout as Checkout;\n\n return (\n <div class=\"new-plan\">\n <div class=\"new-plan__heading\">{this.renderName(this.price)}</div>\n <div>\n <span slot=\"price\">{checkout?.subtotal_display_amount}</span>\n </div>\n <div style={{ fontSize: 'var(--sc-font-size-small)' }}>{this.renderRenewalText()}</div>\n </div>\n );\n }\n\n renderSummary() {\n if (this.loading) {\n return this.renderLoading();\n }\n\n if (!this.invoice) {\n return this.renderEmpty();\n }\n\n const checkout = this.invoice?.checkout as Checkout;\n const manualPaymentMethod = checkout?.manual_payment ? (checkout?.manual_payment_method as ManualPaymentMethod) : null;\n\n const checkout_fees = checkout?.checkout_fees?.data;\n const shipping_fees = checkout?.shipping_fees?.data;\n\n return (\n <Fragment>\n {checkout?.line_items?.data.map(item => (\n <sc-product-line-item\n image={(item.price?.product as Product)?.line_item_image}\n name={(item.price?.product as Product)?.name}\n price={item?.price?.name}\n variant={item?.variant_display_options}\n editable={this.quantityUpdatesEnabled}\n purchasableStatus={item?.purchasable_status_display}\n removable={false}\n note={item?.display_note}\n quantity={item?.quantity}\n amount={item?.subtotal_display_amount}\n interval={`${item?.price?.short_interval_text} ${item?.price?.short_interval_count_text}`}\n onScUpdateQuantity={e => this.updateQuantity(e)}\n fees={item?.fees?.data}\n ></sc-product-line-item>\n ))}\n\n <sc-line-item>\n <span slot=\"description\">{__('Subtotal', 'surecart')}</span>\n <span slot=\"price\">{checkout?.subtotal_display_amount}</span>\n </sc-line-item>\n\n {!!checkout.proration_amount && (\n <sc-line-item>\n <span slot=\"description\">{__('Proration Credit', 'surecart')}</span>\n <span slot=\"price\">{checkout?.proration_display_amount}</span>\n </sc-line-item>\n )}\n\n {!!checkout.applied_balance_amount && (\n <sc-line-item>\n <span slot=\"description\">{__('Applied Balance', 'surecart')}</span>\n <span slot=\"price\">{checkout?.applied_balance_display_amount}</span>\n </sc-line-item>\n )}\n\n {checkout_fees?.length > 0 && (\n <Fragment>\n {checkout_fees?.map(fee => (\n <sc-line-item>\n <span slot=\"description\">{fee?.description}</span>\n <span slot=\"price\">{fee?.display_amount}</span>\n </sc-line-item>\n ))}\n </Fragment>\n )}\n\n {!!checkout.trial_amount && (\n <sc-line-item>\n <span slot=\"description\">{__('Trial', 'surecart')}</span>\n <span slot=\"price\">{checkout?.trial_display_amount}</span>\n </sc-line-item>\n )}\n\n <sc-coupon-form\n discount={checkout?.discount}\n discountsDisplayAmount={checkout?.discounts_display_amount}\n label={__('Add Coupon Code', 'surecart')}\n onScApplyCoupon={e => this.applyCoupon(e)}\n error={this.couponError}\n collapsed\n buttonText={__('Add Coupon Code', 'surecart')}\n ></sc-coupon-form>\n\n {!!checkout?.shipping_amount && (\n <Fragment>\n <sc-line-item style={{ marginTop: 'var(--sc-spacing-small)' }}>\n <span slot=\"description\">{__('Shipping', 'surecart')}</span>\n <span slot=\"price\">{checkout?.shipping_display_amount}</span>\n </sc-line-item>\n\n {shipping_fees?.length > 0 && (\n <Fragment>\n {shipping_fees?.map(fee => (\n <sc-line-item>\n <span slot=\"description\">{fee?.description}</span>\n <span slot=\"price\">{fee?.display_amount}</span>\n </sc-line-item>\n ))}\n </Fragment>\n )}\n </Fragment>\n )}\n\n {!!checkout.tax_amount && (\n <sc-line-item>\n <span slot=\"description\">{formatTaxDisplay(checkout?.tax_label)}</span>\n <span slot=\"price\">{checkout?.tax_display_amount}</span>\n </sc-line-item>\n )}\n\n <sc-divider style={{ '--spacing': '0' }}></sc-divider>\n\n <sc-line-item>\n <span slot=\"description\">{__('Payment', 'surecart')}</span>\n <a\n href={addQueryArgs(window.location.href, {\n action: 'payment',\n })}\n slot=\"price-description\"\n >\n <sc-flex justify-content=\"flex-start\" align-items=\"center\" style={{ '--spacing': '0.5em' }}>\n {!!manualPaymentMethod && <sc-manual-payment-method paymentMethod={manualPaymentMethod} />}\n {!manualPaymentMethod && <sc-payment-method paymentMethod={checkout?.payment_method}></sc-payment-method>}\n <sc-icon name=\"edit-3\"></sc-icon>\n </sc-flex>\n </a>\n </sc-line-item>\n\n <sc-line-item style={{ '--price-size': 'var(--sc-font-size-x-large)' }}>\n <span slot=\"title\">{__('Total Due', 'surecart')}</span>\n <span slot=\"price\">{checkout?.amount_due_display_amount}</span>\n <span slot=\"currency\">{checkout.currency}</span>\n </sc-line-item>\n </Fragment>\n );\n }\n\n render() {\n return (\n <div class=\"upcoming-invoice\">\n {this.error && (\n <sc-alert open={!!this.error} type=\"danger\">\n <span slot=\"title\">{__('Error', 'surecart')}</span>\n {this.error}\n </sc-alert>\n )}\n\n <Fragment>\n <sc-dashboard-module heading={__('New Plan', 'surecart')} class=\"plan-preview\" error={this.error}>\n <sc-card>{this.renderContent()}</sc-card>\n </sc-dashboard-module>\n\n <sc-dashboard-module heading={__('Summary', 'surecart')} class=\"plan-summary\">\n <sc-form onScFormSubmit={() => this.onSubmit()}>\n <sc-card>{this.renderSummary()}</sc-card>\n\n <sc-button type=\"primary\" full submit loading={this.loading || this.busy} disabled={this.loading || this.busy}>\n {__('Confirm', 'surecart')}\n </sc-button>\n </sc-form>\n </sc-dashboard-module>\n\n <sc-text style={{ '--text-align': 'center', '--font-size': 'var(--sc-font-size-small)', '--line-height': 'var(--sc-line-height-normal)' }}>\n <slot name=\"terms\"></slot>\n </sc-text>\n </Fragment>\n\n {this.busy && <sc-block-ui></sc-block-ui>}\n </div>\n );\n }\n}\n"],"version":3}