Merge branch 'feature_bugfix/251201_vf_h5_ui' into feature_bugfix/251201_py_h5_ui
* feature_bugfix/251201_vf_h5_ui: fix: 去除个股中心动画,添加mock数据 feat: 首页代码优化
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// src/views/Home/HomePage.tsx
|
||||
// 首页 - 专业投资分析平台
|
||||
|
||||
import React, { useEffect, useCallback, useState } from 'react';
|
||||
import React, { useEffect, useCallback, useRef } from 'react';
|
||||
import { Box, Container, VStack, SimpleGrid } from '@chakra-ui/react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
@@ -11,7 +11,6 @@ import { ACQUISITION_EVENTS } from '@/lib/constants';
|
||||
import { CORE_FEATURES } from '@/constants/homeFeatures';
|
||||
import { performanceMonitor } from '@/utils/performanceMonitor';
|
||||
import type { Feature } from '@/types/home';
|
||||
import { HeroBackground } from './components/HeroBackground';
|
||||
import { HeroHeader } from './components/HeroHeader';
|
||||
import { FeaturedFeatureCard } from './components/FeaturedFeatureCard';
|
||||
import { FeatureCard } from './components/FeatureCard';
|
||||
@@ -25,7 +24,13 @@ const HomePage: React.FC = () => {
|
||||
const { user, isAuthenticated } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const { track } = usePostHogTrack();
|
||||
const [imageLoaded, setImageLoaded] = useState(false);
|
||||
|
||||
// ⚡ 性能标记:渲染开始(组件函数执行时,使用 ref 避免严格模式下重复标记)
|
||||
const hasMarkedStart = useRef(false);
|
||||
if (!hasMarkedStart.current) {
|
||||
performanceMonitor.mark('homepage-render-start');
|
||||
hasMarkedStart.current = true;
|
||||
}
|
||||
|
||||
// 响应式配置
|
||||
const {
|
||||
@@ -34,12 +39,11 @@ const HomePage: React.FC = () => {
|
||||
headingLetterSpacing,
|
||||
heroTextSize,
|
||||
containerPx,
|
||||
showDecorations
|
||||
} = useHomeResponsive();
|
||||
|
||||
// ⚡ 性能标记:首页组件挂载 = 渲染开始
|
||||
// ⚡ 性能标记:渲染完成(DOM 已挂载)
|
||||
useEffect(() => {
|
||||
performanceMonitor.mark('homepage-render-start');
|
||||
performanceMonitor.mark('homepage-render-end');
|
||||
}, []);
|
||||
|
||||
// PostHog 追踪:页面浏览
|
||||
@@ -70,13 +74,6 @@ const HomePage: React.FC = () => {
|
||||
}
|
||||
}, [track, navigate]);
|
||||
|
||||
// 背景图片加载完成回调
|
||||
const handleImageLoad = useCallback(() => {
|
||||
setImageLoaded(true);
|
||||
// ⚡ 性能标记:首页渲染完成(背景图片加载完成 = 首屏视觉完整)
|
||||
performanceMonitor.mark('homepage-render-end');
|
||||
}, []);
|
||||
|
||||
// 特色功能(第一个)
|
||||
const featuredFeature = CORE_FEATURES[0];
|
||||
// 其他功能
|
||||
@@ -91,12 +88,6 @@ const HomePage: React.FC = () => {
|
||||
bg="linear-gradient(135deg, #0E0C15 0%, #15131D 50%, #252134 100%)"
|
||||
overflow="hidden"
|
||||
>
|
||||
{/* 背景装饰 */}
|
||||
<HeroBackground
|
||||
imageLoaded={imageLoaded}
|
||||
onImageLoad={handleImageLoad}
|
||||
showDecorations={showDecorations}
|
||||
/>
|
||||
|
||||
<Container maxW="7xl" position="relative" zIndex={30} px={containerPx}>
|
||||
<VStack
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// src/views/Home/components/HeroBackground.tsx
|
||||
// 首页英雄区背景装饰组件
|
||||
|
||||
import React from 'react';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import heroBg from '@assets/img/BackgroundCard1.png';
|
||||
|
||||
interface HeroBackgroundProps {
|
||||
imageLoaded: boolean;
|
||||
onImageLoad: () => void;
|
||||
showDecorations: boolean | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页英雄区背景组件
|
||||
* 包含背景图片和装饰性几何图形
|
||||
*/
|
||||
export const HeroBackground: React.FC<HeroBackgroundProps> = ({
|
||||
imageLoaded,
|
||||
onImageLoad,
|
||||
showDecorations
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{/* 背景图片 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top="0"
|
||||
right="0"
|
||||
w="50%"
|
||||
h="100%"
|
||||
bgImage={imageLoaded ? `url(${heroBg})` : 'none'}
|
||||
bgSize="cover"
|
||||
bgPosition="center"
|
||||
opacity={imageLoaded ? 0.3 : 0}
|
||||
transition="opacity 0.5s ease-in"
|
||||
_after={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: 'linear-gradient(90deg, rgba(14, 12, 21, 0.9) 0%, rgba(14, 12, 21, 0.3) 100%)'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 预加载背景图片 */}
|
||||
<Box display="none">
|
||||
<img
|
||||
src={heroBg}
|
||||
alt=""
|
||||
onLoad={onImageLoad}
|
||||
onError={onImageLoad}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* 装饰性几何图形 - 移动端隐藏 */}
|
||||
{showDecorations && (
|
||||
<>
|
||||
<Box
|
||||
position="absolute"
|
||||
top="20%"
|
||||
left="10%"
|
||||
w={{ base: '100px', md: '150px', lg: '200px' }}
|
||||
h={{ base: '100px', md: '150px', lg: '200px' }}
|
||||
borderRadius="50%"
|
||||
bg="rgba(255, 215, 0, 0.1)"
|
||||
filter="blur(80px)"
|
||||
className="float-animation"
|
||||
/>
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="30%"
|
||||
right="20%"
|
||||
w={{ base: '80px', md: '120px', lg: '150px' }}
|
||||
h={{ base: '80px', md: '120px', lg: '150px' }}
|
||||
borderRadius="50%"
|
||||
bg="rgba(138, 43, 226, 0.1)"
|
||||
filter="blur(60px)"
|
||||
className="float-animation-reverse"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -42,7 +42,6 @@ import {
|
||||
useDisclosure,
|
||||
Image,
|
||||
Fade,
|
||||
ScaleFade,
|
||||
Collapse,
|
||||
Stack,
|
||||
Progress,
|
||||
@@ -58,25 +57,12 @@ import {
|
||||
import { SearchIcon, CloseIcon, ArrowForwardIcon, TrendingUpIcon, InfoIcon, ChevronRightIcon, MoonIcon, SunIcon, CalendarIcon } from '@chakra-ui/icons';
|
||||
import { FaChartLine, FaFire, FaRocket, FaBrain, FaCalendarAlt, FaChevronRight, FaArrowUp, FaArrowDown, FaChartBar } from 'react-icons/fa';
|
||||
import { BsGraphUp, BsLightningFill } from 'react-icons/bs';
|
||||
import { keyframes } from '@emotion/react';
|
||||
import * as echarts from 'echarts';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { useStockOverviewEvents } from './hooks/useStockOverviewEvents';
|
||||
// Navigation bar now provided by MainLayout
|
||||
// import HomeNavbar from '../../components/Navbars/HomeNavbar';
|
||||
|
||||
// 动画定义
|
||||
const pulseAnimation = keyframes`
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
100% { transform: scale(1); }
|
||||
`;
|
||||
|
||||
const floatAnimation = keyframes`
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-10px); }
|
||||
`;
|
||||
|
||||
const StockOverview = () => {
|
||||
const navigate = useNavigate();
|
||||
const toast = useToast();
|
||||
@@ -622,7 +608,7 @@ const StockOverview = () => {
|
||||
<Container maxW="container.xl" position="relative">
|
||||
<VStack spacing={8} align="center">
|
||||
<VStack spacing={4} textAlign="center" maxW="3xl">
|
||||
<HStack spacing={3} animation={`${floatAnimation} 3s ease-in-out infinite`}>
|
||||
<HStack spacing={3}>
|
||||
<Icon as={BsGraphUp} boxSize={12} color={colorMode === 'dark' ? goldColor : 'white'} />
|
||||
<Heading
|
||||
as="h1"
|
||||
@@ -922,8 +908,8 @@ const StockOverview = () => {
|
||||
) : (
|
||||
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={6}>
|
||||
{topConcepts.map((concept, index) => (
|
||||
<ScaleFade in={true} initialScale={0.9} key={concept.concept_id}>
|
||||
<Card
|
||||
key={concept.concept_id}
|
||||
bg={cardBg}
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
@@ -964,7 +950,6 @@ const StockOverview = () => {
|
||||
px={3}
|
||||
py={1}
|
||||
borderRadius="full"
|
||||
animation={Math.abs(concept.change_percent) > 5 ? `${pulseAnimation} 2s infinite` : 'none'}
|
||||
border={colorMode === 'dark' ? '1px solid' : 'none'}
|
||||
borderColor={colorMode === 'dark' ? concept.change_percent > 0 ? '#ff4d4d' : '#22c55e' : 'transparent'}
|
||||
>
|
||||
@@ -1039,7 +1024,6 @@ const StockOverview = () => {
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</ScaleFade>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user