diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/ConnectAnalyticsDashboard.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/ConnectAnalyticsDashboard.tsx index e2325a54eb4..e1cf34d7280 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/ConnectAnalyticsDashboard.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/ConnectAnalyticsDashboard.tsx @@ -1,42 +1,201 @@ "use client"; +import { DatePickerWithRange } from "@/components/ui/DatePickerWithRange"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { useWalletUsageAggregate, useWalletUsagePeriod, } from "@3rdweb-sdk/react/hooks/useApi"; -import { useMemo } from "react"; +import { differenceInDays, format, subDays } from "date-fns"; +import { useState } from "react"; import { ConnectAnalyticsDashboardUI } from "./ConnectAnalyticsDashboardUI"; export function ConnectAnalyticsDashboard(props: { clientId: string; }) { - const allTimeFrom = useMemo( - () => new Date(Date.now() - 135 * 24 * 60 * 60 * 1000), - [], + const [range, setRange] = useState(() => + getLastNDaysRange("last-120"), ); - const from = useMemo( - () => new Date(Date.now() - 135 * 24 * 60 * 60 * 1000), - [], + + // use date-fns to calculate the number of days in the range + const daysInRange = differenceInDays(range.to, range.from); + + const [intervalType, setIntervalType] = useState<"day" | "week">( + daysInRange > 30 ? "week" : "day", ); - const to = useMemo(() => new Date(), []); + const walletUsageQuery = useWalletUsagePeriod({ clientId: props.clientId, - from, - to, - period: "day", + from: range.from, + to: range.to, + period: intervalType, }); + const walletUsageAggregateQuery = useWalletUsageAggregate({ clientId: props.clientId, - from: allTimeFrom, - to, + from: range.from, + to: range.to, }); return ( - +
+ { + setRange(newRange); + const days = differenceInDays(newRange.to, newRange.from); + setIntervalType(days > 30 ? "week" : "day"); + }} + /> + +
+
+ +
+ ); +} + +const durationPresets = [ + { + name: "Last 7 Days", + id: "last-7", + days: 7, + }, + { + name: "Last 30 Days", + id: "last-30", + days: 30, + }, + { + name: "Last 60 Days", + id: "last-60", + days: 60, + }, + { + name: "Last 120 Days", + id: "last-120", + days: 120, + }, +] as const; + +type DurationId = (typeof durationPresets)[number]["id"]; + +type Range = { + type: DurationId | "custom"; + label?: string; + from: Date; + to: Date; +}; + +function getLastNDaysRange(id: DurationId) { + const durationInfo = durationPresets.find((preset) => preset.id === id); + if (!durationInfo) { + throw new Error("Invalid duration id"); + } + + const todayDate = new Date(); + + const value: Range = { + type: id, + from: subDays(todayDate, durationInfo.days), + to: todayDate, + label: durationInfo.name, + }; + + return value; +} + +function DateRangeSelector(props: { + range: Range; + setRange: (range: Range) => void; +}) { + const { range, setRange } = props; + + return ( + + setRange({ + from, + to: range.to, + type: "custom", + }) + } + setTo={(to) => + setRange({ + from: range.from, + to, + type: "custom", + }) } + header={ +
+ +
+ } + labelOverride={range.label} + className="w-auto" /> ); } + +function IntervalSelector(props: { + intervalType: "day" | "week"; + setIntervalType: (intervalType: "day" | "week") => void; +}) { + return ( + + ); +} diff --git a/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx b/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx index bd41a34fb11..bdcdaa7574a 100644 --- a/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx +++ b/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx @@ -8,7 +8,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { format } from "date-fns"; +import { format, subDays } from "date-fns"; import { useState } from "react"; import { PayCustomersTable } from "./components/PayCustomersTable"; import { PayNewCustomers } from "./components/PayNewCustomers"; @@ -125,19 +125,15 @@ export function PayAnalytics(props: { clientId: string }) { } function getLastNDaysRange(id: DurationId) { - const todayDate = new Date(); - const pastDate = new Date(todayDate); - const durationInfo = durationPresets.find((preset) => preset.id === id); if (!durationInfo) { throw new Error("Invalid duration id"); } - pastDate.setDate(todayDate.getDate() - durationInfo.days); - + const todayDate = new Date(); const value: Range = { type: id, - from: pastDate, + from: subDays(todayDate, durationInfo.days), to: todayDate, label: durationInfo.name, }; @@ -148,35 +144,6 @@ function getLastNDaysRange(id: DurationId) { function Filters(props: { range: Range; setRange: (range: Range) => void }) { const { range, setRange } = props; - const presets = ( -
- -
- ); - return (
void }) { type: "custom", }) } - header={presets} + header={ +
+ +
+ } labelOverride={range.label} className="w-auto border-none p-0" />