import * as React from 'react'; import I18n from 'i18n-js'; import { loadStripe } from '@stripe/stripe-js'; import ITenantBilling, { TENANT_BILLING_STATUS_ACTIVE, TENANT_BILLING_STATUS_CANCELED, TENANT_BILLING_STATUS_TRIAL } from '../../interfaces/ITenantBilling'; import Box from '../common/Box'; import { EmbeddedCheckout, EmbeddedCheckoutProvider } from '@stripe/react-stripe-js'; import buildRequestHeaders from '../../helpers/buildRequestHeaders'; import { SmallMutedText } from '../common/CustomTexts'; import ActionLink from '../common/ActionLink'; import { BackIcon, LearnMoreIcon } from '../common/Icons'; import PricingTable from './PricingTable'; interface Props { tenantBilling: ITenantBilling; prices: Array; createCheckoutSessionUrl: string; billingUrl: string; manageSubscriptionUrl: string; stripeMonthlyLookupKey: string; stripeYearlyLookupKey: string; stripePublicKey: string; authenticityToken: string; } const Billing = ({ tenantBilling, prices, createCheckoutSessionUrl, billingUrl, manageSubscriptionUrl, stripeMonthlyLookupKey, stripeYearlyLookupKey, stripePublicKey, authenticityToken, }: Props) => { const [stripePromise, setStripePromise] = React.useState(null); const [currentPrice, setCurrentPrice] = React.useState(null); const [chosenPrice, setChosenPrice] = React.useState(null); const [showBackLink, setShowBackLink] = React.useState(false); React.useEffect(() => { setStripePromise(loadStripe(stripePublicKey)); }, []); React.useEffect(() => { if (prices && prices.length > 0) { setCurrentPrice(prices[0].id); } }, [prices]); const fetchClientSecret = React.useCallback(() => { // Create a Checkout Session return fetch(`${createCheckoutSessionUrl}?price_id=${chosenPrice}&tenant_id=${tenantBilling.slug}`, { method: "POST", headers: buildRequestHeaders(authenticityToken), }) .then((res) => res.json()) .then((data) => data.clientSecret); }, [chosenPrice]); React.useEffect(() => { if (chosenPrice) { // scroll to checkout const checkoutElement = document.getElementById('checkout'); setTimeout(() => { checkoutElement.scrollIntoView({behavior: 'smooth'}); }, 300); // show back link after 5 seconds const timer = setTimeout(() => { setShowBackLink(true); }, 5000); return () => clearTimeout(timer); // cleanup on unmount or when chosenPrice changes } else { setShowBackLink(false); // reset state when chosenPrice becomes null } }, [chosenPrice]); const options = {fetchClientSecret}; const currentTime = new Date(); const trialEndsAt = new Date(tenantBilling.trial_ends_at); const trialEndsAtFormatted = trialEndsAt.toLocaleString(undefined, {year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit'}); const subscriptionEndsAt = new Date(tenantBilling.subscription_ends_at); const subscriptionEndsAtFormatted = subscriptionEndsAt.toLocaleString(undefined, {year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit'}); const isExpired = ( (tenantBilling.status === TENANT_BILLING_STATUS_TRIAL && trialEndsAt < currentTime) || ((tenantBilling.status === TENANT_BILLING_STATUS_ACTIVE || tenantBilling.status === TENANT_BILLING_STATUS_CANCELED) && subscriptionEndsAt < currentTime) ); return (

{ I18n.t('billing.title') }

{tenantBilling.status} { isExpired && Expired }

{ tenantBilling.status === TENANT_BILLING_STATUS_TRIAL &&

Trial {isExpired ? 'expired' : 'expires'} on {trialEndsAtFormatted}

} { tenantBilling.status === TENANT_BILLING_STATUS_TRIAL && isExpired &&

Your trial has expired. Please choose a subscription plan to continue using the service.

} { tenantBilling.status === TENANT_BILLING_STATUS_ACTIVE &&

Subscription {isExpired ? 'expired' : 'renews'} on {subscriptionEndsAtFormatted}

} { tenantBilling.status === TENANT_BILLING_STATUS_ACTIVE && isExpired &&

Your subscription has expired because automatic renewal failed. Please update your payment details by managing your subscription.

} { tenantBilling.status === TENANT_BILLING_STATUS_CANCELED &&

Subscription {isExpired ? 'expired' : 'expires'} on {subscriptionEndsAtFormatted}

} { (tenantBilling.status === TENANT_BILLING_STATUS_TRIAL) && chosenPrice === null && } { chosenPrice &&
{ showBackLink ? window.location.href = billingUrl} icon={}> Choose another plan :
}
} { (tenantBilling.status === TENANT_BILLING_STATUS_ACTIVE || tenantBilling.status === TENANT_BILLING_STATUS_CANCELED) &&
You will be redirected to Stripe, our billing partner.
}
window.open('https://astuto.io/terms-of-service', '_blank')} icon={}> Terms of Service window.open('https://astuto.io/privacy-policy', '_blank')} icon={}> Privacy Policy
); } export default Billing;