+
diff --git a/apps/web/app/(app)/organization/[organizationId]/stats/OrgStats.tsx b/apps/web/app/(app)/organization/[organizationId]/stats/OrgStats.tsx
new file mode 100644
index 0000000000..8bb7520167
--- /dev/null
+++ b/apps/web/app/(app)/organization/[organizationId]/stats/OrgStats.tsx
@@ -0,0 +1,229 @@
+"use client";
+
+import { useState, useMemo, useCallback } from "react";
+import type { DateRange } from "react-day-picker";
+import { subDays } from "date-fns/subDays";
+import { Mail, Sparkles, Users } from "lucide-react";
+import { LoadingContent } from "@/components/LoadingContent";
+import { Skeleton } from "@/components/ui/skeleton";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { DatePickerWithRange } from "@/components/DatePickerWithRange";
+import { useOrgStatsTotals } from "@/hooks/useOrgStatsTotals";
+import { useOrgStatsEmailBuckets } from "@/hooks/useOrgStatsEmailBuckets";
+import { useOrgStatsRulesBuckets } from "@/hooks/useOrgStatsRulesBuckets";
+
+const selectOptions = [
+ { label: "Last week", value: "7" },
+ { label: "Last month", value: "30" },
+ { label: "Last 3 months", value: "90" },
+ { label: "All time", value: "0" },
+];
+const defaultSelected = selectOptions[1];
+
+export function OrgStats({ organizationId }: { organizationId: string }) {
+ const [dateDropdown, setDateDropdown] = useState
(
+ defaultSelected.label,
+ );
+
+ const now = useMemo(() => new Date(), []);
+ const [dateRange, setDateRange] = useState({
+ from: subDays(now, Number.parseInt(defaultSelected.value)),
+ to: now,
+ });
+
+ const onSetDateDropdown = useCallback(
+ (option: { label: string; value: string }) => {
+ setDateDropdown(option.label);
+ },
+ [],
+ );
+
+ const options = useMemo(
+ () => ({
+ fromDate: dateRange?.from?.getTime(),
+ toDate: dateRange?.to?.getTime(),
+ }),
+ [dateRange],
+ );
+
+ const {
+ data: totalsData,
+ isLoading: totalsLoading,
+ error: totalsError,
+ } = useOrgStatsTotals(organizationId, options);
+
+ const {
+ data: emailBucketsData,
+ isLoading: emailBucketsLoading,
+ error: emailBucketsError,
+ } = useOrgStatsEmailBuckets(organizationId, options);
+
+ const {
+ data: rulesBucketsData,
+ isLoading: rulesBucketsLoading,
+ error: rulesBucketsError,
+ } = useOrgStatsRulesBuckets(organizationId, options);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+ {totalsData && (
+
+ }
+ />
+ }
+ />
+ }
+ />
+
+ )}
+
+
+
+ }
+ >
+ {emailBucketsData && (
+
+ )}
+
+
+ }
+ >
+ {rulesBucketsData && (
+
+ )}
+
+
+
+
+ );
+}
+
+function StatCard({
+ title,
+ value,
+ icon,
+}: {
+ title: string;
+ value: string;
+ icon: React.ReactNode;
+}) {
+ return (
+