Skip to content

Commit

Permalink
Michalstruck dev 1144 add analytics page (#971)
Browse files Browse the repository at this point in the history
* DEV-1144 split app dashboard to ssr

* DEV-1144 split app dashboard to ssr

* DEV-1144 further split components for server side rendering, global ranking logic

* Makefile DX improvements

* DEV-1144 global rank on verified only

* DEV-1144 working top stats

* Fix chart object merging

* DEV-1144 graphs reworked

* DEV-1144 responsive statcards

* DEV-1144 general logic, calculations, chart and stat styling, simplified data retrieval

* DEV-1144 fix types
  • Loading branch information
michalstruck authored Oct 11, 2024
1 parent b397c05 commit 1aa8826
Show file tree
Hide file tree
Showing 23 changed files with 954 additions and 473 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ up:

hasura-console:
cd hasura; hasura console --endpoint http://localhost:8080 --admin-secret secret!

hasura-migrate:
cd hasura; hasura migrate apply --admin-secret secret!

hasura-seed:
cd hasura; hasura seed apply --admin-secret secret!

hasura-metadata:
cd hasura; hasura metadata export --admin-secret secret!
8 changes: 8 additions & 0 deletions web/api/v2/public/apps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ import {
} from "./graphql/get-app-rankings.generated";
import { getSdk as getHighlightsSdk } from "./graphql/get-app-web-highlights.generated";

export type GetAppsResponse = {
app_rankings: {
top_apps: ReturnType<typeof rankApps>;
highlights: ReturnType<typeof rankApps>;
};
categories: ReturnType<typeof getAllLocalisedCategories>;
};

const queryParamsSchema = yup.object({
page: yup.number().integer().min(1).default(1).notRequired(),
limit: yup.number().integer().min(1).max(500).notRequired().default(250),
Expand Down
9 changes: 3 additions & 6 deletions web/components/Chart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import { mergeDeep } from "@apollo/client/utilities";
import {
CategoryScale,
ChartData,
Expand Down Expand Up @@ -105,7 +106,6 @@ const defaultOptions: ChartOptions<"line"> = {
size: 12,
},
precision: 0,

maxTicksLimit: 5,
},
},
Expand All @@ -117,7 +117,6 @@ export const Chart = (props: ChartProps) => {
() => ({
labels: props.data.x,
datasets: props.data.y.map((dataset) => ({
...dataset,
pointRadius: dataset.data.length === 1 ? 5 : dataset.pointRadius,
pointHoverRadius:
dataset.data.length === 1 ? 5 : dataset.pointHoverRadius,
Expand All @@ -134,6 +133,7 @@ export const Chart = (props: ChartProps) => {
gradient.addColorStop(1, "rgba(251, 251, 252, 0)");
return gradient;
},
...dataset,
})),
}),
[props.data.x, props.data.y],
Expand All @@ -144,10 +144,7 @@ export const Chart = (props: ChartProps) => {
return defaultOptions;
}

return {
...defaultOptions,
...props.options,
};
return mergeDeep(defaultOptions, props.options);
}, [props.options]);

return <Line options={options} data={data} />;
Expand Down
6 changes: 6 additions & 0 deletions web/components/Typography/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { twMerge } from "tailwind-merge";

// NOTE: these namings come from Figma
export enum TYPOGRAPHY {
H3 = "h3",
H4 = "h4",
H5 = "h5",
H6 = "h6",
H7 = "h7",

Expand Down Expand Up @@ -45,8 +47,12 @@ export const Typography = <T extends ElementType = "span">(
<Component
className={twMerge(
clsx(className, {
"font-twk text-5xl font-medium leading-[1.3]":
variant === TYPOGRAPHY.H3,
"font-twk text-4xl font-medium leading-[1.3]":
variant === TYPOGRAPHY.H4,
"font-twk text-3xl font-medium leading-[1.3]":
variant === TYPOGRAPHY.H5,
"font-twk text-2xl font-medium leading-[1.3]":
variant === TYPOGRAPHY.H6,
"font-twk text-lg font-medium leading-[1.3]":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,7 @@ export const AppTopBar = (props: AppTopBarProps) => {
isDeveloperAllowListing={appMetaData?.is_developer_allow_listing}
/>
<div className="grid items-center justify-items-center gap-y-4 sm:grid-cols-auto/1fr/auto sm:justify-items-start sm:gap-x-8">
<ReviewMessageDialog
message={appMetaData.review_message}
metadataId={appMetaData.id}
/>
<ReviewMessageDialog appId={appId} />
<div className="flex w-full justify-end sm:hidden">
<AppStatus
className=""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"use server";

import { logger } from "@/lib/logger";
import { PaymentMetadata } from "@/lib/types";
import { createSignedFetcher } from "aws-sigv4-fetch";

export type GetAccumulativeTransactionDataReturnType = Awaited<
ReturnType<typeof getAccumulativeTransactionData>
>;

export const getAccumulativeTransactionData = async (
appId: string,
): Promise<{
accumulativeTransactions: PaymentMetadata[];
accumulatedAmountUSD: number;
}> => {
try {
if (!process.env.NEXT_SERVER_INTERNAL_PAYMENTS_ENDPOINT) {
throw new Error("Internal payments endpoint must be set.");
}

const signedFetch = createSignedFetcher({
service: "execute-api",
region: process.env.TRANSACTION_BACKEND_REGION,
});

let url = `${process.env.NEXT_SERVER_INTERNAL_PAYMENTS_ENDPOINT}/miniapp?miniapp-id=${appId}`;

const response = await signedFetch(url, {
method: "GET",
headers: {
"User-Agent": "DevPortal/1.0",
"Content-Type": "application/json",
},
});

const data = await response.json();
if (!response.ok) {
throw new Error(
`Failed to fetch transaction data. Status: ${response.status}. Error: ${data}`,
);
}

const sortedTransactions = (data?.result?.transactions || []).sort(
(a: PaymentMetadata, b: PaymentMetadata) =>
new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),
) as PaymentMetadata[];

let accumulatedTokenAmount = 0;
const accumulativeTransactions = sortedTransactions.map((transaction) => {
// TODO - floating point issues here? test on real data
accumulatedTokenAmount += Number(transaction.inputTokenAmount);

return {
...transaction,
inputTokenAmount: String(accumulatedTokenAmount),
};
});

const tokenPriceResponse = (await (
await fetch(
`${process.env.NEXT_PUBLIC_PRICES_ENDPOINT}?cryptoCurrencies=WLD&fiatCurrencies=USD`,
)
).json()) as {
result: {
prices: { WLD: { USD: { amount: string; decimals: number } } };
};
};

const accumulatedAmountUSD =
(accumulatedTokenAmount *
Number(tokenPriceResponse.result.prices.WLD.USD.amount)) /
10 ** tokenPriceResponse.result.prices.WLD.USD.decimals;

return {
accumulativeTransactions,
accumulatedAmountUSD,
};
} catch (error) {
logger.warn("Error fetching transaction data", { error });
return {
accumulativeTransactions: [],
accumulatedAmountUSD: 0,
};
}
};
Loading

0 comments on commit 1aa8826

Please sign in to comment.