import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { PublicLayout } from '@/components/layout' import { PageTransition } from '@/components/page-transition' import { LoadingSkeleton, EmptyState, SearchBar, PricingTable, PricingSidebar, PricingToolbar, ModelCardGrid, ModelDetailsDrawer, } from './components' import { EXCLUDED_GROUPS, VIEW_MODES } from './constants' import { useFilters } from './hooks/use-filters' import { usePricingData } from './hooks/use-pricing-data' export function Pricing() { const { t } = useTranslation() const [selectedModelName, setSelectedModelName] = useState(null) const { models, vendors, groupRatio, usableGroup, endpointMap, autoGroups, isLoading, priceRate, usdExchangeRate, } = usePricingData() const { searchInput, sortBy, vendorFilter, groupFilter, quotaTypeFilter, endpointTypeFilter, tagFilter, tokenUnit, viewMode, showRechargePrice, setSearchInput, setSortBy, setVendorFilter, setGroupFilter, setQuotaTypeFilter, setEndpointTypeFilter, setTagFilter, setTokenUnit, setViewMode, setShowRechargePrice, filteredModels, hasActiveFilters, activeFilterCount, availableTags, clearFilters, clearSearch, } = useFilters(models || []) const handleModelClick = useCallback( (modelName: string) => { setSelectedModelName(modelName) }, [] ) const selectedModel = useMemo( () => selectedModelName ? (models || []).find((model) => model.model_name === selectedModelName) || null : null, [models, selectedModelName] ) const availableGroups = useMemo( () => Object.keys(usableGroup || {}).filter( (g) => !EXCLUDED_GROUPS.includes(g) ), [usableGroup] ) const handleClearAll = useCallback(() => { clearFilters() clearSearch() }, [clearFilters, clearSearch]) const renderPricingContent = () => { if (filteredModels.length === 0) { return ( ) } if (viewMode === VIEW_MODES.CARD) { return ( ) } return ( ) } if (isLoading) { return (
) } return (

{t('Models Directory')}

{t('Model Square')}

{t('This site currently has {{count}} models enabled', { count: models?.length || 0, })}

{t( 'Discover curated AI models, compare pricing and capabilities, and choose the right model for every scenario.' )}

{renderPricingContent()}
{selectedModel && ( { if (!open) setSelectedModelName(null) }} model={selectedModel} groupRatio={groupRatio || {}} usableGroup={usableGroup || {}} endpointMap={ (endpointMap as Record< string, { path?: string; method?: string } >) || {} } autoGroups={autoGroups || []} priceRate={priceRate ?? 1} usdExchangeRate={usdExchangeRate ?? 1} tokenUnit={tokenUnit} showRechargePrice={showRechargePrice} /> )}
) }