{"path":"apps/dashboard/src/components/ui/chart.tsx","size":11521,"locked":false,"binary":false,"truncated":false,"content":"import * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\n\nimport { cn } from \"@/lib/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nexport type ChartConfig = {\n  [k in string]: {\n    label?: React.ReactNode;\n    icon?: React.ComponentType;\n  } & (\n    | { color?: string; theme?: never }\n    | { color?: never; theme: Record<keyof typeof THEMES, string> }\n  );\n};\n\ntype ChartContextProps = {\n  config: ChartConfig;\n};\n\ntype ChartPayloadItem = {\n  dataKey?: string | number;\n  name?: string | number;\n  value?: string | number;\n  color?: string;\n  type?: string;\n  payload?: {\n    fill?: string;\n    [key: string]: unknown;\n  };\n};\n\ntype ChartTooltipContentProps = React.ComponentProps<\"div\"> & {\n  active?: boolean;\n  payload?: ChartPayloadItem[];\n  label?: React.ReactNode;\n  labelFormatter?: (\n    label: React.ReactNode,\n    payload: ChartPayloadItem[],\n  ) => React.ReactNode;\n  formatter?: (\n    value: ChartPayloadItem[\"value\"],\n    name: ChartPayloadItem[\"name\"],\n    item: ChartPayloadItem,\n    index: number,\n    payload: ChartPayloadItem[\"payload\"],\n  ) => React.ReactNode;\n  hideLabel?: boolean;\n  hideIndicator?: boolean;\n  indicator?: \"line\" | \"dot\" | \"dashed\";\n  nameKey?: string;\n  labelKey?: string;\n  labelClassName?: string;\n  color?: string;\n};\n\ntype ChartLegendContentProps = React.ComponentProps<\"div\"> & {\n  payload?: ChartPayloadItem[];\n  verticalAlign?: \"top\" | \"middle\" | \"bottom\";\n  hideIcon?: boolean;\n  nameKey?: string;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n  const context = React.useContext(ChartContext);\n\n  if (!context) {\n    throw new Error(\"useChart must be used within a <ChartContainer />\");\n  }\n\n  return context;\n}\n\nconst ChartContainer = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<\"div\"> & {\n    config: ChartConfig;\n    children: React.ComponentProps<\n      typeof RechartsPrimitive.ResponsiveContainer\n    >[\"children\"];\n  }\n>(({ id, className, children, config, ...props }, ref) => {\n  const uniqueId = React.useId();\n  const chartId = `chart-${id || uniqueId.replace(/:/g, \"\")}`;\n\n  return (\n    <ChartContext.Provider value={{ config }}>\n      <div\n        data-chart={chartId}\n        ref={ref}\n        className={cn(\n          \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none\",\n          className,\n        )}\n        {...props}\n      >\n        <ChartStyle id={chartId} config={config} />\n        <RechartsPrimitive.ResponsiveContainer>\n          {children}\n        </RechartsPrimitive.ResponsiveContainer>\n      </div>\n    </ChartContext.Provider>\n  );\n});\nChartContainer.displayName = \"Chart\";\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n  const colorConfig = Object.entries(config).filter(\n    ([, config]) => config.theme || config.color,\n  );\n\n  if (!colorConfig.length) {\n    return null;\n  }\n\n  return (\n    <style\n      dangerouslySetInnerHTML={{\n        __html: Object.entries(THEMES)\n          .map(\n            ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n  .map(([key, itemConfig]) => {\n    const color =\n      itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||\n      itemConfig.color;\n    return color ? `  --color-${key}: ${color};` : null;\n  })\n  .join(\"\\n\")}\n}\n`,\n          )\n          .join(\"\\n\"),\n      }}\n    />\n  );\n};\n\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\nconst ChartTooltipContent = React.forwardRef<\n  HTMLDivElement,\n  ChartTooltipContentProps\n>(\n  (\n    {\n      active,\n      payload,\n      className,\n      indicator = \"dot\",\n      hideLabel = false,\n      hideIndicator = false,\n      label,\n      labelFormatter,\n      labelClassName,\n      formatter,\n      color,\n      nameKey,\n      labelKey,\n    },\n    ref,\n  ) => {\n    const { config } = useChart();\n\n    const tooltipLabel = React.useMemo(() => {\n      if (hideLabel || !payload?.length) {\n        return null;\n      }\n\n      const [item] = payload;\n      const key = `${labelKey || item?.dataKey || item?.name || \"value\"}`;\n      const itemConfig = getPayloadConfigFromPayload(config, item, key);\n      const value =\n        !labelKey && typeof label === \"string\"\n          ? config[label as keyof typeof config]?.label || label\n          : itemConfig?.label;\n\n      if (labelFormatter) {\n        return (\n          <div className={cn(\"font-medium\", labelClassName)}>\n            {labelFormatter(value, payload)}\n          </div>\n        );\n      }\n\n      if (!value) {\n        return null;\n      }\n\n      return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>;\n    }, [\n      label,\n      labelFormatter,\n      payload,\n      hideLabel,\n      labelClassName,\n      config,\n      labelKey,\n    ]);\n\n    if (!active || !payload?.length) {\n      return null;\n    }\n\n    const nestLabel = payload.length === 1 && indicator !== \"dot\";\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\n          \"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl\",\n          className,\n        )}\n      >\n        {!nestLabel ? tooltipLabel : null}\n        <div className=\"grid gap-1.5\">\n          {payload\n            .filter((item) => item.type !== \"none\")\n            .map((item, index) => {\n              const key = `${nameKey || item.name || item.dataKey || \"value\"}`;\n              const itemConfig = getPayloadConfigFromPayload(config, item, key);\n              const indicatorColor = color || item.payload?.fill || item.color;\n\n              return (\n                <div\n                  key={item.dataKey}\n                  className={cn(\n                    \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n                    indicator === \"dot\" && \"items-center\",\n                  )}\n                >\n                  {formatter && item?.value !== undefined && item.name ? (\n                    formatter(item.value, item.name, item, index, item.payload)\n                  ) : (\n                    <>\n                      {itemConfig?.icon ? (\n                        <itemConfig.icon />\n                      ) : (\n                        !hideIndicator && (\n                          <div\n                            className={cn(\n                              \"shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]\",\n                              {\n                                \"h-2.5 w-2.5\": indicator === \"dot\",\n                                \"w-1\": indicator === \"line\",\n                                \"w-0 border-[1.5px] border-dashed bg-transparent\":\n                                  indicator === \"dashed\",\n                                \"my-0.5\": nestLabel && indicator === \"dashed\",\n                              },\n                            )}\n                            style={\n                              {\n                                \"--color-bg\": indicatorColor,\n                                \"--color-border\": indicatorColor,\n                              } as React.CSSProperties\n                            }\n                          />\n                        )\n                      )}\n                      <div\n                        className={cn(\n                          \"flex flex-1 justify-between leading-none\",\n                          nestLabel ? \"items-end\" : \"items-center\",\n                        )}\n                      >\n                        <div className=\"grid gap-1.5\">\n                          {nestLabel ? tooltipLabel : null}\n                          <span className=\"text-muted-foreground\">\n                            {itemConfig?.label || item.name}\n                          </span>\n                        </div>\n                        {item.value && (\n                          <span className=\"font-mono font-medium tabular-nums text-foreground\">\n                            {item.value.toLocaleString()}\n                          </span>\n                        )}\n                      </div>\n                    </>\n                  )}\n                </div>\n              );\n            })}\n        </div>\n      </div>\n    );\n  },\n);\nChartTooltipContent.displayName = \"ChartTooltip\";\n\nconst ChartLegend = RechartsPrimitive.Legend;\n\nconst ChartLegendContent = React.forwardRef<\n  HTMLDivElement,\n  ChartLegendContentProps\n>(\n  (\n    { className, hideIcon = false, payload, verticalAlign = \"bottom\", nameKey },\n    ref,\n  ) => {\n    const { config } = useChart();\n\n    if (!payload?.length) {\n      return null;\n    }\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\n          \"flex items-center justify-center gap-4\",\n          verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n          className,\n        )}\n      >\n        {payload\n          .filter((item) => item.type !== \"none\")\n          .map((item) => {\n            const key = `${nameKey || item.dataKey || \"value\"}`;\n            const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n            return (\n              <div\n                key={item.value}\n                className={cn(\n                  \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\",\n                )}\n              >\n                {itemConfig?.icon && !hideIcon ? (\n                  <itemConfig.icon />\n                ) : (\n                  <div\n                    className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n                    style={{\n                      backgroundColor: item.color,\n                    }}\n                  />\n                )}\n                {itemConfig?.label}\n              </div>\n            );\n          })}\n      </div>\n    );\n  },\n);\nChartLegendContent.displayName = \"ChartLegend\";\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(\n  config: ChartConfig,\n  payload: unknown,\n  key: string,\n) {\n  if (typeof payload !== \"object\" || payload === null) {\n    return undefined;\n  }\n\n  const payloadPayload =\n    \"payload\" in payload &&\n    typeof payload.payload === \"object\" &&\n    payload.payload !== null\n      ? payload.payload\n      : undefined;\n\n  let configLabelKey: string = key;\n\n  if (\n    key in payload &&\n    typeof payload[key as keyof typeof payload] === \"string\"\n  ) {\n    configLabelKey = payload[key as keyof typeof payload] as string;\n  } else if (\n    payloadPayload &&\n    key in payloadPayload &&\n    typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n  ) {\n    configLabelKey = payloadPayload[\n      key as keyof typeof payloadPayload\n    ] as string;\n  }\n\n  return configLabelKey in config\n    ? config[configLabelKey]\n    : config[key as keyof typeof config];\n}\n\nexport {\n  ChartContainer,\n  ChartTooltip,\n  ChartTooltipContent,\n  ChartLegend,\n  ChartLegendContent,\n  ChartStyle,\n};\n"}