Skip to content

Commit

Permalink
feat: add viewthrough and clickthrough reporting (#1023)
Browse files Browse the repository at this point in the history
* feat: add viewthrough and clickthrough reporting

* test: should only be 2 decimal places

* fix: update overview to convert from bignumber

* fix: remove filter from change

* fix: future code

* fix: make sure that overview are numbers

* fix: make sure we have maximum digits

* fix: rebase deleted file
  • Loading branch information
IanKrieger authored Jan 25, 2024
1 parent 384f2cc commit 050f131
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 211 deletions.
14 changes: 7 additions & 7 deletions src/components/Datagrid/renderers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { CampaignExtras } from "user/adSet/AdSetList";
import { FilterContext } from "state/context";
import { refetchAdvertiserCampaignsQuery } from "graphql/advertiser.generated";
import { UpdateAdSetInput } from "graphql/types";
import { toLocaleString } from "util/bignumber";
import BigNumber from "bignumber.js";

export type CellValueRenderer = (value: any) => ReactNode;
const ADS_DEFAULT_TIMEZONE = "America/New_York";
Expand Down Expand Up @@ -78,16 +80,14 @@ export const StandardRenderers: Record<string, CellValueRenderer> = {
};

export function renderMonetaryAmount(
value: number,
value: BigNumber | number,
currency: string,
): ReactNode {
) {
const val = BigNumber(value);
if (currency === "USD") {
return `$${value.toLocaleString("en", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`;
return `$${toLocaleString(val)}`;
} else {
return <span>{value.toLocaleString("en")}&nbsp;BAT</span>;
return `${toLocaleString(val)} ${currency}`;
}
}

Expand Down
49 changes: 41 additions & 8 deletions src/graphql/analytics-overview.generated.tsx

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions src/graphql/analytics-overview.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ fragment Engagement on Engagement {
creativeid
creativestate
creativepayload
count
view
click
viewthroughConversion
clickthroughConversion
conversion
dismiss
downvote
landed
spend
upvote
downvote
price
cost
android
ios
linux
Expand Down
12 changes: 1 addition & 11 deletions src/user/adSet/AdSetList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { Chip } from "@mui/material";
import { Status } from "components/Campaigns/Status";
import _ from "lodash";
import {
adSetOnOffState,
StandardRenderers,
} from "components/Datagrid/renderers";
import { adSetOnOffState } from "components/Datagrid/renderers";
import { CampaignAdsFragment } from "graphql/campaign.generated";
import { CampaignSource } from "graphql/types";
import { StatsMetric } from "user/analytics/analyticsOverview/types";
Expand Down Expand Up @@ -85,13 +82,6 @@ export function AdSetList({ campaign, loading, engagements }: Props) {
filterable: false,
width: 100,
},
{
field: "createdAt",
headerName: "Created",
valueGetter: ({ row }) => row.createdAt,
renderCell: ({ row }) => StandardRenderers.date(row.createdAt),
width: 120,
},
{
field: "name",
headerName: "Name",
Expand Down
12 changes: 4 additions & 8 deletions src/user/ads/AdList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { StatsMetric } from "user/analytics/analyticsOverview/types";
import { AdDetailTable } from "user/views/user/AdDetailTable";
import { GridColDef } from "@mui/x-data-grid";
import { CreativeFragment } from "graphql/creative.generated";
import { StandardRenderers } from "components/Datagrid/renderers";
import { Box } from "@mui/material";

interface Props {
Expand Down Expand Up @@ -48,16 +47,13 @@ export function AdList({ campaign, loading, engagements }: Props) {
const ads: AdDetails[] = _.flatMap(adSets, "ads");

const columns: GridColDef<AdDetails>[] = [
{
field: "createdAt",
headerName: "Created",
valueGetter: ({ row }) => row.creative.createdAt,
renderCell: ({ row }) => StandardRenderers.date(row.creative.createdAt),
},
{
field: "name",
headerName: "Ad Name",
valueGetter: ({ row }) => row.creative.name,
valueGetter: ({ row }) =>
row.adState !== "deleted"
? row.creative.name
: `(DELETED) ${row.creative.name}`,
renderCell: ({ row }) => (
<Box>
{row.adState === "deleted" && <strong>(DELETED) </strong>}
Expand Down
33 changes: 21 additions & 12 deletions src/user/analytics/analyticsOverview/components/LiveFeed.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Box, Chip, Typography } from "@mui/material";
import { OverviewDetail, StatsMetric } from "../types";
import { toLocaleString } from "util/bignumber";

interface OverviewProps extends OverviewDetail {
currency: string;
Expand All @@ -18,46 +19,54 @@ interface Feed {

export default function LiveFeed({ overview, processed }: LiveFeedProps) {
const { budget, currency } = overview;
const realSpend = processed.spend > budget ? budget : processed.spend;
const realSpend = processed.spend.gte(budget) ? budget : processed.spend;

const feedValues: Feed[] = [
{
label: "Click-through rate",
value: `${processed.ctr.toFixed(2)}%`,
value: `${toLocaleString(processed.ctr)}%`,
},
{
label: "Site visit rate",
value: `${processed.visitRate.toFixed(2)}%`,
value: `${toLocaleString(processed.visitRate)}%`,
},
{
label: "Dismissal rate",
value: `${processed.dismissRate.toFixed(2)}%`,
value: `${toLocaleString(processed.dismissRate)}%`,
},
{
label: "Click to site visit rate",
value: `${processed.landingRate.toFixed(2)}%`,
value: `${toLocaleString(processed.landingRate)}%`,
},
{ label: "Upvotes", value: `${processed.upvotes}` },
{ label: "Downvotes", value: `${processed.downvotes}` },
{ label: "Upvotes", value: toLocaleString(processed.upvotes) },
{ label: "Downvotes", value: toLocaleString(processed.downvotes) },
{
label: "Spend",
value: `${realSpend.toLocaleString()} ${currency}`,
value: `$${toLocaleString(realSpend)} ${currency}`,
},
{
label: "Budget",
value: `${budget.toLocaleString()} ${currency}`,
value: `$${toLocaleString(budget)} ${currency}`,
},
];

if (processed.conversions > 0) {
if (processed.conversions.gt(0)) {
feedValues.push(
{
label: "Conversions",
value: `${processed.conversions}`,
value: toLocaleString(processed.conversions),
},
{
label: "View-through Conversions",
value: toLocaleString(processed.viewthroughConversion),
},
{
label: "Click-through Conversions",
value: toLocaleString(processed.clickthroughConversion),
},
{
label: "CPA",
value: `$${processed.cpa.toLocaleString()}`,
value: `$${toLocaleString(processed.cpa)} ${currency}`,
},
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import MetricSelect from "user/analytics/analyticsOverview/components/MetricSele
import { Box, Stack, Switch, Tooltip, Typography } from "@mui/material";
import { decideValueAttribute } from "user/analytics/analyticsOverview/lib/overview.library";
import { Metrics, StatsMetric } from "user/analytics/analyticsOverview/types";
import { toLocaleString } from "util/bignumber";

type FilterMetric = {
key: keyof StatsMetric;
Expand Down Expand Up @@ -56,7 +57,7 @@ const FilterBox = ({
width="100%"
>
<Typography>
{attrs.prefix ?? ""} {displayVal} {attrs.suffix ?? ""}
{attrs.prefix ?? ""} {toLocaleString(displayVal)} {attrs.suffix ?? ""}
</Typography>
<Tooltip title={filter.active ? "Hide" : "Show"}>
<Switch
Expand Down
12 changes: 12 additions & 0 deletions src/user/analytics/analyticsOverview/components/MetricSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ export default function MetricSelect({
tooltip:
"Counted when a user reaches a designated conversion landing page",
},
{
value: "viewthroughConversion",
label: "View-through Conversions",
tooltip:
"Counted when a user reaches a designated conversion landing page following an ad impression.",
},
{
value: "clickthroughConversion",
label: "Click-through Conversions",
tooltip:
"Counted when a user reaches a designated conversion landing page following an impression and click of the ad.",
},
{
value: "dismissals",
label: "Dismissals",
Expand Down
4 changes: 4 additions & 0 deletions src/user/analytics/analyticsOverview/lib/ads.library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export function adEngagements(
for (const key in grouped) {
const group = grouped[key];
const stats = processStats(group);
if (!stats) {
continue;
}

metrics.set(key, stats);
}
return metrics;
Expand Down
4 changes: 4 additions & 0 deletions src/user/analytics/analyticsOverview/lib/creative.library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export function creativeEngagements(
const group = byCreative[key];
const payload = JSON.parse(group[0].creativepayload);
const reducedCreative = processStats(group);
if (!reducedCreative) {
continue;
}

metrics.push({
...reducedCreative,
creativePayload: {
Expand Down
Loading

0 comments on commit 050f131

Please sign in to comment.