mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-24 18:24:20 +00:00
style(view_users.tsx): cleanup ui to show filters in consistent style
This commit is contained in:
parent
72dd00d418
commit
f887dc6bff
1 changed files with 130 additions and 40 deletions
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import {
|
||||
Card,
|
||||
Title,
|
||||
|
@ -131,6 +131,9 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
|
|||
max_spend: null
|
||||
});
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
const [showColumnDropdown, setShowColumnDropdown] = useState(false);
|
||||
const [selectedFilter, setSelectedFilter] = useState("Email");
|
||||
const filtersRef = useRef(null);
|
||||
|
||||
// check if window is not undefined
|
||||
if (typeof window !== "undefined") {
|
||||
|
@ -374,56 +377,143 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
|
|||
<div className="border-b px-6 py-4">
|
||||
<div className="flex flex-col space-y-4">
|
||||
{/* Search and Filter Controls */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex-1 max-w-md">
|
||||
<TextInput
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
{/* Email Search */}
|
||||
<div className="relative w-64">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search by email..."
|
||||
className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
value={filters.email}
|
||||
onChange={(e) => handleFilterChange('email', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<svg
|
||||
className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
|
||||
{/* Filter Button */}
|
||||
<button
|
||||
className={`px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 ${showFilters ? 'bg-gray-100' : ''}`}
|
||||
onClick={() => setShowFilters(!showFilters)}
|
||||
className="ml-4"
|
||||
>
|
||||
{showFilters ? "Hide Filters" : "Show Filters"}
|
||||
</Button>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
|
||||
/>
|
||||
</svg>
|
||||
Filters
|
||||
{(filters.user_id || filters.user_role || filters.team) && (
|
||||
<span className="w-2 h-2 rounded-full bg-blue-500"></span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* Reset Filters Button */}
|
||||
<button
|
||||
className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
|
||||
onClick={() => {
|
||||
setFilters({
|
||||
email: "",
|
||||
user_id: "",
|
||||
user_role: "",
|
||||
team: "",
|
||||
model: "",
|
||||
min_spend: null,
|
||||
max_spend: null
|
||||
});
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
||||
/>
|
||||
</svg>
|
||||
Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Advanced Filters */}
|
||||
{/* Additional Filters */}
|
||||
{showFilters && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
|
||||
<TextInput
|
||||
placeholder="Filter by User ID"
|
||||
value={filters.user_id}
|
||||
onChange={(e) => handleFilterChange('user_id', e.target.value)}
|
||||
/>
|
||||
|
||||
<Select
|
||||
value={filters.user_role}
|
||||
onValueChange={(value) => handleFilterChange('user_role', value)}
|
||||
placeholder="Select Role"
|
||||
>
|
||||
{Object.entries(possibleUIRoles).map(([key, value]) => (
|
||||
<SelectItem key={key} value={key}>
|
||||
{value.ui_label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
<div className="flex flex-wrap items-center gap-3 mt-3">
|
||||
{/* User ID Search */}
|
||||
<div className="relative w-64">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Filter by User ID"
|
||||
className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
value={filters.user_id}
|
||||
onChange={(e) => handleFilterChange('user_id', e.target.value)}
|
||||
/>
|
||||
<svg
|
||||
className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<Select
|
||||
value={filters.team}
|
||||
onValueChange={(value) => handleFilterChange('team', value)}
|
||||
placeholder="Select Team"
|
||||
>
|
||||
{teams?.map((team) => (
|
||||
<SelectItem key={team.team_id} value={team.team_id}>
|
||||
{team.team_alias || team.team_id}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
{/* Role Dropdown */}
|
||||
<div className="w-64">
|
||||
<Select
|
||||
value={filters.user_role}
|
||||
onValueChange={(value) => handleFilterChange('user_role', value)}
|
||||
placeholder="Select Role"
|
||||
>
|
||||
{Object.entries(possibleUIRoles).map(([key, value]) => (
|
||||
<SelectItem key={key} value={key}>
|
||||
{value.ui_label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Team Dropdown */}
|
||||
<div className="w-64">
|
||||
<Select
|
||||
value={filters.team}
|
||||
onValueChange={(value) => handleFilterChange('team', value)}
|
||||
placeholder="Select Team"
|
||||
>
|
||||
{teams?.map((team) => (
|
||||
<SelectItem key={team.team_id} value={team.team_id}>
|
||||
{team.team_alias || team.team_id}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue