Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add stacking dao amounts / month #18

Merged
merged 3 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading