All files / apps/host/src/components/ChartRequest index.tsx

95.23% Statements 20/21
87.5% Branches 14/16
100% Functions 7/7
94.73% Lines 18/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                                    4x                       6x 6x 6x   6x 6x 6x   6x   6x 14x           14x       6x   2x       2x 2x     2x         6x                           6x                        
import { useCallback, useMemo, useState } from 'react';
import { View } from 'react-native';
 
import { makeStyles } from '@repo/ui/themes/makeStyles';
import { useTheme } from '@repo/ui/themes/ThemeContext';
 
import { ChartRequestDonut } from './ChartRequestDonut';
import { ChartRequestPeriodSummary } from './ChartRequestPeriodSummary';
import { getRequestCategoryColors, REQUEST_CATEGORY_LABELS } from './constants';
import type { ChartRequestColoredActivity, ChartRequestPeriod, ChartRequestProps } from './types';
 
export type {
  ChartRequestActivity,
  ChartRequestPeriod,
  ChartRequestPeriodInfo,
  ChartRequestProps,
} from './types';
 
export const ChartRequest = ({
  week,
  month,
  initialPeriod = 'week',
  period,
  onPeriodChange,
  weekLabel = 'LAST WEEK',
  monthLabel = 'LAST MONTH',
  totalLabel = 'Total',
  testID,
  style,
}: ChartRequestProps) => {
  const { theme } = useTheme();
  const styles = useStyles();
  const [internalPeriod, setInternalPeriod] = useState<ChartRequestPeriod>(initialPeriod);
 
  const selectedPeriod = period ?? internalPeriod;
  const selectedData = selectedPeriod === 'month' ? month : week;
  const categoryColors = useMemo(() => getRequestCategoryColors(theme), [theme]);
 
  const coloredActivities = useMemo<ChartRequestColoredActivity[]>(
    () =>
      selectedData.activities
        .map(activity => ({
          category: activity.category,
          label: activity.label ?? REQUEST_CATEGORY_LABELS[activity.category],
          count: activity.count,
          color: activity.color ?? categoryColors[activity.category],
        }))
        .filter(activity => activity.count > 0),
    [categoryColors, selectedData.activities],
  );
 
  const handlePeriodChange = useCallback(
    (nextPeriod: ChartRequestPeriod) => {
      Iif (nextPeriod === selectedPeriod) {
        return;
      }
 
      Eif (period === undefined) {
        setInternalPeriod(nextPeriod);
      }
 
      onPeriodChange?.(nextPeriod);
    },
    [onPeriodChange, period, selectedPeriod],
  );
 
  return (
    <View style={[styles.container, style]} testID={testID}>
      <ChartRequestDonut totalLabel={totalLabel} activities={coloredActivities} />
      <ChartRequestPeriodSummary
        selectedPeriod={selectedPeriod}
        weekLabel={weekLabel}
        monthLabel={monthLabel}
        onPeriodChange={handlePeriodChange}
        activities={coloredActivities}
      />
    </View>
  );
};
 
const useStyles = makeStyles(theme => ({
  container: {
    backgroundColor: theme.colors.background.secondary,
    borderRadius: theme.metrics.borderRadius[6],
    width: theme.metrics.sizing.full,
    paddingHorizontal: theme.metrics.spacing[2.5],
    paddingTop: theme.metrics.spacing[5.5],
    paddingBottom: theme.metrics.spacing[5],
    alignItems: 'center',
    gap: theme.metrics.spacing[3],
  },
}));