import { useEffect, useMemo, useRef, useState } from 'react' import { VChart } from '@visactor/react-vchart' import { AreaChart, BarChart3, WalletCards } from 'lucide-react' import { useTranslation } from 'react-i18next' import type { TimeGranularity } from '@/lib/time' import { VCHART_OPTION } from '@/lib/vchart' import { useThemeCustomization } from '@/context/theme-customization-provider' import { useTheme } from '@/context/theme-provider' import { CONSUMPTION_DISTRIBUTION_CHART_OPTIONS, DEFAULT_TIME_GRANULARITY, } from '@/features/dashboard/constants' import { processChartData } from '@/features/dashboard/lib' import type { ConsumptionDistributionChartType, QuotaDataItem, } from '@/features/dashboard/types' let themeManagerPromise: Promise< (typeof import('@visactor/vchart'))['ThemeManager'] > | null = null interface ConsumptionDistributionChartProps { data: QuotaDataItem[] loading?: boolean timeGranularity?: TimeGranularity defaultChartType?: ConsumptionDistributionChartType } const CHART_TYPE_ICONS: Record< ConsumptionDistributionChartType, typeof BarChart3 > = { bar: BarChart3, area: AreaChart, } export function ConsumptionDistributionChart( props: ConsumptionDistributionChartProps ) { const { t } = useTranslation() const { resolvedTheme } = useTheme() const { customization } = useThemeCustomization() const [chartType, setChartType] = useState( props.defaultChartType ?? 'bar' ) const [themeReady, setThemeReady] = useState(false) const themeManagerRef = useRef< (typeof import('@visactor/vchart'))['ThemeManager'] | null >(null) const timeGranularity = props.timeGranularity ?? DEFAULT_TIME_GRANULARITY useEffect(() => { if (props.defaultChartType) setChartType(props.defaultChartType) }, [props.defaultChartType]) useEffect(() => { const updateTheme = async () => { setThemeReady(false) if (!themeManagerPromise) { themeManagerPromise = import('@visactor/vchart').then( (m) => m.ThemeManager ) } const ThemeManager = await themeManagerPromise themeManagerRef.current = ThemeManager ThemeManager.setCurrentTheme(resolvedTheme === 'dark' ? 'dark' : 'light') setThemeReady(true) } updateTheme() }, [resolvedTheme]) const chartData = useMemo( () => processChartData( props.loading ? [] : props.data, timeGranularity, t, customization.preset ), [props.data, props.loading, timeGranularity, t, customization.preset] ) const spec = chartType === 'bar' ? chartData.spec_line : chartData.spec_area return (
{t('Quota Distribution')}
{t('Total:')} {chartData.totalQuotaDisplay}
{CONSUMPTION_DISTRIBUTION_CHART_OPTIONS.map((item) => { const Icon = CHART_TYPE_ICONS[item.value] return ( ) })}
{themeReady && spec && ( )}
) }