import React, { useState, useEffect } from "react"; import { Card, Title, Subtitle, Table, TableHead, TableHeaderCell, TableRow, TableCell, TableBody, Tab, Text, TabGroup, TabList, TabPanels, Metric, Grid, TabPanel, Select, SelectItem, Dialog, DialogPanel, Icon, TextInput, } from "@tremor/react"; import { userInfoCall } from "./networking"; import { Badge, BadgeDelta, Button } from "@tremor/react"; import RequestAccess from "./request_model_access"; import CreateUser from "./create_user_button"; import Paragraph from "antd/es/skeleton/Paragraph"; import InformationCircleIcon from "@heroicons/react/outline/InformationCircleIcon"; interface ViewUserDashboardProps { accessToken: string | null; token: string | null; keys: any[] | null; userRole: string | null; userID: string | null; teams: any[] | null; setKeys: React.Dispatch>; } const ViewUserDashboard: React.FC = ({ accessToken, token, keys, userRole, userID, teams, setKeys, }) => { const [userData, setUserData] = useState(null); const [endUsers, setEndUsers] = useState(null); const [currentPage, setCurrentPage] = useState(0); const [openDialogId, setOpenDialogId] = React.useState(null); const [selectedItem, setSelectedItem] = useState(null); const defaultPageSize = 25; useEffect(() => { if (!accessToken || !token || !userRole || !userID) { return; } const fetchData = async () => { try { // Replace with your actual API call for model data const userDataResponse = await userInfoCall( accessToken, null, userRole, true, currentPage, defaultPageSize ); console.log("user data response:", userDataResponse); setUserData(userDataResponse); } catch (error) { console.error("There was an error fetching the model data", error); } }; if (accessToken && token && userRole && userID) { fetchData(); } }, [accessToken, token, userRole, userID, currentPage]); if (!userData) { return
Loading...
; } if (!accessToken || !token || !userRole || !userID) { return
Loading...
; } function renderPagination() { if (!userData) return null; const totalPages = Math.ceil(userData.length / defaultPageSize); return (
Showing Page {currentPage+1} of {totalPages}
); } return (
These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM
User ID User Email User Models User Spend ($ USD) User Max Budget ($ USD) User API Key Aliases {userData.map((user: any) => ( {user.user_id} {user.user_email} {user.models && user.models.length > 0 ? user.models : "All Models"} {user.spend ? user.spend?.toFixed(2) : 0} {user.max_budget ? user.max_budget : "Unlimited"} {user && user.key_aliases ? user.key_aliases.filter((key: any) => key !== null).length > 0 ? {user.key_aliases.filter((key: any) => key !== null).join(', ') } : No Keys : No Keys} {/* {user.key_aliases.filter(key => key !== null).length} Keys */} {/* { setOpenDialogId(user.user_id) setSelectedItem(user) }}>View Keys */} ))}
{/* End User Spend Total Events {endUsers?.map((user: any, index: number) => ( {user.end_user} {user.total_spend} {user.total_events} ))}
*/}
{renderPagination()}
{/* { setOpenDialogId(null); }} >
Key Aliases {selectedItem && selectedItem.key_aliases ? selectedItem.key_aliases.filter(key => key !== null).length > 0 ? selectedItem.key_aliases.filter(key => key !== null).join(', ') : 'No Keys' : "No Keys"}
*/}
); }; export default ViewUserDashboard;