diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 0561a4a9b9a..c398d251af8 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -1037,6 +1037,9 @@ "settings.organization.billing.notSetUp": "Billing has not yet been set up for this organization. Start by adding a payment method.", "settings.organization.billing.title": "Billing", "settings.organization.billing.manualPaymentStatus": "Reach out to Sales if you have any questions about your plan.", + "settings.organization.billing.lockedPaymentStatus": "Your syncs are disabled. Please get in touch with {mail} to unlock your account.", + "settings.organization.billing.disabledPaymentStatus": "Your syncs are disabled due to unpaid invoices. Please update your payment method to enable syncing again.", + "settings.organization.billing.gracePeriodPaymentStatus": "Please update your payment method to keep using Airbyte. Otherwise your syncs will be disabled {days, plural, =0 {very soon} one {in # day} other {in # days}}.", "settings.organization.billing.billingInformation": "Billing information", "settings.organization.billing.billingInformationError": "Error loading billing information", "settings.organization.billing.update": "Update", diff --git a/airbyte-webapp/src/packages/cloud/area/billing/utils/useBillingStatusBanner.tsx b/airbyte-webapp/src/packages/cloud/area/billing/utils/useBillingStatusBanner.tsx new file mode 100644 index 00000000000..1a9aa7b7ed9 --- /dev/null +++ b/airbyte-webapp/src/packages/cloud/area/billing/utils/useBillingStatusBanner.tsx @@ -0,0 +1,76 @@ +import dayjs from "dayjs"; +import { useIntl } from "react-intl"; + +import { ExternalLink } from "components/ui/Link"; + +import { useCurrentOrganizationInfo } from "core/api"; +import { links } from "core/utils/links"; + +interface BillingStatusBanner { + content: React.ReactNode; + level: "warning" | "info"; +} + +export const useBillingStatusBanner = (): BillingStatusBanner | undefined => { + const { formatMessage } = useIntl(); + const { billing } = useCurrentOrganizationInfo(); + + if (!billing) { + return undefined; + } + + if (billing.paymentStatus === "manual") { + return { + level: "info", + content: formatMessage( + { id: "settings.organization.billing.manualPaymentStatus" }, + { + lnk: (node: React.ReactNode) => ( + + {node} + + ), + } + ), + }; + } + + if (billing.paymentStatus === "locked") { + return { + level: "warning", + content: formatMessage( + { id: "settings.organization.billing.lockedPaymentStatus" }, + { + mail: ( + + billing@airbyte.io + + ), + } + ), + }; + } + + if (billing.paymentStatus === "disabled") { + return { + level: "warning", + content: formatMessage({ id: "settings.organization.billing.disabledPaymentStatus" }), + }; + } + + if (billing.paymentStatus === "grace_period") { + return { + level: "warning", + content: formatMessage( + { id: "settings.organization.billing.gracePeriodPaymentStatus" }, + { + days: billing?.gracePeriodEndsAt + ? Math.max(dayjs(billing.gracePeriodEndsAt * 1000).diff(dayjs(), "days"), 0) + : 0, + } + ), + }; + } + + return undefined; +}; diff --git a/airbyte-webapp/src/packages/cloud/views/billing/OrganizationBillingPage/BillingBanners.tsx b/airbyte-webapp/src/packages/cloud/views/billing/OrganizationBillingPage/BillingBanners.tsx index 011e52a8af7..b8c28d0e01b 100644 --- a/airbyte-webapp/src/packages/cloud/views/billing/OrganizationBillingPage/BillingBanners.tsx +++ b/airbyte-webapp/src/packages/cloud/views/billing/OrganizationBillingPage/BillingBanners.tsx @@ -4,32 +4,17 @@ import { useIntl } from "react-intl"; import { Link } from "components/ui/Link"; import { Message } from "components/ui/Message"; -import { useCurrentOrganizationInfo } from "core/api"; -import { links } from "core/utils/links"; import { useExperiment } from "hooks/services/Experiment"; +import { useBillingStatusBanner } from "packages/cloud/area/billing/utils/useBillingStatusBanner"; export const BillingBanners: React.FC = () => { const { formatMessage } = useIntl(); - const { billing } = useCurrentOrganizationInfo(); + const billingBanner = useBillingStatusBanner(); const isAutoRechargeEnabled = useExperiment("billing.autoRecharge"); return ( <> - {billing?.paymentStatus === "manual" && ( - ( - - {node} - - ), - } - )} - /> - )} + {billingBanner && } {isAutoRechargeEnabled && (