Antdesign React之API展示页面

news/2024/12/21 18:37:46/文章来源:https://www.cnblogs.com/chiusto/p/18621031

本项目基于antdesignpro,点击调试后跳转弹窗,左边展示public/doc路径下的md文档并且通过markdownview渲染成md,右侧是json编辑器


index.tsx

import React, { useState, useMemo } from 'react';
import { Layout, Menu, theme, Row, Col } from 'antd';
import { HomeOutlined, FireTwoTone, HeartTwoTone } from '@ant-design/icons';
import CustomCard from "./CustomCard";
import { cardData, categoryLabels, categoryKeys, Card } from './cardData';const { Header, Content, Sider } = Layout;const sidebarItems = [HomeOutlined, FireTwoTone, HeartTwoTone].map((icon, index) => ({key: categoryKeys[index],icon: React.createElement(icon),label: categoryLabels[index],}),
);interface CardGridProps {cards: Card[];
}// 卡片网格
const CardGrid: React.FC<CardGridProps> = ({ cards }) => (<Row gutter={[16, 16]}>{cards.map((card, index) => (<Col key={index} xs={24} sm={12} md={8} lg={6}><CustomCard {...card} /></Col>))}</Row>
);const Test2: React.FC = () => {const {token: { colorBgContainer, borderRadiusLG, fontSizeHeading1, paddingLG },} = theme.useToken();const [selectedCategory, setSelectedCategory] = useState(categoryKeys[0]);// 筛选出当前选中类别的卡片const filteredCards = useMemo(() => {// 如果选中类别是 'all',则返回所有类别的卡片if (selectedCategory === 'all') {return cardData.flatMap(category => category.cards);}// 否则,只返回该类别的卡片return cardData.filter(category => category.categoryName === selectedCategory).flatMap(category => category.cards);}, [selectedCategory]);return (<Layout><Headerstyle={{textAlign: 'center',height: 100,paddingInline: paddingLG,lineHeight: '64px',fontSize: fontSizeHeading1,fontFamily: 'PingFang SC',backgroundColor: 'white',}}>API HUB</Header><Content style={{ padding: '0 48px' }}><Layoutstyle={{ padding: '24px 0', background: colorBgContainer, borderRadius: borderRadiusLG }}><Sider style={{ background: colorBgContainer }} width={200}><Menumode="inline"selectedKeys={[selectedCategory]}style={{ height: '100%' }}items={sidebarItems}onClick={(e) => setSelectedCategory(e.key)}/></Sider><Content style={{ padding: '0 24px', minHeight: 280 }}><CardGrid cards={filteredCards} /></Content></Layout></Content></Layout>);
};export default Test2;

customcard.tsx,定义每一个api卡片

import React, { useState } from 'react';
import { Card, Typography, Button, Modal, Avatar, Row, Col } from 'antd';
import { EyeOutlined, StarOutlined } from '@ant-design/icons';
import AceEditor from 'react-ace';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-github';
import MarkdownView from '../MarkdownView/MarkdownView';const { Meta } = Card;interface CardProps {title: string;views: number;stars: number;description: string;avatar: string;mdFilePath: string;
}const CustomCard: React.FC<CardProps> = React.memo(({ title, views, stars, description, avatar, mdFilePath 
}) => {const [isModalVisible, setIsModalVisible] = useState(false);const [fileContent, setFileContent] = useState('');const [jsonContent, setJsonContent] = useState(`{"example": "data"
}`);// 点击调试按钮处理函数const handleButtonClick = async () => {try {const publicPath = process.env.PUBLIC_URL || '';const response = await fetch(`${publicPath}/doc/${mdFilePath}`);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const content = await response.text();setFileContent(content);setIsModalVisible(true);} catch (error) {console.error('Error reading file:', error);}};// JSON编辑器变更处理函数const handleJsonChange = (value: string) => {setJsonContent(value);};return (<><Card hoverable><Metaavatar={<Avatarsrc={avatar}size={64}/>}title={<div><Typography.Title level={5}>{title}</Typography.Title><div><EyeOutlined style={{ marginRight: 4 }} />{views?.toLocaleString() ?? 0}<StarOutlined style={{ marginLeft: 16, marginRight: 4 }} />{stars?.toLocaleString() ?? 0}</div></div>}/><Typography.Paragraph ellipsis={{ rows: 2, expandable: false }}>{description}</Typography.Paragraph><div><Button type="primary" onClick={handleButtonClick}>调试</Button></div></Card><Modaltitle={title}open={isModalVisible}onCancel={() => setIsModalVisible(false)}footer={null}width="90vw"centeredbodyStyle={{ maxHeight: '90vh',overflow: 'auto',padding: '24px'}}><Row gutter={24}>{/* Markdown内容 - 左侧 */}<Col span={18} style={{ maxHeight: '80vh', overflowY: 'auto',borderRight: '1px solid #e8e8e8'}}><MarkdownView content={fileContent} /></Col>{/* JSON编辑器 - 右侧 */}<Col span={6} style={{ display: 'flex',flexDirection: 'column',alignItems: 'flex-end'  // 向右对齐}}><h3 style={{ marginTop: 0, alignSelf: 'flex-start' }}>JSON 编辑器</h3><AceEditormode="json"theme="github"value={jsonContent}onChange={handleJsonChange}name="json-editor"editorProps={{ $blockScrolling: true }}setOptions={{showLineNumbers: true,tabSize: 2,useWorker: false,fontSize: 14,printMargin: false }}width="100%"// height="calc(100vh - 200px)"height="50%"style={{border: '1px solid #e8e8e8',borderRadius: '4px'}}/><Button type="primary" style={{ marginTop: 10 }}>调试</Button></Col></Row></Modal></>);
});export default CustomCard;

carddata.tsx,定义了一些接口的数据,后续将接入后端

export interface Card {title: string;views: number;stars: number;description: string;avatar: string;mdFilePath: string; // 新增的属性
}export interface Category {categoryName: string;cards: Card[];
}export const cardData: Category[] = [{categoryName: 'hot',cards: [{title: 'OpenAI GPT-3',views: 1250000,stars: 8500,description: 'OpenAI GPT-3是一个强大的自然语言处理API,可用于多种语言任务,如文本生成、翻译和问答。',avatar: 'https://example.com/openai-avatar.png',mdFilePath: 'test.md', // 示例路径},{title: 'TensorFlow API',views: 980000,stars: 7200,description: 'TensorFlow提供了全面的机器学习和深度学习工具,支持模型训练、部署和推理。',avatar: 'https://example.com/tensorflow-avatar.png',mdFilePath: 'test2.md', // 示例路径},],},{categoryName: 'fav',cards: [{title: 'Stripe支付API',views: 750000,stars: 6300,description: 'Stripe API提供了简单而强大的支付处理功能,支持多种货币和支付方式。',avatar: 'https://example.com/stripe-avatar.png',mdFilePath: 'public/doc/stripe-api.md', // 示例路径},],},{categoryName: 'all',cards: [{title: 'Google Maps API',views: 2000000,stars: 9500,description: 'Google Maps API提供了全面的地图、地理编码和路线规划功能,适用于各种位置基础应用。',avatar: 'https://example.com/googlemaps-avatar.png',mdFilePath: 'public/doc/google-maps-api.md', // 示例路径},{title: 'AWS S3 API',views: 1800000,stars: 8900,description: 'Amazon S3 API提供了可扩展的云存储解决方案,支持大规模数据存储和检索。',avatar: 'https://example.com/awss3-avatar.png',mdFilePath: 'public/doc/aws-s3-api.md', // 示例路径},{title: 'Twitter API',views: 1500000,stars: 7800,description: 'Twitter API允许开发者访问和分析Twitter平台的数据,包括推文、用户信息和趋势。',avatar: 'https://example.com/twitter-avatar.png',mdFilePath: 'public/doc/twitter-api.md', // 示例路径},],},{categoryName: 'hot',cards: [{title: 'Firebase实时数据库',views: 950000,stars: 7100,description: 'Firebase实时数据库提供了实时同步的云托管NoSQL数据库,适用于构建协作应用。',avatar: 'https://example.com/firebase-avatar.png',mdFilePath: 'public/doc/firebase-realtime-db.md', // 示例路径},],},{categoryName: 'fav',cards: [{title: 'Spotify API',views: 850000,stars: 6800,description: 'Spotify API使开发者能够集成Spotify的音乐流媒体功能,包括搜索、播放控制和推荐。',avatar: 'https://example.com/spotify-avatar.png',mdFilePath: 'public/doc/spotify-api.md', // 示例路径},{title: 'GitHub API',views: 1100000,stars: 8200,description: 'GitHub API提供了访问GitHub平台数据的接口,支持代码仓库管理、问题跟踪等功能。',avatar: 'https://example.com/github-avatar.png',mdFilePath: 'public/doc/github-api.md', // 示例路径},],},
];export const categoryLabels = ['全部', '使用热门', '收藏'];
export const categoryKeys = ['all', 'hot', 'fav'];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/856443.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时间复杂度:理解算法性能的核心指标

在编程和算法设计中,时间复杂度是一个至关重要的概念。它用来衡量一个算法在处理不同规模的输入数据时,执行所需要的时间增长速度。换句话说,时间复杂度能够帮助我们理解算法在面对大数据时的表现,是否能高效地完成任务。 什么是时间复杂度? 时间复杂度是一个描述算法效率…

TIA环境下SCL编程练习:产生m到n之间的随机整数,存入数组

假设需要读取100个随机数,存入有100个成员的数组。做这个练习是为了学习一下SCL编程。随机数使用系统时钟纳秒数来线性转换。 新建项目,选用1500PLC(6ES7 513-1AL02-0AB0,当然可以选用其它型号),设定本地时区,建立网络。 新建DB,建立变量,取消优化块的访问。 新建FC,…

大学微积分 AB 第六单元:变革的整合与积累(定积分、黎曼近似)

积分学简介 定积分简介 例子: 示例:变化的积累 1/2是面积的一半 例子:

实验六 C++

任务四: Vector.hpp:#pragma once #ifndef VECTOR_HPP #define VECTOR_HPP#include <iostream> #include <stdexcept> // 为异常类提供支持 #include <memory> // 为 std::unique_ptr 提供支持template <typename T> class Vector { private:std::…

道阻且长——2024秋软工实践个人总结

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13315这个作业的目标 回顾自己的软工实践课程学号 102201120道阻且长——2024秋软工实践个人总结 一、学期回顾 1.1 想象与实际 开课之…

【Rive】Rive在Android上的简单应用

1 前言 ​ Rive 是一款强大的矢量图编辑器,可以设计图形、也可以制作动画。Rive 提供了矩形、圆形、三角形、多边形、星形、钢笔、文字等工具来绘制各式各样的矢量图形;提供了平移、旋转、缩放等工具对矢量图形进行各种变换;提供了骨骼、约束、时间线、状态机、过渡条件、…

UML之类与类图

在所有项目中,类都是最常见的UML模型元素(当然,不可否认,很多项目还没画出类图就直接进入编码实现的阶段了)。类是UML模型与具体实现代码之间的桥梁,随着对UML建模的深入了解,我们也会发现,类(确切说是分析类)其实也是一些模型之间的桥梁。 在真实世界中不同对象通过…

Linux学习笔记(二) vi/vim快速入门

Linux系统会内置vi文本编辑器。 vim具有程序编辑的能力,可以看作是vi的增强版本,可以主动的以字体颜色辨别语法的正确性, 方便程序设计。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。 下面将介绍: 1.vim打开或创建文件的方法。 2.vim的三种工…

Z-BlogPHP 安装步骤

解压程序代码将下载的 Z-BlogPHP 压缩包解压到你的网站根目录,例如 /home/wwwroot/example.com/。访问安装页面打开浏览器,访问你的网站地址,例如 http://example.com/。 会自动跳转到安装页面 http://example.com/zb_install/index.php。填写安装信息在安装页面中输入以下信…

请问如何在 Z-BlogPHP 中开启 Beta 版更新推送?

在 Z-BlogPHP 中开启 Beta 版更新推送可以帮助你及时获取最新的功能和改进,但同时也需要注意 Beta 版可能存在不稳定的情况。以下是开启 Beta 版更新推送的详细步骤:进入后台管理:登录 Z-BlogPHP 后台管理界面,使用你在安装时设置的管理员用户名和密码。访问应用中心:在后…

升级 Z-BlogPHP 到 1.7.3.3260 后为什么会出现后台登录错误?

升级 Z-BlogPHP 到 1.7.3.3260 版本后,后台登录可能会出现错误,主要是由于新版本增加了两个重要的安全保护功能:CSRF(跨站请求伪造)保护和验证码功能。这些功能旨在提高系统的安全性,防止未经授权的访问和自动化攻击。然而,由于某些主题或插件的兼容性问题,这些新增的安…

织梦网站logo图片怎么修改,织梦网站Logo图片修改指南

修改织梦网站的Logo图片可以提升网站的品牌形象。以下是详细的步骤:登录后台管理系统:使用管理员账号登录织梦CMS的后台管理系统。进入模板管理:导航到“模板管理” -> “默认模板管理”。编辑头部模板:找到头部模板文件,通常是header.htm。 点击“编辑”按钮,打开模板…