import { useBreakpoint } from 'common' import { useMemo } from 'react' import { cn } from 'ui' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' import { BILLING_BREAKDOWN_METRICS } from '../BillingSettings/BillingBreakdown/BillingBreakdown.constants' import { BillingMetric } from '../BillingSettings/BillingBreakdown/BillingMetric' import { ComputeMetric } from '../BillingSettings/BillingBreakdown/ComputeMetric' import { SectionContent } from './SectionContent' import AlertError from '@/components/ui/AlertError' import { ComputeUsageMetric, computeUsageMetricLabel, PricingMetric, } from '@/data/analytics/org-daily-stats-query' import type { OrgSubscription } from '@/data/subscriptions/types' import { useOrgUsageQuery } from '@/data/usage/org-usage-query' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { DOCS_URL } from '@/lib/constants' export interface ComputeProps { orgSlug: string projectRef?: string | null startDate: string | undefined endDate: string | undefined subscription: OrgSubscription | undefined currentBillingCycleSelected: boolean } const METRICS_TO_HIDE_WITH_NO_USAGE: PricingMetric[] = [ PricingMetric.DISK_IOPS_IO2, PricingMetric.DISK_IOPS_GP3, PricingMetric.DISK_SIZE_GB_HOURS_GP3, PricingMetric.DISK_SIZE_GB_HOURS_IO2, PricingMetric.DISK_THROUGHPUT_GP3, PricingMetric.LOG_INGESTION, PricingMetric.LOG_STORAGE, PricingMetric.LOG_QUERYING, PricingMetric.ACTIVE_COMPUTE_HOURS, ] export const TotalUsage = ({ orgSlug, projectRef, subscription, startDate, endDate, currentBillingCycleSelected, }: ComputeProps) => { const isMobile = useBreakpoint('md') const isUsageBillingEnabled = subscription?.usage_billing_enabled const { billingAll } = useIsFeatureEnabled(['billing:all']) const { data: org } = useSelectedOrganizationQuery() const hasActiveRestriction = Boolean(org?.restriction_status) const { data: usage, error: usageError, isPending: isLoadingUsage, isError: isErrorUsage, isSuccess: isSuccessUsage, } = useOrgUsageQuery({ orgSlug, projectRef, start: !currentBillingCycleSelected && startDate ? new Date(startDate) : undefined, end: !currentBillingCycleSelected && endDate ? new Date(endDate) : undefined, }) // When the user filters by project ref or selects a custom timeframe, we only display usage+project breakdown, but no costs/limits const showRelationToSubscription = currentBillingCycleSelected && !projectRef const isOnHigherPlan = ['team', 'enterprise', 'platform'].includes(subscription?.plan.id ?? '') const hasExceededAnyLimits = showRelationToSubscription && Boolean( usage?.usages.find( (usageItem) => // Filter out compute as compute has no quota and is always being charged for !usageItem.metric.startsWith('COMPUTE_') && !usageItem.unlimited && usageItem.usage > (usageItem?.pricing_free_units ?? 0) ) ) const sortedBillingMetrics = useMemo(() => { if (!usage) return [] const breakdownMetrics = BILLING_BREAKDOWN_METRICS.filter((metric) => usage.usages.some((usage) => usage.metric === metric.key) ).filter((metric) => { if (!METRICS_TO_HIDE_WITH_NO_USAGE.includes(metric.key as PricingMetric)) return true const metricUsage = usage.usages.find((it) => it.metric === metric.key) return metricUsage && metricUsage.usage > 0 }) return breakdownMetrics.slice().sort((a, b) => { const usageMetaA = usage.usages.find((x) => x.metric === a.key) const usageRatioA = typeof usageMetaA !== 'number' ? (usageMetaA?.usage ?? 0) / (usageMetaA?.pricing_free_units ?? 0) : 0 const usageMetaB = usage.usages.find((x) => x.metric === b.key) const usageRatioB = typeof usageMetaB !== 'number' ? (usageMetaB?.usage ?? 0) / (usageMetaB?.pricing_free_units ?? 0) : 0 return ( // Sort unavailable features to bottom Number(usageMetaB?.available_in_plan) - Number(usageMetaA?.available_in_plan) || // Sort high-usage features to top usageRatioB - usageRatioA ) }) }, [usage]) const computeMetrics = (usage?.usages || []) .filter((it) => it.metric.startsWith('COMPUTE')) .map((it) => it.metric) as ComputeUsageMetric[] return (
{!hasExceededAnyLimits ? ( You have not exceeded your{' '} {subscription?.plan.name} Plan quota in this billing cycle. ) : hasExceededAnyLimits && subscription?.plan?.id === 'free' ? ( You have exceeded your{' '} {subscription?.plan.name} Plan quota in this billing cycle. Upgrade your plan to continue using Briven without restrictions. ) : hasExceededAnyLimits && subscription?.usage_billing_enabled === false && subscription?.plan?.id === 'pro' ? ( You have exceeded your{' '} {subscription?.plan.name} Plan quota in this billing cycle. Disable your spend cap to continue using Briven without restrictions. ) : hasExceededAnyLimits && subscription?.usage_billing_enabled === true ? ( You have exceeded your{' '} {subscription?.plan.name} Plan quota in this billing cycle and will be charged for over-usage. ) : ( You have not exceeded your{' '} {subscription?.plan.name} Plan quota in this billing cycle. )}
)}