Files
vf_react/src/views/Home/HomePage.tsx
zdl 70509a02c9 feat(HomePage): 已登录用户访问首页展示个人中心内容
- HomePage: 添加条件渲染,已登录时展示 Center 组件
- 重构 Center 目录结构,合并 Center.tsx 到 index.tsx
- 重命名 CenterDashboard 为 Center(lazy-components, homeRoutes)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-24 11:06:30 +08:00

181 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/views/Home/HomePage.tsx
// 首页 - 专业投资分析平台
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';
import { usePostHogTrack } from '@/hooks/usePostHogRedux';
import { useHomeResponsive } from '@/hooks/useHomeResponsive';
import { ACQUISITION_EVENTS } from '@/lib/constants';
import { CORE_FEATURES } from '@/constants/homeFeatures';
import { performanceMonitor } from '@/utils/performanceMonitor';
import type { Feature } from '@/types/home';
import { HeroHeader } from './components/HeroHeader';
import { FeaturedFeatureCard } from './components/FeaturedFeatureCard';
import { FeatureCard } from './components/FeatureCard';
import MiniProgramLauncher from '@/components/MiniProgramLauncher';
import { isMobileDevice } from '@/components/MiniProgramLauncher/hooks/useWechatEnvironment';
import Center from '@views/Center';
import '@/styles/home-animations.css';
/**
* 首页组件
* 展示平台核心功能,引导用户探索各个功能模块
*/
const HomePage: React.FC = () => {
const { user, isAuthenticated, isLoading } = useAuth();
const navigate = useNavigate();
const { track } = usePostHogTrack();
// ⚡ 性能标记:渲染开始(组件函数执行时,使用 ref 避免严格模式下重复标记)
const hasMarkedStart = useRef(false);
if (!hasMarkedStart.current) {
performanceMonitor.mark('homepage-render-start');
hasMarkedStart.current = true;
}
// 响应式配置
const {
headingSize,
headingLetterSpacing,
heroTextSize,
containerPx,
} = useHomeResponsive();
// ⚡ 性能标记渲染完成DOM 已挂载)
useEffect(() => {
performanceMonitor.mark('homepage-render-end');
}, []);
// PostHog 追踪:页面浏览
useEffect(() => {
track(ACQUISITION_EVENTS.LANDING_PAGE_VIEWED, {
timestamp: new Date().toISOString(),
is_authenticated: isAuthenticated,
user_id: user?.id || null,
});
}, [track, isAuthenticated, user?.id]);
// 功能卡片点击处理
const handleFeatureClick = useCallback((feature: Feature) => {
// PostHog 追踪:功能卡片点击
track(ACQUISITION_EVENTS.FEATURE_CARD_VIEWED, {
feature_id: feature.id,
feature_title: feature.title,
feature_url: feature.url,
is_featured: feature.featured || false,
link_type: feature.url.startsWith('http') ? 'external' : 'internal',
});
// 导航处理
if (feature.url.startsWith('http')) {
window.open(feature.url, '_blank');
} else {
navigate(feature.url);
}
}, [track, navigate]);
// 特色功能(第一个)
const featuredFeature = CORE_FEATURES[0];
// 其他功能
const regularFeatures = CORE_FEATURES.slice(1);
// 移动端判断(用于显示小程序入口)
const isMobile = isMobileDevice();
// 等待认证状态确认(避免闪烁)
if (isLoading) {
return null;
}
// 已登录直接渲染个人中心
if (isAuthenticated && user) {
return <Center />;
}
// 未登录渲染首页内容
return (
<Box minH="100%">
{/* Hero Section - 深色科技风格,自适应容器高度 */}
<Box
position="relative"
minH="100%"
bg="linear-gradient(135deg, #0E0C15 0%, #15131D 50%, #252134 100%)"
overflow="hidden"
>
<Container maxW="7xl" position="relative" px={containerPx}>
<VStack
spacing={{ base: 5, md: 8, lg: 10 }}
align="stretch"
py={{ base: 8, md: 10, lg: 12 }}
justify="center"
>
{/* 主标题区域 */}
<HeroHeader
headingSize={headingSize}
headingLetterSpacing={headingLetterSpacing}
heroTextSize={heroTextSize}
/>
{/* 核心功能面板 */}
<Box pb={{ base: 5, md: 8 }}>
<VStack spacing={{ base: 4, md: 5 }}>
{/* 特色功能卡片 - 新闻中心 */}
<FeaturedFeatureCard
feature={featuredFeature}
onClick={handleFeatureClick}
/>
{/* 其他功能卡片 */}
<SimpleGrid
columns={{ base: 1, md: 2, lg: 3 }}
spacing={{ base: 2, md: 3, lg: 4 }}
w="100%"
>
{regularFeatures.map((feature) => (
<FeatureCard
key={feature.id}
feature={feature}
onClick={handleFeatureClick}
/>
))}
</SimpleGrid>
</VStack>
</Box>
</VStack>
</Container>
</Box>
{/* 移动端右上角固定按钮 - 小程序入口 */}
{isMobile && (
<Box
position="fixed"
top="70px"
right="16px"
zIndex={1000}
>
<MiniProgramLauncher
path="pages/index/index"
forceLaunchMethod="urlScheme"
buttonStyle={{
backgroundColor: '#07c160',
color: '#fff',
padding: '8px 16px',
fontSize: '14px',
fontWeight: '500',
borderRadius: '20px',
boxShadow: '0 2px 8px rgba(7, 193, 96, 0.3)',
}}
>
</MiniProgramLauncher>
</Box>
)}
</Box>
);
};
export default HomePage;