Files
timeline-frontend/src/pages/list/basic-list/components/TimelineItem/TimelineItem.tsx

156 lines
5.6 KiB
TypeScript
Raw Normal View History

2025-07-22 22:52:55 +08:00
import { Badge, Col, Drawer, Row, Timeline } from 'antd';
import React from 'react';
import TimelineImage from '@/components/TimelineImage';
import TimelineItemDrawer from '@/pages/list/basic-list/components/TimelineItemDrawer';
import { StoryItem, TimelineEvent } from '@/pages/list/basic-list/data';
import './index.css';
interface TimelineItemProps {
event: StoryItem;
onUpdate?: (updatedEvent: TimelineEvent) => void; // 数据更新回调
}
const TimelineItem = ({ event: initialEvent, onUpdate }: TimelineItemProps) => {
const [openMainDrawer, setOpenMainDrawer] = React.useState(false);
const [expanded, setExpanded] = React.useState(false); // 控制子项展开状态
const [openSubDrawer, setOpenSubDrawer] = React.useState(false);
const [selectedSubItem, setSelectedSubItem] = React.useState<TimelineEvent | null>(null);
const showMainDrawer = () => {
setOpenMainDrawer(true);
};
return (
<div className={`timeline-item ${expanded ? 'expanded' : ''}`}>
{/* 主时间线容器 */}
<div className={`timeline-event-container ${expanded ? 'expanded' : ''}`}>
<div className={`timeline-event ${expanded ? 'minimized' : ''}`}>
<Row gutter={24} align="middle">
<Col span={6}>
<TimelineImage
width={200}
height={200}
title={initialEvent.title}
imageInstanceId={initialEvent.coverInstanceId}
/>
</Col>
<Col span={16} offset={2}>
<div className="timeline-content-text" onClick={showMainDrawer}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 'bold' }}>{initialEvent.title}</h2>
<p style={{ marginBottom: '0.5rem' }}>{initialEvent.description}</p>
<div style={{ color: '#666', lineHeight: '1.6' }}>
<span>{initialEvent.storyItemTime}</span>
<br />
<span>{initialEvent.createTime}</span>
<br />
<span>{initialEvent.updateTime}</span>
</div>
</div>
</Col>
</Row>
{/* 子时间点徽章 */}
{initialEvent.subItems && initialEvent.subItems.length > 0 && (
<Badge
count={`${initialEvent.subItems.length} 个子时间点`}
style={{
backgroundColor: '#1890ff',
position: 'absolute',
top: 10,
right: 10,
transform: 'translate(50%, -50%)', // 修复超出边界
padding: '0 6px',
borderRadius: 4,
cursor: 'pointer',
fontSize: 12,
height: 20,
lineHeight: '20px',
textAlign: 'center',
minWidth: 60,
boxSizing: 'border-box',
}}
onClick={(e) => {
e.stopPropagation();
setExpanded(!expanded);
}}
/>
)}
</div>
{/* 子时间线列表 */}
{initialEvent.subItems && initialEvent.subItems.length > 0 && expanded && (
<div className="sub-timeline-wrapper">
<Timeline
mode="left"
items={initialEvent.subItems.map((sub) => ({
children: (
<div
className="sub-timeline-item"
style={{
fontSize: '12px',
padding: '8px 0',
cursor: 'pointer',
transition: 'background-color 0.2s',
':hover': { backgroundColor: '#f5f5f5' }, // 添加 hover 效果
}}
>
<Row>
<Col span={4}>
<TimelineImage title={sub.title} imageInstanceId={sub.coverInstanceId} />
</Col>
<Col span={18} offset={2}>
<div className="timeline-content-text" onClick={showMainDrawer}>
<h2 style={{ fontSize: '1.2rem', fontWeight: 'normal' }}>{sub.title}</h2>
<p style={{ marginBottom: '0.5rem' }}>{sub.description}</p>
<div style={{ color: '#999', lineHeight: '1.6' }}>
<span>{sub.storyItemTime}</span>
<br />
<span>{sub.createTime}</span>
<br />
<span>{sub.updateTime}</span>
</div>
</div>
</Col>
</Row>
</div>
),
}))}
/>
</div>
)}
{/* 主时间点详情抽屉 */}
<TimelineItemDrawer
storyItem={initialEvent}
open={openMainDrawer}
setOpen={setOpenMainDrawer}
/>
{/* 子时间点详情抽屉 */}
{selectedSubItem && (
<Drawer
width={640}
placement="right"
onClose={() => setOpenSubDrawer(false)}
open={openSubDrawer}
title={selectedSubItem.title}
>
<p style={{ marginBottom: 24 }}>
<strong></strong>
{selectedSubItem.description}
</p>
<p>
<strong></strong>
{selectedSubItem.time || '未设置'}
</p>
</Drawer>
)}
</div>
</div>
);
};
export default TimelineItem;