/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. For commercial licensing, please contact support@quantumnous.com */ import React from 'react'; import { usePricingFilterCounts } from '../../../../hooks/model-pricing/usePricingFilterCounts'; import { getLobeHubIcon } from '../../../../helpers'; const ModelsSidebar = ({ models, filterVendor, setFilterVendor, filterSupplierType, setFilterSupplierType, filterTag, setFilterTag, filterGroup, filterQuotaType, filterEndpointType, searchValue, loading, t, }) => { const { vendorModels, tagModels, supplierTypeModels } = usePricingFilterCounts({ models, filterGroup, filterQuotaType, filterEndpointType, filterVendor, filterTag, filterSupplierType, searchValue, }); // ─── 作者 (Vendors) ─── const vendors = React.useMemo(() => { const names = [...new Set(models.map((m) => m.vendor_name).filter(Boolean))].sort(); return names.map((name) => { const icon = models.find((m) => m.vendor_name === name)?.vendor_icon; return { name, icon, count: vendorModels.filter((m) => m.vendor_name === name).length, }; }); }, [models, vendorModels]); // ─── 服务商 (Supplier Types) ─── const supplierTypes = React.useMemo(() => { const types = new Set(); models.forEach((m) => { (m.channel_list || []).forEach((ch) => { if (ch.supplier_type) types.add(ch.supplier_type); }); }); return [...types].sort(); }, [models]); // ─── 输入模态 (Tags) ─── const tags = React.useMemo(() => { const allTags = new Set(); models.forEach((m) => { if (m.tags) { String(m.tags).split(/[,;|]/).map(s => s.trim()).filter(Boolean).forEach(t => allTags.add(t.toLowerCase())); } }); return [...allTags].sort(); }, [models]); const FilterItem = ({ label, count, active, onClick }) => (
{label} {count}
); return (
{/* 作者 */}
{t('作者')}
setFilterVendor('all')} /> {vendors.map((v) => ( {v.icon && ( { e.target.style.display = 'none'; }} /> )} {v.name} } count={v.count} active={filterVendor === v.name} onClick={() => setFilterVendor(filterVendor === v.name ? 'all' : v.name)} /> ))}
{/* 服务商 */}
{t('服务商')}
setFilterSupplierType('all')} /> {supplierTypes.map((type) => ( (m.channel_list || []).some((ch) => ch.supplier_type === type) ).length} active={filterSupplierType === type} onClick={() => setFilterSupplierType(filterSupplierType === type ? 'all' : type)} /> ))}
{/* 输入模态 */}
{t('输入模态')}
setFilterTag('all')} /> {tags.map((tag) => ( m.tags && String(m.tags).split(/[,;|]/).map(s => s.trim()).includes(tag) ).length} active={filterTag === tag} onClick={() => setFilterTag(filterTag === tag ? 'all' : tag)} /> ))}
); }; export default ModelsSidebar;