/* 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import React, { useState } from 'react'; import { Card, Divider, Typography, Button } from '@douyinfe/semi-ui'; import PropTypes from 'prop-types'; import { useIsMobile } from '../../../hooks/common/useIsMobile'; import { IconEyeOpened, IconEyeClosed } from '@douyinfe/semi-icons'; const { Text } = Typography; /** * CardPro 高级卡片组件 * * 布局分为6个区域: * 1. 统计信息区域 (statsArea) * 2. 描述信息区域 (descriptionArea) * 3. 类型切换/标签区域 (tabsArea) * 4. 操作按钮区域 (actionsArea) * 5. 搜索表单区域 (searchArea) * 6. 分页区域 (paginationArea) - 固定在卡片底部 * * 支持三种布局类型: * - type1: 操作型 (如TokensTable) - 描述信息 + 操作按钮 + 搜索表单 * - type2: 查询型 (如LogsTable) - 统计信息 + 搜索表单 * - type3: 复杂型 (如ChannelsTable) - 描述信息 + 类型切换 + 操作按钮 + 搜索表单 */ const CardPro = ({ type = 'type1', className = '', children, // 各个区域的内容 statsArea, descriptionArea, tabsArea, actionsArea, searchArea, paginationArea, // 新增分页区域 // 卡片属性 shadows = '', bordered = true, // 自定义样式 style, // 国际化函数 t = (key) => key, ...props }) => { const isMobile = useIsMobile(); const [showMobileActions, setShowMobileActions] = useState(false); const toggleMobileActions = () => { setShowMobileActions(!showMobileActions); }; const hasMobileHideableContent = actionsArea || searchArea; const renderHeader = () => { const hasContent = statsArea || descriptionArea || tabsArea || actionsArea || searchArea; if (!hasContent) return null; return (
{/* 统计信息区域 - 用于type2 */} {type === 'type2' && statsArea && <>{statsArea}} {/* 描述信息区域 - 用于type1和type3 */} {(type === 'type1' || type === 'type3') && descriptionArea && ( <>{descriptionArea} )} {/* 第一个分隔线 - 在描述信息或统计信息后面 */} {((type === 'type1' || type === 'type3') && descriptionArea) || (type === 'type2' && statsArea) ? ( ) : null} {/* 类型切换/标签区域 - 主要用于type3 */} {type === 'type3' && tabsArea && <>{tabsArea}} {/* 移动端操作切换按钮 */} {isMobile && hasMobileHideableContent && ( <>
)} {/* 操作按钮和搜索表单的容器 */}
{/* 操作按钮区域 - 用于type1和type3 */} {(type === 'type1' || type === 'type3') && actionsArea && (Array.isArray(actionsArea) ? ( actionsArea.map((area, idx) => ( {idx !== 0 && }
{area}
)) ) : (
{actionsArea}
))} {/* 当同时存在操作区和搜索区时,插入分隔线 */} {actionsArea && searchArea && } {/* 搜索表单区域 - 所有类型都可能有 */} {searchArea &&
{searchArea}
}
); }; const headerContent = renderHeader(); // 渲染分页区域 const renderFooter = () => { if (!paginationArea) return null; return (
{paginationArea}
); }; const footerContent = renderFooter(); return ( {children} ); }; CardPro.propTypes = { // 布局类型 type: PropTypes.oneOf(['type1', 'type2', 'type3']), // 样式相关 className: PropTypes.string, style: PropTypes.object, shadows: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), bordered: PropTypes.bool, // 内容区域 statsArea: PropTypes.node, descriptionArea: PropTypes.node, tabsArea: PropTypes.node, actionsArea: PropTypes.oneOfType([ PropTypes.node, PropTypes.arrayOf(PropTypes.node), ]), searchArea: PropTypes.node, paginationArea: PropTypes.node, // 表格内容 children: PropTypes.node, // 国际化函数 t: PropTypes.func, }; export default CardPro;