ActiveCompute.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { BarChart2 } from 'lucide-react'
  2. import { useMemo } from 'react'
  3. import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
  4. import { SectionContent } from './SectionContent'
  5. import { dailyUsageToDataPoints } from './Usage.utils'
  6. import UsageBarChart from './UsageBarChart'
  7. import Panel from '@/components/ui/Panel'
  8. import { DataPoint } from '@/data/analytics/constants'
  9. import { PricingMetric, type OrgDailyUsageResponse } from '@/data/analytics/org-daily-stats-query'
  10. import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
  11. import { DOCS_URL } from '@/lib/constants'
  12. export interface ComputeProps {
  13. orgDailyStats: OrgDailyUsageResponse | undefined
  14. isLoadingOrgDailyStats: boolean
  15. }
  16. const ActiveCompute = ({ orgDailyStats, isLoadingOrgDailyStats }: ComputeProps) => {
  17. const { billingAll } = useIsFeatureEnabled(['billing:all'])
  18. const chartData: DataPoint[] = dailyUsageToDataPoints(
  19. orgDailyStats,
  20. (metric) => metric === PricingMetric.ACTIVE_COMPUTE_HOURS
  21. )
  22. const notAllValuesZero = useMemo(() => {
  23. return chartData.some(
  24. (dataPoint) =>
  25. dataPoint['active_compute_hours'] && Number(dataPoint['active_compute_hours']) > 0
  26. )
  27. }, [chartData])
  28. return (
  29. <div id="active-compute" className="scroll-my-12">
  30. <SectionContent
  31. section={{
  32. name: 'Active Compute Hours',
  33. description:
  34. 'Amount of active compute hours your projects on scale-to-zero instances consumed. Projects on scale-to-zero instances automatically scale down after a 15m inactivity period.',
  35. links: billingAll
  36. ? [
  37. {
  38. name: 'Learn more',
  39. url: `${DOCS_URL}/guides/integrations/briven-for-platforms#pico-compute-instance`,
  40. },
  41. ]
  42. : [],
  43. }}
  44. >
  45. {isLoadingOrgDailyStats && <GenericSkeletonLoader />}
  46. {!isLoadingOrgDailyStats && (
  47. <>
  48. <div className="space-y-1">
  49. {chartData.length > 0 && (
  50. <div className="flex items-center justify-between">
  51. <div className="flex items-center space-x-4">
  52. <p className="text-sm">Active Compute Hours usage</p>
  53. </div>
  54. </div>
  55. )}
  56. <div className="flex items-center justify-between border-b last:border-b-0 py-1 last:py-0">
  57. <p className="text-sm text-foreground-light">
  58. Active Compute Hours usage in period
  59. </p>
  60. <p className="text-sm">
  61. {chartData.reduce(
  62. (prev, cur) => prev + ((cur['active_compute_hours'] as number) ?? 0),
  63. 0
  64. )}{' '}
  65. hours
  66. </p>
  67. </div>
  68. </div>
  69. {chartData.length > 0 && notAllValuesZero ? (
  70. <UsageBarChart
  71. name={`Active Compute Hours usage`}
  72. unit={'hours'}
  73. attributes={[{ key: 'active_compute_hours', color: 'blue' }]}
  74. data={chartData}
  75. yMin={24}
  76. />
  77. ) : (
  78. <Panel>
  79. <Panel.Content>
  80. <div className="flex flex-col items-center justify-center">
  81. <BarChart2 className="text-foreground-light mb-2" />
  82. <p className="text-sm">No data in period</p>
  83. <p className="text-sm text-foreground-light">May take up to one hour to show</p>
  84. </div>
  85. </Panel.Content>
  86. </Panel>
  87. )}
  88. </>
  89. )}
  90. </SectionContent>
  91. </div>
  92. )
  93. }
  94. export default ActiveCompute