import { useCallback, useState } from 'react' import { ArrowUpDown, Check, Filter, Grid2X2, Table2 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { cn } from '@/lib/utils' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from '@/components/ui/sheet' import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip' import { VIEW_MODES, getSortLabels, type SortOption, type ViewMode, } from '../constants' import type { PricingModel, PricingVendor, TokenUnit } from '../types' import { PricingSidebar } from './pricing-sidebar' type SegmentOption = { value: string label?: string icon?: React.ComponentType<{ className?: string }> tooltip?: string } export interface PricingToolbarProps { filteredCount: number totalCount?: number sortBy: string onSortChange: (value: string) => void tokenUnit: TokenUnit onTokenUnitChange: (value: TokenUnit) => void showRechargePrice: boolean onRechargePriceChange: (value: boolean) => void viewMode: ViewMode onViewModeChange: (value: ViewMode) => void quotaTypeFilter: string endpointTypeFilter: string vendorFilter: string groupFilter: string tagFilter: string onQuotaTypeChange: (value: string) => void onEndpointTypeChange: (value: string) => void onVendorChange: (value: string) => void onGroupChange: (value: string) => void onTagChange: (value: string) => void vendors: PricingVendor[] groups: string[] groupRatios?: Record tags: string[] models: PricingModel[] hasActiveFilters: boolean activeFilterCount: number onClearFilters: () => void } function SegmentedControl(props: { options: SegmentOption[] value: string onChange: (value: string) => void ariaLabel: string }) { return (
{props.options.map((option) => { const Icon = option.icon const isActive = option.value === props.value const button = ( ) if (!option.tooltip) { return button } return ( {option.tooltip} ) })}
) } export function PricingToolbar(props: PricingToolbarProps) { const { t } = useTranslation() const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false) const sortLabels = getSortLabels(t) const handleTokenUnitChange = useCallback( (value: string) => props.onTokenUnitChange(value as TokenUnit), [props] ) const handleViewModeChange = useCallback( (value: string) => props.onViewModeChange(value as ViewMode), [props] ) const handleRechargePriceChange = useCallback( (value: string) => props.onRechargePriceChange(value === 'recharge'), [props] ) return (
{props.filteredCount.toLocaleString()} {props.filteredCount === 1 ? t('model') : t('models')} {props.hasActiveFilters && props.totalCount && ( / {props.totalCount.toLocaleString()} )}
} > {sortLabels[props.sortBy as SortOption] || t('Sort')} {Object.entries(sortLabels).map(([value, label]) => ( props.onSortChange(value)} className='gap-2' > {label} ))}
{t('Filter')} {t('Filter models by provider, group, type, endpoint, and tags.')}
) }