refactor(Concept): 迁移至 HeroSection 组件

- 使用通用 HeroSection 替换原有 Hero 区域代码
- 配置 purple 主题预设,统计区使用独立卡片样式
- 搜索框宽度设为 140%,支持回车和点击搜索
- 移除搜索按钮 loading 状态绑定,避免页面加载时显示 loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-30 11:11:39 +08:00
parent bc6d5fd222
commit 1e511cb3f5

View File

@@ -136,6 +136,7 @@ import { useConceptEvents } from './hooks/useConceptEvents';
import { getApiBase } from '@utils/apiConfig';
import { GLASS_BLUR } from '@/constants/glassConfig';
import { HeroSection } from '@components/HeroSection';
// API配置 - 生产环境通过 api.valuefrontier.cn 代理
const API_BASE_URL = process.env.NODE_ENV === 'production'
@@ -1572,216 +1573,59 @@ const ConceptCenter = () => {
{/* 导航栏已由 MainLayout 提供 */}
{/* Hero Section - 精简版 */}
{/* Hero Section - 使用负 margin 抵消 Layout 的 padding 实现全宽背景 */}
<Box
position="relative"
bgGradient="linear(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)"
color="white"
overflow="hidden"
zIndex={1}
mx={{ base: -4, md: -6, lg: '-80px' }}
>
{/* 科幻网格背景 */}
<Box
position="absolute"
top="0"
left="0"
right="0"
bottom="0"
bgImage="linear-gradient(rgba(99, 102, 241, 0.1) 1px, transparent 1px), linear-gradient(90deg, rgba(99, 102, 241, 0.1) 1px, transparent 1px)"
bgSize="40px 40px"
opacity={0.3}
/>
{/* 发光球体 */}
<Box
position="absolute"
top="20%"
right="10%"
width="200px"
height="200px"
borderRadius="full"
bgGradient="radial(circle, rgba(139, 92, 246, 0.4), transparent 70%)"
filter="blur(40px)"
/>
<Box
position="absolute"
bottom="10%"
left="10%"
width="250px"
height="250px"
borderRadius="full"
bgGradient="radial(circle, rgba(59, 130, 246, 0.3), transparent 70%)"
filter="blur(50px)"
/>
<Box px={{ base: 4, md: 6, lg: '80px' }} position="relative" py={{ base: 8, md: 12 }}>
<VStack spacing={6}>
{/* 标题区域 */}
<VStack spacing={3} textAlign="center">
<HStack spacing={3} justify="center">
<Icon as={Brain} boxSize={10} color="cyan.300" filter="drop-shadow(0 0 10px rgba(6, 182, 212, 0.5))" />
</HStack>
<VStack spacing={1}>
<Heading
as="h1"
fontSize={{ base: "3xl", md: "4xl" }}
fontWeight="black"
bgGradient="linear(to-r, cyan.200, purple.200, pink.200)"
bgClip="text"
letterSpacing="tight"
textShadow="0 0 30px rgba(147, 197, 253, 0.3)"
>
概念中心
</Heading>
<HStack spacing={2} justify="center">
<Icon as={Clock} boxSize={3} color="cyan.200" />
<Text fontSize="xs" fontWeight="medium" opacity={0.8}>
数据约下午4点更新
</Text>
</HStack>
</VStack>
<Text fontSize="md" opacity={0.7} maxW="2xl">
AI驱动的概念板块分析平台 · 实时追踪市场热点 · 智能挖掘投资机会
</Text>
</VStack>
{/* 核心数据展示 */}
<HStack
spacing={6}
divider={<Box w="1px" h="30px" bg="whiteAlpha.300" />}
bg="whiteAlpha.100"
backdropFilter={GLASS_BLUR.sm}
px={8}
py={3}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.300"
boxShadow="0 8px 32px rgba(0, 0, 0, 0.3)"
>
<HStack spacing={2}>
<Icon as={Tags} boxSize={4} color="cyan.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="cyan.300">500+</Text>
<Text fontSize="xs" opacity={0.7}>概念板块</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={LineChart} boxSize={4} color="purple.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="purple.300">5000+</Text>
<Text fontSize="xs" opacity={0.7}>相关个股</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={Zap} boxSize={4} color="yellow.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="yellow.300">24/7</Text>
<Text fontSize="xs" opacity={0.7}>实时监控</Text>
</VStack>
</HStack>
</HStack>
{/* 搜索框 */}
<Box w="100%" maxW="3xl">
<VStack spacing={2}>
<Box w="100%" position="relative">
<Flex
align="center"
bg="rgba(255, 255, 255, 0.95)"
backdropFilter={GLASS_BLUR.sm}
borderRadius="full"
overflow="hidden"
boxShadow="0 8px 32px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(139, 92, 246, 0.2)"
transition="all 0.3s"
_hover={{
boxShadow: '0 12px 40px rgba(139, 92, 246, 0.4), 0 0 0 2px rgba(139, 92, 246, 0.4)',
transform: 'translateY(-2px)',
}}
>
<InputGroup size="lg" flex={1}>
<InputLeftElement pointerEvents="none" h="full">
<Icon as={Search} color="purple.400" boxSize={5} />
</InputLeftElement>
<Input
placeholder="搜索概念板块、个股、关键词..."
bg="transparent"
color="gray.800"
border="none"
fontSize="md"
fontWeight="medium"
pl={12}
_placeholder={{ color: 'gray.400' }}
_focus={{
outline: 'none',
boxShadow: 'none'
}}
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onKeyPress={handleKeyPress}
pr={searchQuery ? "50px" : "16px"}
/>
{searchQuery && (
<IconButton
position="absolute"
right="10px"
top="50%"
transform="translateY(-50%)"
size="sm"
aria-label="清除搜索"
icon={<X size={16} />}
variant="ghost"
color="gray.500"
borderRadius="full"
_hover={{ color: 'gray.700', bg: 'gray.200' }}
onClick={handleClearSearch}
zIndex={1}
/>
)}
</InputGroup>
<Button
size="lg"
borderRadius="0 50px 50px 0"
bgGradient="linear(135deg, #667eea 0%, #764ba2 100%)"
color="white"
leftIcon={<Search size={16} />}
_hover={{
bgGradient: 'linear(135deg, #5568d3 0%, #663a8e 100%)',
transform: 'scale(1.02)',
}}
_active={{
bgGradient: 'linear(135deg, #4a5abf 0%, #58327a 100%)',
transform: 'scale(0.98)',
}}
onClick={handleSearch}
isLoading={loading}
loadingText="搜索中"
px={8}
minW="140px"
fontWeight="bold"
fontSize="md"
transition="all 0.2s"
border="none"
alignSelf="stretch"
boxShadow="inset 0 1px 0 rgba(255, 255, 255, 0.2)"
>
搜索
</Button>
</Flex>
</Box>
{searchQuery && sortBy === '_score' && (
<Text fontSize="xs" color="cyan.200" opacity={0.9}>
正在搜索 "{searchQuery}"已自动切换到相关度排序
</Text>
)}
</VStack>
</Box>
</VStack>
</Box>
</Box>
{/* Hero Section - 使用通用 HeroSection 组件 */}
<HeroSection
icon={Brain}
title="概念中心"
subtitle="AI驱动的概念板块分析平台 · 实时追踪市场热点 · 智能挖掘投资机会"
updateHint={
<HStack spacing={2} justify="center">
<Icon as={Clock} boxSize={3} color="cyan.200" />
<Text fontSize="xs" fontWeight="medium" opacity={0.8}>
数据约下午4点更新
</Text>
</HStack>
}
themePreset="purple"
fullWidth
decorations={[
{ type: 'grid', intensity: 0.3 },
{ type: 'glowOrbs', intensity: 0.5 },
]}
search={{
placeholder: '搜索概念板块、个股、关键词...',
showSearchButton: true,
searchButtonText: '搜索',
maxWidth: '2xl',
// 受控模式
value: searchQuery,
onChange: setSearchQuery,
onClear: handleClearSearch,
isSearching: false,
showDropdown: false,
onSearch: async () => {
handleSearch();
return [];
},
onResultSelect: () => {},
}}
stats={{
columns: { base: 3, md: 3 },
showIcons: false,
items: [
{ key: 'concepts', label: '概念板块', value: '500+', icon: Tags, iconColor: 'cyan.300', valueColor: 'cyan.300' },
{ key: 'stocks', label: '相关个股', value: '5000+', icon: LineChart, iconColor: 'purple.300', valueColor: 'purple.300' },
{ key: 'monitor', label: '实时监控', value: '24/7', icon: Zap, iconColor: 'yellow.300', valueColor: 'yellow.300' },
],
}}
afterSearch={
searchQuery && sortBy === '_score' ? (
<Text fontSize="xs" color="cyan.200" opacity={0.9}>
正在搜索 "{searchQuery}"已自动切换到相关度排序
</Text>
) : null
}
/>
{/* 主内容区域 - padding 由 MainLayout 统一设置 */}
<Box py={10} position="relative" zIndex={1}>