/**
* Company 页面顶部搜索栏组件 - FUI 科幻风格
*
* 设计特点:
* - 左侧固定标题 + 副标题
* - 右侧简洁搜索框
* - 深色背景 + 金色强调色
*/
import React, { memo, useMemo, useCallback, useState } from 'react';
import {
Box,
Flex,
HStack,
VStack,
Text,
} from '@chakra-ui/react';
import { AutoComplete, Input, Spin } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { useStockSearch } from '@hooks/useStockSearch';
import { THEME } from '../../config';
import { FUI_COLORS, FUI_GLOW, FUI_ANIMATION, FUI_GLASS } from '../../theme/fui';
import type { CompanyHeaderProps, StockSearchResult } from '../../types';
/**
* 页面标题组件
*/
const PageTitle = memo(() => (
个股详情
查看股票实时行情、财务数据和盈利预测
));
PageTitle.displayName = 'PageTitle';
/**
* 搜索框组件(状态自管理,减少父组件重渲染)
*/
const SearchBox = memo<{
stockCode: string;
onStockChange: (value: string) => void;
}>(({
stockCode,
onStockChange,
}) => {
// 输入状态 - 默认为空,显示 placeholder
const [inputCode, setInputCode] = useState('');
// 股票搜索 Hook
const searchHook = useStockSearch({
limit: 10,
debounceMs: 300,
onSearch: () => {}, // 空回调,追踪在父组件处理
}) as {
searchResults: StockSearchResult[];
isSearching: boolean;
handleSearch: (query: string) => void;
clearSearch: () => void;
};
const { searchResults, isSearching, handleSearch: doSearch, clearSearch } = searchHook;
// 转换为 AutoComplete options
const stockOptions = useMemo(() => {
return searchResults.map((stock: StockSearchResult) => ({
value: stock.stock_code,
label: (
{stock.stock_code}
{stock.stock_name}
{stock.pinyin_abbr && (
{stock.pinyin_abbr.toUpperCase()}
)}
),
}));
}, [searchResults]);
// 选中股票
const handleSelect = useCallback((value: string) => {
clearSearch();
setInputCode(value);
if (value !== stockCode) {
onStockChange(value);
}
}, [clearSearch, stockCode, onStockChange]);
// 键盘事件 - 回车搜索
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
if (e.key === 'Enter' && inputCode && inputCode !== stockCode) {
onStockChange(inputCode);
}
}, [inputCode, stockCode, onStockChange]);
return (
: null}
>
}
onKeyDown={handleKeyDown}
style={{
backgroundColor: 'transparent',
borderColor: FUI_COLORS.gold[400],
borderRadius: 6,
height: 44,
color: FUI_COLORS.gold[400],
}}
/>
);
});
SearchBox.displayName = 'SearchBox';
/**
* Company 页面顶部组件
*/
const CompanyHeader: React.FC = memo(({
stockCode,
onStockChange,
}) => {
return (
{/* 左侧:页面标题 */}
{/* 右侧:搜索框 */}
);
});
CompanyHeader.displayName = 'CompanyHeader';
export default CompanyHeader;