feat: 日历空状态优化 - 添加高亮导航链接

- CalendarPanel: 移除底部关闭按钮,优化空状态文案
- 空状态添加日历图标和引导文案
- 「计划」「复盘」「投资日历」高亮可点击
- 点击计划/复盘切换到对应列表视图
- 点击投资日历打开投资日历弹窗
- 扩展 PlanningContextValue 类型支持导航方法

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-05 13:40:43 +08:00
parent 863212f53f
commit 0cc75462aa
3 changed files with 83 additions and 2 deletions

View File

@@ -145,4 +145,14 @@ export interface PlanningContextValue {
/** 卡片背景色 */ /** 卡片背景色 */
cardBg: string; cardBg: string;
// 导航方法(可选,用于空状态引导)
/** 切换视图模式 */
setViewMode?: (mode: 'calendar' | 'list') => void;
/** 切换列表 Tab */
setListTab?: (tab: number) => void;
/** 关闭弹窗 */
closeModal?: () => void;
} }

View File

@@ -3,7 +3,7 @@
* 使用 FullCalendar 展示投资计划、复盘等事件 * 使用 FullCalendar 展示投资计划、复盘等事件
*/ */
import React, { useState } from 'react'; import React, { useState, lazy, Suspense } from 'react';
import { import {
Box, Box,
Modal, Modal,
@@ -18,6 +18,7 @@ import {
Spinner, Spinner,
Center, Center,
Icon, Icon,
Link,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiCalendar } from 'react-icons/fi'; import { FiCalendar } from 'react-icons/fi';
import FullCalendar from '@fullcalendar/react'; import FullCalendar from '@fullcalendar/react';
@@ -32,6 +33,9 @@ import { usePlanningData } from './PlanningContext';
import { EventDetailCard } from './EventDetailCard'; import { EventDetailCard } from './EventDetailCard';
import type { InvestmentEvent } from '@/types'; import type { InvestmentEvent } from '@/types';
// 懒加载投资日历组件
const InvestmentCalendar = lazy(() => import('@/views/Community/components/InvestmentCalendar'));
dayjs.locale('zh-cn'); dayjs.locale('zh-cn');
/** /**
@@ -59,10 +63,14 @@ export const CalendarPanel: React.FC = () => {
loading, loading,
borderColor, borderColor,
secondaryText, secondaryText,
setViewMode,
setListTab,
} = usePlanningData(); } = usePlanningData();
// 详情弹窗 // 详情弹窗
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
// 投资日历弹窗
const [isInvestmentCalendarOpen, setIsInvestmentCalendarOpen] = useState(false);
const [selectedDate, setSelectedDate] = useState<Dayjs | null>(null); const [selectedDate, setSelectedDate] = useState<Dayjs | null>(null);
const [selectedDateEvents, setSelectedDateEvents] = useState<InvestmentEvent[]>([]); const [selectedDateEvents, setSelectedDateEvents] = useState<InvestmentEvent[]>([]);
@@ -155,7 +163,48 @@ export const CalendarPanel: React.FC = () => {
<Icon as={FiCalendar} boxSize={10} color="gray.300" /> <Icon as={FiCalendar} boxSize={10} color="gray.300" />
<Text color={secondaryText}></Text> <Text color={secondaryText}></Text>
<Text fontSize="sm" color={secondaryText}> <Text fontSize="sm" color={secondaryText}>
<Link
color="purple.500"
fontWeight="medium"
mx={1}
onClick={() => {
onClose();
setViewMode?.('list');
setListTab?.(0);
}}
cursor="pointer"
>
</Link>
<Link
color="green.500"
fontWeight="medium"
mx={1}
onClick={() => {
onClose();
setViewMode?.('list');
setListTab?.(1);
}}
cursor="pointer"
>
</Link>
<Link
color="blue.500"
fontWeight="medium"
mx={1}
onClick={() => {
onClose();
setIsInvestmentCalendarOpen(true);
}}
cursor="pointer"
>
</Link>
</Text> </Text>
</VStack> </VStack>
</Center> </Center>
@@ -176,6 +225,26 @@ export const CalendarPanel: React.FC = () => {
</Modal> </Modal>
)} )}
{/* 投资日历 Modal */}
{isInvestmentCalendarOpen && (
<Modal
isOpen={isInvestmentCalendarOpen}
onClose={() => setIsInvestmentCalendarOpen(false)}
size="6xl"
>
<ModalOverlay />
<ModalContent maxW="1200px">
<ModalHeader></ModalHeader>
<ModalCloseButton />
<ModalBody pb={6}>
<Suspense fallback={<Center py={8}><Spinner size="xl" color="blue.500" /></Center>}>
<InvestmentCalendar />
</Suspense>
</ModalBody>
</ModalContent>
</Modal>
)}
</Box> </Box>
); );
}; };

View File

@@ -134,6 +134,8 @@ const InvestmentPlanningCenter: React.FC = () => {
textColor, textColor,
secondaryText, secondaryText,
cardBg, cardBg,
setViewMode,
setListTab,
}; };
// 计算各类型事件数量 // 计算各类型事件数量