Skip to content

Commit

Permalink
feat: add stacking dao amounts / month (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
pradel authored Mar 30, 2024
1 parent 531f82f commit ad4b881
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/app/api/chainhooks/arkadiko/add-liquidity/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { db } from "@/db/db";
import { type InsertTransaction, transactionTable } from "@/db/schema";
import { getOrInsertToken } from "@/db/token";
import type {
ChainhookPayload,
ChainhookReceiptEventFTTransferEvent,
ChainhookReceiptEventSTXTransferEvent,
} from "@/lib/chainhooks";
import { getOrInsertToken } from "@/lib/currencies";

export const dynamic = "force-dynamic";

Expand Down
2 changes: 1 addition & 1 deletion src/app/api/chainhooks/arkadiko/remove-liquidity/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { db } from "@/db/db";
import { type InsertTransaction, transactionTable } from "@/db/schema";
import { getOrInsertToken } from "@/db/token";
import type {
ChainhookPayload,
ChainhookReceiptEventFTTransferEvent,
ChainhookReceiptEventSTXTransferEvent,
} from "@/lib/chainhooks";
import { getOrInsertToken } from "@/lib/currencies";

export const dynamic = "force-dynamic";

Expand Down
2 changes: 1 addition & 1 deletion src/app/api/chainhooks/stackingdao/deposit/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { db } from "@/db/db";
import { type InsertTransaction, transactionTable } from "@/db/schema";
import { getOrInsertToken } from "@/db/token";
import { conflictUpdateSetAllColumns } from "@/db/utils";
import type {
ChainhookPayload,
ChainhookReceiptEventFTMintEvent,
ChainhookReceiptEventSTXTransferEvent,
} from "@/lib/chainhooks";
import { getOrInsertToken } from "@/lib/currencies";

export const dynamic = "force-dynamic";

Expand Down
2 changes: 1 addition & 1 deletion src/app/api/chainhooks/stackingdao/withdraw/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { db } from "@/db/db";
import { type InsertTransaction, transactionTable } from "@/db/schema";
import { getOrInsertToken } from "@/db/token";
import { conflictUpdateSetAllColumns } from "@/db/utils";
import type {
ChainhookPayload,
ChainhookReceiptEventFTBurnEvent,
ChainhookReceiptEventSTXTransferEvent,
} from "@/lib/chainhooks";
import { getOrInsertToken } from "@/lib/currencies";

export const dynamic = "force-dynamic";

Expand Down
2 changes: 1 addition & 1 deletion src/app/api/chainhooks/swap/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { db } from "@/db/db";
import { type InsertTransaction, transactionTable } from "@/db/schema";
import { getOrInsertToken } from "@/db/token";
import { conflictUpdateSetAllColumns } from "@/db/utils";
import type {
ChainhookPayload,
ChainhookReceiptEventFTTransferEvent,
ChainhookReceiptEventSTXTransferEvent,
} from "@/lib/chainhooks";
import { getOrInsertToken } from "@/lib/currencies";
import type { Protocol } from "@/lib/protocols";

export const dynamic = "force-dynamic";
Expand Down
43 changes: 9 additions & 34 deletions src/app/protocols/[protocol]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { ProtocolInfo } from "@/components/Protocol/ProtocolInfo";
import { UniqueUsersBarChart } from "@/components/Stats/UniqueUsersBarChart";
import { DepositWithdrawBarChart } from "@/components/Stats/stackingdao/DepositsWithdrawBarChart";
import { TransactionRow } from "@/components/Transaction/TransactionRow";
import { getTransactions, getTransactionsStats } from "@/db/transactions";
import {
Expand All @@ -13,13 +15,10 @@ import {
Card,
Container,
Heading,
IconButton,
Separator,
Text,
} from "@radix-ui/themes";
import { IconBrandX, IconWorld } from "@tabler/icons-react";
import type { Metadata } from "next";
import Image from "next/image";
import NextLink from "next/link";
import { notFound } from "next/navigation";
import { Fragment, Suspense } from "react";
Expand Down Expand Up @@ -61,41 +60,11 @@ export default async function ProtocolPage({
getTransactions({ protocol, action: searchParams.action }),
getTransactionsStats({ protocol }),
]);
const protocolInfo = protocolsInfo[protocol];
const protocolActions = protocolsActions[protocol];

return (
<Container size="2" className="px-4 pt-10">
<div className="flex items-start gap-5">
<Image
className="rounded-full"
src={`/protocols/${protocol}.png`}
alt={`${protocol} logo`}
width={50}
height={50}
priority
/>
<div>
<Heading as="h1" size="5" color="gray" highContrast>
{protocolInfo.name}
</Heading>
<Text className="mt-1" as="p" size="2" color="gray">
{protocolInfo.description}
</Text>
<div className="mt-2 space-x-2">
<IconButton size="1" variant="ghost" color="gray" asChild>
<a href={protocolInfo.website} target="_blank" rel="noreferrer">
<IconWorld size={14} />
</a>
</IconButton>
<IconButton size="1" variant="ghost" color="gray" asChild>
<a href={protocolInfo.x} target="_blank" rel="noreferrer">
<IconBrandX size={14} />
</a>
</IconButton>
</div>
</div>
</div>
<ProtocolInfo protocol={protocol} />

<div className="mt-5 grid grid-cols-2 gap-5">
<Card size="2">
Expand All @@ -120,6 +89,12 @@ export default async function ProtocolPage({
<UniqueUsersBarChart protocol={protocol} />
</Suspense>

{protocol === "stackingdao" ? (
<Suspense>
<DepositWithdrawBarChart />
</Suspense>
) : null}

<div className="mt-10">
<Heading as="h2" size="3" color="gray" highContrast>
Transactions
Expand Down
45 changes: 45 additions & 0 deletions src/components/Protocol/ProtocolInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Protocol, protocolsInfo } from "@/lib/protocols";
import { Heading, IconButton, Text } from "@radix-ui/themes";
import { IconBrandX, IconWorld } from "@tabler/icons-react";
import Image from "next/image";

interface ProtocolInfoProps {
protocol: Protocol;
}

export const ProtocolInfo = ({ protocol }: ProtocolInfoProps) => {
const protocolInfo = protocolsInfo[protocol];

return (
<div className="flex items-start gap-5">
<Image
className="rounded-full"
src={`/protocols/${protocol}.png`}
alt={`${protocol} logo`}
width={50}
height={50}
priority
/>
<div>
<Heading as="h1" size="5" color="gray" highContrast>
{protocolInfo.name}
</Heading>
<Text className="mt-1" as="p" size="2" color="gray">
{protocolInfo.description}
</Text>
<div className="mt-2 space-x-2">
<IconButton size="1" variant="ghost" color="gray" asChild>
<a href={protocolInfo.website} target="_blank" rel="noreferrer">
<IconWorld size={14} />
</a>
</IconButton>
<IconButton size="1" variant="ghost" color="gray" asChild>
<a href={protocolInfo.x} target="_blank" rel="noreferrer">
<IconBrandX size={14} />
</a>
</IconButton>
</div>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
import { BarChart } from "@/components/ui/BarChart";
import { numberValueFormatter } from "@/components/ui/utils";
import type { Protocol } from "@/lib/protocols";
import { Card, Inset, Separator, Text } from "@radix-ui/themes";

Expand Down Expand Up @@ -39,6 +40,7 @@ export const UniqueUsersBarChartClient = ({
index="date"
categories={[protocol]}
colors={["orange"]}
valueFormatter={numberValueFormatter}
/>
</Card>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";
import { BarChart } from "@/components/ui/BarChart";
import { displayPrice } from "@/lib/currencies";
import { Card, Inset, Separator, Text } from "@radix-ui/themes";

interface DepositWithdrawBarChartClientProps {
data: {
date: string;
withdrawals: number;
deposits: number;
}[];
}

export const DepositWithdrawBarChartClient = ({
data,
}: DepositWithdrawBarChartClientProps) => {
return (
<Card size="2" className="mt-5">
<Text as="div" size="2" weight="medium" color="gray" highContrast>
Deposits and Withdrawals in STX
</Text>
<Text className="mt-1" as="div" size="1" color="gray">
Amount of deposits and withdrawals made by users per month
</Text>
<Inset py="current" side="bottom">
<Separator size="4" />
</Inset>
<BarChart
className="mt-6 pr-3"
data={data}
index="date"
categories={["deposits", "withdrawals"]}
colors={["orange", "indigo"]}
valueFormatter={(value) => displayPrice(value, 6)}
/>
</Card>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { db } from "@/db/db";
import { transactionTable } from "@/db/schema";
import { eq, sql } from "drizzle-orm";
import { DepositWithdrawBarChartClient } from "./DepositWithdrawBarChartClient";

const getData = async () => {
const query = db
.select({
month: sql<string>`strftime('%Y-%m', timestamp, 'unixepoch') as month`,
depositsAmount: sql<number>`sum(case when action = 'stackingdao-deposit' then json->>'outAmount' else 0 end) as depositsAmount`,
withdrawalsAmount: sql<number>`sum(case when action = 'stackingdao-withdraw' then json->>'inAmount' else 0 end) as withdrawalsAmount`,
})
.from(transactionTable)
.where(eq(transactionTable.protocol, "stackingdao"))
.groupBy(sql`month`);

const stats = await query;
return stats;
};

export const DepositWithdrawBarChart = async () => {
const stats = await getData();

const formattedData: {
date: string;
withdrawals: number;
deposits: number;
}[] = stats.map((d) => ({
date: d.month,
withdrawals: d.withdrawalsAmount,
deposits: d.depositsAmount,
}));

return <DepositWithdrawBarChartClient data={formattedData} />;
};
9 changes: 6 additions & 3 deletions src/components/ui/BarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
XAxis,
YAxis,
} from "recharts";
import { constructCategoryColors } from "./utils";
import { constructCategoryColors, defaultValueFormatter } from "./utils";

interface BarChartProps {
className?: string;
Expand All @@ -18,6 +18,7 @@ interface BarChartProps {
categories: string[];
stack?: boolean;
colors: string[];
valueFormatter?: (value: number | string) => string;
}

export const BarChart = ({
Expand All @@ -27,6 +28,7 @@ export const BarChart = ({
categories,
stack,
colors,
valueFormatter = defaultValueFormatter,
}: BarChartProps) => {
const categoryColors = constructCategoryColors(categories, colors);

Expand Down Expand Up @@ -64,8 +66,9 @@ export const BarChart = ({
stroke=""
className="fill-gray-11 text-1"
tickMargin={8}
tickFormatter={valueFormatter}
/>
<Tooltip
<Tooltip<number, "unknown">
cursor={{ fill: "var(--gray-11)", opacity: "0.10" }}
content={({ label, payload }) => (
<div className="min-w-[150px] rounded-2 bg-[var(--color-background)] py-3">
Expand All @@ -87,7 +90,7 @@ export const BarChart = ({
<Text as="div" size="2" color="gray">
{p.name}:{" "}
<Text color="gray" highContrast>
{p.value?.toLocaleString("en-US")}
{p.value ? valueFormatter(p.value) : ""}
</Text>
</Text>
</div>
Expand Down
12 changes: 12 additions & 0 deletions src/components/ui/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export const themeColors: {
fillColor: "fill-orange-9",
bgColor: "bg-orange-9",
},
indigo: {
fillColor: "fill-indigo-9",
bgColor: "bg-indigo-9",
},
};

export const constructCategoryColors = (
Expand All @@ -22,3 +26,11 @@ export const constructCategoryColors = (
});
return categoryColors;
};

export const defaultValueFormatter = (value: number | string) => {
return value.toString();
};

export const numberValueFormatter = (value: number | string) => {
return value.toLocaleString("en-US");
};
Loading

0 comments on commit ad4b881

Please sign in to comment.