Design
llms.txt digitalcrew.tech

Analytics

ActivityChart

A day-bucketed Recharts chart in Max's glass panel: each series is drawn as an area, a line or a bar, with a dot legend and a popover tooltip.

MaxAnalyticsDigitalCrew.ActivityChart
ActivityChart · live · 960px wideOpen

Guidelines#

Use it for activity over a period on the analytics page, a campaign's performance tab and detail sheets.

What you provide: title (a 12px uppercase overline), data (one point per day, date as YYYY-MM-DD plus numeric keys; the default point type is AnalyticsTimeseriesPointDto), series ({ key, label, color, kind: "area" | "line" | "bar" }) and isLoading. Take the presets from chart-series.ts: VOLUME_SERIES, ENGAGEMENT_SERIES, DEALS_SERIES, with colours C1–C4 = var(--chart-1…4).

Anatomy: glass-panel glass-hover border border-glass rounded-3xl px-6 py-6. The plot is 280px tall. The grid is dashed 3 3, horizontal only, drawn in var(--border) at 50% opacity. Axis ticks are 11px muted-foreground with no axis or tick lines. The X axis reads MMM d with a 32px minimum tick gap. The Y axis is 48px wide and shows integers only. Areas are monotone with a 2px stroke and 12% fill. Lines are 2px with no dots and a 4px active dot. Bars have [4,4,0,0] radii and a maximum width of 24px. The tooltip is rounded-xl border-glass bg-popover shadow-md.

States: while isLoading, a 280px Skeleton (rounded-2xl) replaces the chart. When no series has a value above 0, a dashed box reads "No activity in this period".

Don't hard-code hex colours; pass the --chart-N variables so the chart follows the theme. Don't expect stacking: areas overlap.

Facts#

GroupAnalytics
ProductMax
Globalwindow.DigitalCrew.ActivityChart
Sourcemax-agent: src/features/analytics/ui/activity-chart.tsx
Import in the appimport { ActivityChart } from "@/features/analytics/ui/activity-chart";

API#

TypeScript declarations emitted from src/features/analytics/ui/activity-chart.tsx.

/** A day-bucketed point: the date key plus numeric series values. */
export type ChartPoint = {
    date: string;
};
export interface ChartSeries<Point extends ChartPoint = AnalyticsTimeseriesPointDto> {
    key: Exclude<keyof Point, "date"> & string;
    label: string;
    /** CSS color (use the theme's --chart-N variables) */
    color: string;
    kind: "area" | "line" | "bar";
}
export declare function ActivityChart<Point extends ChartPoint = AnalyticsTimeseriesPointDto>({ title, data, series, isLoading, }: {
    title: string;
    data: Point[];
    series: ChartSeries<Point>[];
    isLoading: boolean;
}): JSX.Element;

Example#

The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.

<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  // VOLUME_SERIES from src/features/analytics/ui/chart-series.ts
  var SERIES = [
    { key: "email_sent", label: "Emails sent", color: "var(--chart-1)", kind: "area" },
    { key: "linkedin_invitations_sent", label: "LinkedIn invitations", color: "var(--chart-2)", kind: "area" },
    { key: "linkedin_messages_sent", label: "LinkedIn messages", color: "var(--chart-3)", kind: "area" }
  ];
  // Sat 12 Sep to Fri 25 Sep 2026: quiet weekends, busy weekdays.
  var SENT = [18, 12, 212, 236, 248, 231, 204, 22, 15, 244, 262, 275, 258, 221];
  var INV = [4, 2, 58, 64, 61, 66, 52, 5, 3, 67, 72, 70, 74, 60];
  var MSG = [6, 3, 41, 47, 52, 44, 38, 7, 4, 49, 55, 58, 53, 46];
  // One AnalyticsTimeseriesPointDto per day (every field of the DTO is present).
  var DATA = SENT.map(function (sent, i) {
    return {
      date: new Date(Date.UTC(2026, 8, 12 + i)).toISOString().slice(0, 10),
      email_sent: sent,
      email_opened: Math.round(sent * 0.52),
      email_replied: Math.round(sent * 0.041),
      linkedin_invitations_sent: INV[i],
      linkedin_connections: Math.round(INV[i] * 0.38),
      linkedin_messages_sent: MSG[i],
      linkedin_replies: Math.round(MSG[i] * 0.12),
      whatsapp_messages_sent: 0,
      whatsapp_replies: 0,
      meetings_booked: i % 3 === 0 ? 1 : 2,
      deals_created: 0,
      deals_won: 0,
      prospect_lists_created: 0,
      signals_detected: 0
    };
  });
  function App() {
    return h(DC.ActivityChart, { title: "Outreach volume", data: DATA, series: SERIES, isLoading: false });
  }
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>