更新Company页面的UI为FUI风格
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* StockQuoteCard - 股票行情卡片组件
|
||||
*
|
||||
* 展示股票的实时行情、关键指标和主力动态
|
||||
* 采用原子组件拆分,提高可维护性和复用性
|
||||
* 采用 FUI 科幻风格设计 - Ash Thorp / Linear.app 风格
|
||||
*
|
||||
* 优化:数据获取已下沉到组件内部,Props 从 11 个精简为 4 个
|
||||
*/
|
||||
@@ -10,11 +10,10 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
CardBody,
|
||||
Flex,
|
||||
VStack,
|
||||
Skeleton,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
@@ -26,11 +25,69 @@ import {
|
||||
MainForceInfo,
|
||||
CompanyInfo,
|
||||
StockCompareModal,
|
||||
STOCK_CARD_THEME,
|
||||
} from './components';
|
||||
import { useStockQuoteData, useStockCompare } from './hooks';
|
||||
import type { StockQuoteCardProps } from './types';
|
||||
|
||||
// FUI 主题色彩
|
||||
const FUI_THEME = {
|
||||
gold: '#D4AF37',
|
||||
goldLight: 'rgba(212, 175, 55, 0.15)',
|
||||
goldGlow: 'rgba(212, 175, 55, 0.4)',
|
||||
bgCard: 'linear-gradient(145deg, rgba(26, 26, 46, 0.95) 0%, rgba(15, 15, 26, 0.98) 100%)',
|
||||
border: 'rgba(212, 175, 55, 0.2)',
|
||||
borderHover: 'rgba(212, 175, 55, 0.4)',
|
||||
textPrimary: 'rgba(255, 255, 255, 0.95)',
|
||||
textSecondary: 'rgba(255, 255, 255, 0.7)',
|
||||
};
|
||||
|
||||
// FUI 角落装饰组件
|
||||
const CornerDecoration: React.FC<{ position: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' }> = ({ position }) => {
|
||||
const positionStyles = {
|
||||
topLeft: { top: '8px', left: '8px', borderTop: '2px solid', borderLeft: '2px solid' },
|
||||
topRight: { top: '8px', right: '8px', borderTop: '2px solid', borderRight: '2px solid' },
|
||||
bottomLeft: { bottom: '8px', left: '8px', borderBottom: '2px solid', borderLeft: '2px solid' },
|
||||
bottomRight: { bottom: '8px', right: '8px', borderBottom: '2px solid', borderRight: '2px solid' },
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
position="absolute"
|
||||
w="12px"
|
||||
h="12px"
|
||||
borderColor={FUI_THEME.goldGlow}
|
||||
opacity={0.7}
|
||||
{...positionStyles[position]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// FUI 卡片标题组件
|
||||
const FUICardTitle: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
||||
<Text
|
||||
fontSize="11px"
|
||||
fontWeight="600"
|
||||
letterSpacing="0.15em"
|
||||
textTransform="uppercase"
|
||||
color={FUI_THEME.gold}
|
||||
mb={4}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
_before={{
|
||||
content: '""',
|
||||
display: 'inline-block',
|
||||
width: '4px',
|
||||
height: '4px',
|
||||
bg: FUI_THEME.gold,
|
||||
borderRadius: '1px',
|
||||
mr: 2,
|
||||
boxShadow: `0 0 6px ${FUI_THEME.gold}`,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Text>
|
||||
);
|
||||
|
||||
const StockQuoteCard: React.FC<StockQuoteCardProps> = ({
|
||||
stockCode,
|
||||
isInWatchlist = false,
|
||||
@@ -64,26 +121,70 @@ const StockQuoteCard: React.FC<StockQuoteCardProps> = ({
|
||||
clearCompare();
|
||||
};
|
||||
|
||||
const { cardBg, borderColor } = STOCK_CARD_THEME;
|
||||
|
||||
// 加载中或无数据时显示骨架屏
|
||||
// 加载中或无数据时显示 FUI 风格骨架屏
|
||||
if (isLoading || !quoteData) {
|
||||
return (
|
||||
<Card bg={cardBg} shadow="sm" borderWidth="1px" borderColor={borderColor}>
|
||||
<CardBody>
|
||||
<VStack spacing={4} align="stretch">
|
||||
<Skeleton height="30px" width="200px" />
|
||||
<Skeleton height="60px" />
|
||||
<Skeleton height="80px" />
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Box
|
||||
position="relative"
|
||||
bg={FUI_THEME.bgCard}
|
||||
borderRadius="lg"
|
||||
border="1px solid"
|
||||
borderColor={FUI_THEME.border}
|
||||
p={6}
|
||||
overflow="hidden"
|
||||
boxShadow={`0 4px 20px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.05)`}
|
||||
>
|
||||
<CornerDecoration position="topLeft" />
|
||||
<CornerDecoration position="topRight" />
|
||||
<CornerDecoration position="bottomLeft" />
|
||||
<CornerDecoration position="bottomRight" />
|
||||
<VStack spacing={4} align="stretch">
|
||||
<Skeleton height="30px" width="200px" startColor="rgba(212, 175, 55, 0.1)" endColor="rgba(212, 175, 55, 0.2)" />
|
||||
<Skeleton height="60px" startColor="rgba(212, 175, 55, 0.1)" endColor="rgba(212, 175, 55, 0.2)" />
|
||||
<Skeleton height="80px" startColor="rgba(212, 175, 55, 0.1)" endColor="rgba(212, 175, 55, 0.2)" />
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card bg={cardBg} shadow="sm" borderWidth="1px" borderColor={borderColor}>
|
||||
<CardBody>
|
||||
<Box
|
||||
position="relative"
|
||||
bg={FUI_THEME.bgCard}
|
||||
borderRadius="lg"
|
||||
border="1px solid"
|
||||
borderColor={FUI_THEME.border}
|
||||
overflow="hidden"
|
||||
boxShadow={`0 4px 20px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.05)`}
|
||||
backdropFilter="blur(12px)"
|
||||
transition="all 0.3s ease"
|
||||
_hover={{
|
||||
borderColor: FUI_THEME.borderHover,
|
||||
boxShadow: `0 8px 32px rgba(0, 0, 0, 0.4), 0 0 20px ${FUI_THEME.goldLight}, inset 0 1px 0 rgba(255, 255, 255, 0.08)`,
|
||||
}}
|
||||
>
|
||||
{/* FUI 角落装饰 */}
|
||||
<CornerDecoration position="topLeft" />
|
||||
<CornerDecoration position="topRight" />
|
||||
<CornerDecoration position="bottomLeft" />
|
||||
<CornerDecoration position="bottomRight" />
|
||||
|
||||
{/* 顶部光效线条 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top={0}
|
||||
left="20%"
|
||||
right="20%"
|
||||
height="1px"
|
||||
bg={`linear-gradient(90deg, transparent, ${FUI_THEME.gold}, transparent)`}
|
||||
opacity={0.6}
|
||||
/>
|
||||
|
||||
{/* 内容区域 */}
|
||||
<Box p={6}>
|
||||
{/* FUI 标题 */}
|
||||
<FUICardTitle>个股详情 · STOCK QUOTE</FUICardTitle>
|
||||
|
||||
{/* 顶部:股票名称 + 关注/分享按钮 + 更新时间 */}
|
||||
<StockHeader
|
||||
name={quoteData.name}
|
||||
@@ -110,6 +211,13 @@ const StockQuoteCard: React.FC<StockQuoteCardProps> = ({
|
||||
isLoading={isCompareLoading}
|
||||
/>
|
||||
|
||||
{/* 分隔线 */}
|
||||
<Box
|
||||
my={4}
|
||||
height="1px"
|
||||
bg={`linear-gradient(90deg, transparent, ${FUI_THEME.border}, transparent)`}
|
||||
/>
|
||||
|
||||
{/* 1:2 布局 */}
|
||||
<Flex gap={8}>
|
||||
{/* 左栏:价格信息 (flex=1) */}
|
||||
@@ -127,14 +235,20 @@ const StockQuoteCard: React.FC<StockQuoteCardProps> = ({
|
||||
</Box>
|
||||
|
||||
{/* 右栏:关键指标 + 主力动态 (flex=2) */}
|
||||
<Flex flex="2" minWidth="0" gap={8} borderLeftWidth="1px" borderColor={borderColor} pl={8}>
|
||||
<Flex
|
||||
flex="2"
|
||||
minWidth="0"
|
||||
gap={8}
|
||||
borderLeftWidth="1px"
|
||||
borderColor={FUI_THEME.border}
|
||||
pl={8}
|
||||
>
|
||||
<KeyMetrics
|
||||
pe={quoteData.pe}
|
||||
eps={quoteData.eps}
|
||||
pb={quoteData.pb}
|
||||
marketCap={quoteData.marketCap}
|
||||
totalShares={quoteData.totalShares}
|
||||
floatShares={quoteData.floatShares}
|
||||
turnoverRate={quoteData.turnoverRate}
|
||||
week52Low={quoteData.week52Low}
|
||||
week52High={quoteData.week52High}
|
||||
/>
|
||||
@@ -148,9 +262,29 @@ const StockQuoteCard: React.FC<StockQuoteCardProps> = ({
|
||||
</Flex>
|
||||
|
||||
{/* 公司信息区块 */}
|
||||
{basicInfo && <CompanyInfo basicInfo={basicInfo} />}
|
||||
</CardBody>
|
||||
</Card>
|
||||
{basicInfo && (
|
||||
<>
|
||||
<Box
|
||||
my={4}
|
||||
height="1px"
|
||||
bg={`linear-gradient(90deg, transparent, ${FUI_THEME.border}, transparent)`}
|
||||
/>
|
||||
<CompanyInfo basicInfo={basicInfo} />
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* 底部光效线条 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom={0}
|
||||
left="30%"
|
||||
right="30%"
|
||||
height="1px"
|
||||
bg={`linear-gradient(90deg, transparent, ${FUI_THEME.goldGlow}, transparent)`}
|
||||
opacity={0.4}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user