diff --git a/ui/litellm-dashboard/src/components/usage.tsx b/ui/litellm-dashboard/src/components/usage.tsx
index 5908ef10d..221fbdda3 100644
--- a/ui/litellm-dashboard/src/components/usage.tsx
+++ b/ui/litellm-dashboard/src/components/usage.tsx
@@ -1,9 +1,9 @@
import { BarChart, Card, Title } from "@tremor/react";
import React, { useState, useEffect } from "react";
-import { Grid, Col, Text } from "@tremor/react";
+import { Grid, Col, Text, LineChart } from "@tremor/react";
import { userSpendLogsCall } from "./networking";
-import { AreaChart, Flex, Switch, Subtitle } from "@tremor/react";
+import { start } from "repl";
interface UsagePageProps {
accessToken: string | null;
@@ -12,12 +12,65 @@ interface UsagePageProps {
userID: string | null;
}
-type DataType = {
- api_key: string;
- startTime: string;
- _sum: {
- spend: number;
- };
+type CustomTooltipTypeBar = {
+ payload: any;
+ active: boolean | undefined;
+ label: any;
+};
+
+const customTooltip = (props: CustomTooltipTypeBar) => {
+ const { payload, active } = props;
+ if (!active || !payload) return null;
+
+ const value = payload[0].payload;
+ const date = value["startTime"];
+
+ // Convert the object into an array of key-value pairs
+ const entries: [string, number][] = Object.entries(value)
+ .filter(([key]) => key !== "spend" && key !== "startTime")
+ .map(([key, value]) => [key, value as number]); // Type assertion to specify the value as number
+
+ // Sort the array based on the float value in descending order
+ entries.sort((a, b) => b[1] - a[1]);
+
+ // Get the top 5 key-value pairs
+ const topEntries = entries.slice(0, 5);
+
+ return (
+
+ {date}
+ {topEntries.map(([key, value]) => (
+
+
+
+ Token: {key.substring(0, 4)}{" "}
+
+ Spend: {value}
+
+
+
+
+ ))}
+
+ );
+
+ // return (
+ //
+ // {payload.map((category: any, idx: number) => {
+ //
+ //
+ //
+ //
{category.dataKey}
+ //
+ // {category.value} bpm
+ //
+ //
+ //
;
+ // })}
+ //
+ // );
};
const UsagePage: React.FC = ({
@@ -28,6 +81,7 @@ const UsagePage: React.FC = ({
}) => {
const currentDate = new Date();
const [keySpendData, setKeySpendData] = useState([]);
+ const [keyCategories, setKeyCategories] = useState([]);
const firstDay = new Date(
currentDate.getFullYear(),
@@ -63,32 +117,42 @@ const UsagePage: React.FC = ({
useEffect(() => {
if (accessToken && token && userRole && userID) {
- const cachedKeySpendData = localStorage.getItem("keySpendData");
- if (cachedKeySpendData) {
- setKeySpendData(JSON.parse(cachedKeySpendData));
- } else {
- const fetchData = async () => {
- try {
- const response = await userSpendLogsCall(
- accessToken,
- token,
- userRole,
- userID,
- startTime,
- endTime
- );
- setKeySpendData(response);
- localStorage.setItem("keySpendData", JSON.stringify(response));
- } catch (error) {
- console.error("There was an error fetching the data", error);
- // Optionally, update your UI to reflect the error state here as well
- }
- };
- fetchData();
- }
+ const fetchData = async () => {
+ try {
+ const response = await userSpendLogsCall(
+ accessToken,
+ token,
+ userRole,
+ userID,
+ startTime,
+ endTime
+ );
+
+ const uniqueKeys: Set = new Set();
+
+ response.forEach((item: any) => {
+ Object.keys(item).forEach((key) => {
+ if (key !== "spend" && key !== "startTime") {
+ uniqueKeys.add(key);
+ }
+ });
+ });
+ let uniqueKeysList = Array.from(uniqueKeys);
+ setKeyCategories(uniqueKeysList);
+ setKeySpendData(response);
+ // localStorage.setItem("keySpendData", JSON.stringify(response));
+ // localStorage.setItem(
+ // "keyCategories",
+ // JSON.stringify(uniqueKeysList)
+ // );
+ } catch (error) {
+ console.error("There was an error fetching the data", error);
+ // Optionally, update your UI to reflect the error state here as well
+ }
+ };
+ fetchData();
}
}, [accessToken, token, userRole, userID]);
-
return (
@@ -103,6 +167,7 @@ const UsagePage: React.FC = ({
valueFormatter={valueFormatter}
yAxisWidth={100}
tickGap={5}
+ customTooltip={customTooltip}
/>