- 创建 ForecastSkeleton 组件(图表卡片 + 表格) - 初始加载时显示骨架屏 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
/**
|
|
* 盈利预测报表视图 - 黑金主题
|
|
* 优化:使用 useForecastData Hook、错误处理、memo 包装
|
|
*/
|
|
|
|
import React, { memo } from 'react';
|
|
import { Box, SimpleGrid, Center, VStack, Text, Button } from '@chakra-ui/react';
|
|
import { useForecastData } from './hooks';
|
|
import {
|
|
IncomeProfitGrowthChart,
|
|
EpsChart,
|
|
PePegChart,
|
|
DetailTable,
|
|
ForecastSkeleton,
|
|
} from './components';
|
|
import type { ForecastReportProps } from './types';
|
|
|
|
const ForecastReport: React.FC<ForecastReportProps> = ({ stockCode }) => {
|
|
const { data, isLoading, error, refetch } = useForecastData(stockCode);
|
|
|
|
// 加载状态 - 显示骨架屏
|
|
if (isLoading && !data) {
|
|
return <ForecastSkeleton />;
|
|
}
|
|
|
|
// 错误状态
|
|
if (error && !data) {
|
|
return (
|
|
<Center h="200px">
|
|
<VStack spacing={3}>
|
|
<Text color="red.400">{error}</Text>
|
|
<Button size="sm" colorScheme="yellow" variant="outline" onClick={refetch}>
|
|
重试
|
|
</Button>
|
|
</VStack>
|
|
</Center>
|
|
);
|
|
}
|
|
|
|
// 无数据
|
|
if (!data) return null;
|
|
|
|
return (
|
|
<Box>
|
|
{/* 图表区域 - 3列布局 */}
|
|
<SimpleGrid columns={{ base: 1, md: 3 }} spacing={4}>
|
|
<IncomeProfitGrowthChart
|
|
incomeProfitData={data.income_profit_trend}
|
|
growthData={data.growth_bars}
|
|
/>
|
|
<EpsChart data={data.eps_trend} />
|
|
<PePegChart data={data.pe_peg_axes} />
|
|
</SimpleGrid>
|
|
|
|
{/* 详细数据表格 */}
|
|
<Box mt={4}>
|
|
<DetailTable data={data.detail_table} />
|
|
</Box>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default memo(ForecastReport);
|