Skip to content

Commit

Permalink
Update analytics cards
Browse files Browse the repository at this point in the history
  • Loading branch information
TWilson023 committed May 31, 2024
1 parent 20db0ed commit 5876955
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 66 deletions.
5 changes: 4 additions & 1 deletion apps/web/lib/analytics/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import z from "../zod";
import { analyticsQuerySchema } from "../zod/schemas/analytics";
import { VALID_ANALYTICS_ENDPOINTS, intervals } from "./constants";
import { EVENT_TYPES, VALID_ANALYTICS_ENDPOINTS, intervals } from "./constants";

export type IntervalOptions = (typeof intervals)[number];
export type AnalyticsGroupByOptions =
Expand All @@ -10,6 +10,9 @@ export type CompositeAnalyticsResponseOptions =
| "leads"
| "sales"
| "amount";

export type EventType = (typeof EVENT_TYPES)[number];

export type LocationTabs = "countries" | "cities";
export type TopLinksTabs = "link" | "url";
export type DeviceTabs = "devices" | "browsers" | "os";
Expand Down
56 changes: 8 additions & 48 deletions apps/web/ui/analytics/analytics-card.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import useWorkspace from "@/lib/swr/use-workspace";
import { EventType } from "@/lib/analytics/types";
import { Modal, TabSelect } from "@dub/ui";
import { Crosshairs, CursorRays, InvoiceDollar } from "@dub/ui/src/icons";
import { cn } from "@dub/utils";
import { capitalize, cn } from "@dub/utils";
import {
ComponentType,
Dispatch,
ReactNode,
SVGProps,
SetStateAction,
useContext,
useMemo,
useState,
} from "react";
import { AnalyticsContext } from ".";

type EventType = "clicks" | "leads" | "sales";

export function AnalyticsCard<T extends string>({
tabs,
selectedTabId,
Expand All @@ -32,34 +26,15 @@ export function AnalyticsCard<T extends string>({
hasMore?: boolean;
children: (props: {
limit?: number;
event: EventType;
event?: EventType;
setShowModal: (show: boolean) => void;
}) => ReactNode;
className?: string;
}) {
const { demo } = useContext(AnalyticsContext);
const { betaTester } = useWorkspace();
const { selectedTab: event } = useContext(AnalyticsContext);

const [showModal, setShowModal] = useState(false);

const eventTabs: {
id: EventType;
icon: ComponentType<SVGProps<SVGSVGElement>>;
label: string;
}[] = useMemo(
() =>
demo || betaTester
? [
{ id: "clicks", icon: CursorRays, label: "Clicks" },
{ id: "leads", icon: Crosshairs, label: "Leads" },
{ id: "sales", icon: InvoiceDollar, label: "Sales" },
]
: [{ id: "clicks", icon: CursorRays, label: "Clicks" }],
[demo, betaTester],
);

const [eventTab, setEventTab] = useState<EventType>("clicks");

const selectedTab = tabs.find(({ id }) => id === selectedTabId);

return (
Expand All @@ -72,7 +47,7 @@ export function AnalyticsCard<T extends string>({
<div className="border-b border-gray-200 px-6 py-4">
<h1 className="text-lg font-semibold">{selectedTab?.label}</h1>
</div>
{children({ event: eventTab, setShowModal })}
{children({ setShowModal, event })}
</Modal>
<div
className={cn(
Expand All @@ -88,27 +63,12 @@ export function AnalyticsCard<T extends string>({
onSelect={onSelectTab}
/>

{/* Event (clicks, leads, sales) tabs */}
<div className="flex gap-2">
{eventTabs.map(({ id, icon: Icon, label }) => (
<button
key={id}
onClick={() => setEventTab(id)}
title={label}
className={cn(
"rounded-md border border-white p-2",
id === eventTab
? "border-gray-200 bg-gray-100"
: "hover:bg-gray-100 active:border-gray-100",
)}
>
<Icon className="h-4 w-4" />
</button>
))}
<div className="flex items-center gap-2 pr-2 text-xs uppercase text-gray-500">
{capitalize(event === "composite" ? "clicks" : event)}
</div>
</div>
<div className="py-4">
{children({ limit: expandLimit, event: eventTab, setShowModal })}
{children({ limit: expandLimit, event, setShowModal })}
</div>
{hasMore && (
<div className="absolute bottom-0 left-0 z-10 flex w-full items-end">
Expand Down
6 changes: 3 additions & 3 deletions apps/web/ui/analytics/devices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function Devices() {
expandLimit={8}
hasMore={(data?.length ?? 0) > 8}
>
{({ limit, event, setShowModal }) =>
{({ limit, setShowModal }) =>
data ? (
data.length > 0 ? (
<BarList
Expand All @@ -48,10 +48,10 @@ export default function Devices() {
},
getNewPath: true,
}) as string,
value: d[event] || 0,
value: d.count || 0,
})) || []
}
maxValue={(data && data[0]?.[event]) || 0}
maxValue={(data && data[0]?.count) || 0}
barBackground="bg-green-100"
hoverBackground="hover:bg-gradient-to-r hover:from-green-50 hover:to-transparent hover:border-green-500"
setShowModal={setShowModal}
Expand Down
23 changes: 18 additions & 5 deletions apps/web/ui/analytics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
2. Public stats page, e.g. dub.co/stats/github, stey.me/stats/weathergpt
*/

import { VALID_ANALYTICS_FILTERS } from "@/lib/analytics/constants";
import { CompositeAnalyticsResponseOptions } from "@/lib/analytics/types";
import {
EVENT_TYPES,
VALID_ANALYTICS_FILTERS,
} from "@/lib/analytics/constants";
import {
CompositeAnalyticsResponseOptions,
EventType,
} from "@/lib/analytics/types";
import { editQueryString } from "@/lib/analytics/utils";
import useWorkspace from "@/lib/swr/use-workspace";
import { fetcher } from "@dub/utils";
Expand All @@ -27,7 +33,7 @@ import TopLinks from "./top-links";
export const AnalyticsContext = createContext<{
basePath: string;
baseApiPath: string;
selectedTab: string;
selectedTab: EventType;
domain?: string;
key?: string;
url?: string;
Expand Down Expand Up @@ -99,8 +105,15 @@ export default function Analytics({
const interval =
start || end ? undefined : searchParams?.get("interval") ?? "24h";

const selectedTab =
demo || betaTester ? searchParams.get("tab") || "composite" : "clicks";
const selectedTab: EventType = useMemo(() => {
if (!demo && !betaTester) return "clicks";

const tab = searchParams.get("tab");

return tab && (EVENT_TYPES as ReadonlyArray<string>).includes(tab)
? (tab as EventType)
: "composite";
}, [searchParams.get("tab")]);

const { basePath, domain, baseApiPath } = useMemo(() => {
if (admin) {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/ui/analytics/locations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function Locations() {
expandLimit={8}
hasMore={(data?.length ?? 0) > 8}
>
{({ limit, event, setShowModal }) =>
{({ limit, setShowModal }) =>
data ? (
data.length > 0 ? (
<BarList
Expand All @@ -46,10 +46,10 @@ export default function Locations() {
},
getNewPath: true,
}) as string,
value: d[event] || 0,
value: d.count || 0,
})) || []
}
maxValue={(data && data[0]?.[event]) || 0}
maxValue={(data && data[0]?.count) || 0}
barBackground="bg-blue-100"
hoverBackground="hover:bg-gradient-to-r hover:from-blue-50 hover:to-transparent hover:border-blue-500"
setShowModal={setShowModal}
Expand Down
6 changes: 3 additions & 3 deletions apps/web/ui/analytics/referer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default function Referer() {
expandLimit={8}
hasMore={(data?.length ?? 0) > 8}
>
{({ limit, event, setShowModal }) =>
{({ limit, setShowModal }) =>
data ? (
data.length > 0 ? (
<BarList
Expand All @@ -129,10 +129,10 @@ export default function Referer() {
},
getNewPath: true,
}) as string,
value: d[event] || 0,
value: d.count || 0,
})) || []
}
maxValue={(data && data[0]?.[event]) || 0}
maxValue={(data && data[0]?.count) || 0}
barBackground="bg-red-100"
hoverBackground="hover:bg-gradient-to-r hover:from-red-50 hover:to-transparent hover:border-red-500"
setShowModal={setShowModal}
Expand Down
6 changes: 3 additions & 3 deletions apps/web/ui/analytics/top-links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function TopLinks() {
showUrls ? null : setSelectedTabId(tabId)
}
>
{({ limit, event, setShowModal }) =>
{({ limit, setShowModal }) =>
data ? (
data.length > 0 ? (
<BarList
Expand All @@ -66,11 +66,11 @@ export default function TopLinks() {
},
getNewPath: true,
}) as string,
value: d[event] || 0,
value: d.count || 0,
...(!showUrls && { linkData: d }),
})) || []
}
maxValue={(data && data[0]?.[event]) || 0}
maxValue={(data && data[0]?.count) || 0}
barBackground="bg-orange-100"
hoverBackground="hover:bg-gradient-to-r hover:from-orange-50 hover:to-transparent hover:border-orange-500"
setShowModal={setShowModal}
Expand Down

0 comments on commit 5876955

Please sign in to comment.