diff --git a/src/components/FavoriteButton/index.tsx b/src/components/FavoriteButton/index.tsx new file mode 100644 index 00000000..6d572164 --- /dev/null +++ b/src/components/FavoriteButton/index.tsx @@ -0,0 +1,84 @@ +/** + * FavoriteButton - 通用关注/收藏按钮组件(图标按钮) + */ + +import React from 'react'; +import { IconButton, Tooltip, Spinner } from '@chakra-ui/react'; +import { Star } from 'lucide-react'; + +export interface FavoriteButtonProps { + /** 是否已关注 */ + isFavorite: boolean; + /** 加载状态 */ + isLoading?: boolean; + /** 点击回调 */ + onClick: () => void; + /** 按钮大小 */ + size?: 'sm' | 'md' | 'lg'; + /** 颜色主题 */ + colorScheme?: 'gold' | 'default'; + /** 是否显示 tooltip */ + showTooltip?: boolean; +} + +// 颜色配置 +const COLORS = { + gold: { + active: '#F4D03F', // 已关注 - 亮金色 + inactive: '#C9A961', // 未关注 - 暗金色 + hoverBg: 'whiteAlpha.100', + }, + default: { + active: 'yellow.400', + inactive: 'gray.400', + hoverBg: 'gray.100', + }, +}; + +const FavoriteButton: React.FC = ({ + isFavorite, + isLoading = false, + onClick, + size = 'sm', + colorScheme = 'gold', + showTooltip = true, +}) => { + const colors = COLORS[colorScheme]; + const currentColor = isFavorite ? colors.active : colors.inactive; + const label = isFavorite ? '取消关注' : '加入自选'; + + const iconButton = ( + + ) : ( + + ) + } + variant="ghost" + color={currentColor} + size={size} + onClick={onClick} + isDisabled={isLoading} + _hover={{ bg: colors.hoverBg }} + /> + ); + + if (showTooltip) { + return ( + + {iconButton} + + ); + } + + return iconButton; +}; + +export default FavoriteButton; diff --git a/src/views/Company/components/CompanyHeader/SearchBar.js b/src/views/Company/components/CompanyHeader/SearchBar.js index ce0aa93b..fad22ced 100644 --- a/src/views/Company/components/CompanyHeader/SearchBar.js +++ b/src/views/Company/components/CompanyHeader/SearchBar.js @@ -1,5 +1,5 @@ // src/views/Company/components/CompanyHeader/SearchBar.js -// 股票搜索栏组件 +// 股票搜索栏组件 - 金色主题 import React from 'react'; import { @@ -30,7 +30,7 @@ const SearchBar = ({ - + @@ -54,7 +58,7 @@ const SearchBar = ({ color="#C9A961" borderWidth="1px" borderColor="#C9A961" - _hover={{ bg: '#1a1a1a' }} + _hover={{ bg: '#1a1a1a', borderColor: '#F4D03F', color: '#F4D03F' }} > 查询 diff --git a/src/views/Company/components/CompanyHeader/WatchlistButton.js b/src/views/Company/components/CompanyHeader/WatchlistButton.js deleted file mode 100644 index 2b788ab8..00000000 --- a/src/views/Company/components/CompanyHeader/WatchlistButton.js +++ /dev/null @@ -1,35 +0,0 @@ -// src/views/Company/components/CompanyHeader/WatchlistButton.js -// 自选股按钮组件 - -import React from 'react'; -import { Button } from '@chakra-ui/react'; -import { StarIcon } from '@chakra-ui/icons'; - -/** - * 自选股按钮组件 - * - * @param {Object} props - * @param {boolean} props.isInWatchlist - 是否已在自选股中 - * @param {boolean} props.isLoading - 是否正在加载 - * @param {Function} props.onClick - 点击回调 - */ -const WatchlistButton = ({ - isInWatchlist, - isLoading, - onClick, -}) => { - return ( - - ); -}; - -export default WatchlistButton; diff --git a/src/views/Company/components/CompanyHeader/index.js b/src/views/Company/components/CompanyHeader/index.js index 6a1d3d8a..321333f4 100644 --- a/src/views/Company/components/CompanyHeader/index.js +++ b/src/views/Company/components/CompanyHeader/index.js @@ -9,72 +9,50 @@ import { VStack, Heading, Text, - Badge, } from '@chakra-ui/react'; import SearchBar from './SearchBar'; -import WatchlistButton from './WatchlistButton'; /** * 公司详情页面头部区域组件 * * 包含: - * - 页面标题和描述 + * - 页面标题和描述(金色主题) * - 股票搜索栏 - * - 自选股按钮 - * - 当前股票代码显示 * * @param {Object} props - * @param {string} props.stockCode - 当前股票代码 * @param {string} props.inputCode - 搜索输入框值 * @param {Function} props.onInputChange - 输入变化回调 * @param {Function} props.onSearch - 搜索回调 * @param {Function} props.onKeyPress - 键盘事件回调 - * @param {boolean} props.isInWatchlist - 是否在自选股中 - * @param {boolean} props.isWatchlistLoading - 自选股操作加载中 - * @param {Function} props.onWatchlistToggle - 自选股切换回调 * @param {string} props.bgColor - 背景颜色 */ const CompanyHeader = ({ - stockCode, inputCode, onInputChange, onSearch, onKeyPress, - isInWatchlist, - isWatchlistLoading, - onWatchlistToggle, bgColor, }) => { return ( - {/* 标题区域 */} + {/* 标题区域 - 金色主题 */} - 个股详情 - + 个股详情 + 查看股票实时行情、财务数据和盈利预测 - {/* 操作区域 */} - - {/* 搜索栏 */} - - - {/* 自选股按钮 */} - - + {/* 搜索栏 */} + diff --git a/src/views/Company/components/CompanyTabs/index.js b/src/views/Company/components/CompanyTabs/index.js index 3e7ee98f..78fcf379 100644 --- a/src/views/Company/components/CompanyTabs/index.js +++ b/src/views/Company/components/CompanyTabs/index.js @@ -83,7 +83,7 @@ const CompanyTabs = ({ stockCode, onTabChange }) => { {COMPANY_TABS.map((tab) => { const Component = TAB_COMPONENTS[tab.key]; return ( - + ); diff --git a/src/views/Company/components/StockQuoteCard/index.tsx b/src/views/Company/components/StockQuoteCard/index.tsx index e8477b89..1b8eb173 100644 --- a/src/views/Company/components/StockQuoteCard/index.tsx +++ b/src/views/Company/components/StockQuoteCard/index.tsx @@ -16,8 +16,12 @@ import { Badge, Progress, Skeleton, + IconButton, + Tooltip, } from '@chakra-ui/react'; +import { Share2 } from 'lucide-react'; +import FavoriteButton from '@components/FavoriteButton'; import type { StockQuoteCardProps } from './types'; import { mockStockQuoteData } from './mockData'; @@ -50,7 +54,16 @@ const formatNetInflow = (value: number): string => { const StockQuoteCard: React.FC = ({ data = mockStockQuoteData, isLoading = false, + isInWatchlist = false, + isWatchlistLoading = false, + onWatchlistToggle, + onShare, }) => { + // 处理分享点击 + const handleShare = () => { + onShare?.(); + }; + // 黑金主题颜色配置 const cardBg = '#1A202C'; const borderColor = '#C9A961'; @@ -77,31 +90,47 @@ const StockQuoteCard: React.FC = ({ return ( - {/* 顶部:股票名称 + 更新时间 */} - - - - {data.name} + {/* 顶部:股票名称 + 关注/分享按钮 + 更新时间 */} + + {/* 左侧:名称(代码) | 指数标签 */} + + + {data.name}({data.code}) + + {data.indexTags.length > 0 && ( + <> + | + + {data.indexTags.join('、')} + + + )} + + + {/* 右侧:关注 + 分享 + 时间 */} + + {})} + colorScheme="gold" + size="sm" + /> + + } + variant="ghost" + color={labelColor} + size="sm" + onClick={handleShare} + _hover={{ bg: 'whiteAlpha.100' }} + /> + + + {data.updateTime.split(' ')[1]} - - ({data.code}) - - {data.indexTags.map((tag) => ( - - {tag} - - ))} - - 更新时间:{data.updateTime} - {/* 三栏布局 */} @@ -124,19 +153,35 @@ const StockQuoteCard: React.FC = ({ {formatChangePercent(data.changePercent)} - + {/* 次要行情:今开 | 昨收 | 最高 | 最低 */} + 今开: - + {formatPrice(data.todayOpen)} + | 昨收: - + {formatPrice(data.yesterdayClose)} + | + + 最高: + + {formatPrice(data.todayHigh)} + + + | + + 最低: + + {formatPrice(data.todayLow)} + + diff --git a/src/views/Company/components/StockQuoteCard/mockData.ts b/src/views/Company/components/StockQuoteCard/mockData.ts index dd6fd49c..be47d6b7 100644 --- a/src/views/Company/components/StockQuoteCard/mockData.ts +++ b/src/views/Company/components/StockQuoteCard/mockData.ts @@ -14,6 +14,8 @@ export const mockStockQuoteData: StockQuoteCardData = { changePercent: 3.65, todayOpen: 2156.0, yesterdayClose: 2101.0, + todayHigh: 2185.0, + todayLow: 2150.0, // 关键指标 pe: 38.62, @@ -30,4 +32,7 @@ export const mockStockQuoteData: StockQuoteCardData = { // 更新时间 updateTime: '2025-12-03 14:30:25', + + // 自选状态 + isFavorite: false, }; diff --git a/src/views/Company/components/StockQuoteCard/types.ts b/src/views/Company/components/StockQuoteCard/types.ts index 89e503f0..ee286682 100644 --- a/src/views/Company/components/StockQuoteCard/types.ts +++ b/src/views/Company/components/StockQuoteCard/types.ts @@ -16,6 +16,8 @@ export interface StockQuoteCardData { changePercent: number; // 涨跌幅(百分比,如 3.65 表示 +3.65%) todayOpen: number; // 今开 yesterdayClose: number; // 昨收 + todayHigh: number; // 今日最高 + todayLow: number; // 今日最低 // 关键指标 pe: number; // 市盈率 @@ -32,6 +34,9 @@ export interface StockQuoteCardData { // 更新时间 updateTime: string; // 格式:YYYY-MM-DD HH:mm:ss + + // 自选状态 + isFavorite?: boolean; // 是否已加入自选 } /** @@ -40,4 +45,10 @@ export interface StockQuoteCardData { export interface StockQuoteCardProps { data?: StockQuoteCardData; isLoading?: boolean; + // 自选股相关(与 WatchlistButton 接口保持一致) + isInWatchlist?: boolean; // 是否在自选股中 + isWatchlistLoading?: boolean; // 自选股操作加载中 + onWatchlistToggle?: () => void; // 自选股切换回调 + // 分享 + onShare?: () => void; // 分享回调 } diff --git a/src/views/Company/index.js b/src/views/Company/index.js index 850d9695..5c2a9b86 100644 --- a/src/views/Company/index.js +++ b/src/views/Company/index.js @@ -66,21 +66,21 @@ const CompanyIndex = () => { return ( - {/* 页面头部:标题、搜索、自选股按钮 */} + {/* 页面头部:标题、搜索 */} - {/* 股票行情卡片:价格、关键指标、主力动态 */} - + {/* 股票行情卡片:价格、关键指标、主力动态、自选股按钮 */} + {/* Tab 切换区域:概览、行情、财务、预测 */}