180 lines
6.8 KiB
JavaScript
180 lines
6.8 KiB
JavaScript
// src/views/Community/components/HotEvents.js
|
|
import React, { useState } from 'react';
|
|
import { Card, Badge, Tag, Empty, Carousel, Tooltip } from 'antd';
|
|
import { ArrowUpOutlined, ArrowDownOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import moment from 'moment';
|
|
import './HotEvents.css';
|
|
import defaultEventImage from '../../../assets/img/default-event.jpg'
|
|
|
|
// 自定义箭头组件
|
|
const CustomArrow = ({ className, style, onClick, direction }) => {
|
|
const Icon = direction === 'left' ? LeftOutlined : RightOutlined;
|
|
return (
|
|
<div
|
|
className={`${className} custom-carousel-arrow`}
|
|
style={{
|
|
...style,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
}}
|
|
onClick={onClick}
|
|
>
|
|
<Icon style={{ fontSize: '20px', color: '#1890ff' }} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const HotEvents = ({ events, onPageChange }) => {
|
|
const navigate = useNavigate();
|
|
const [currentSlide, setCurrentSlide] = useState(0);
|
|
|
|
const renderPriceChange = (value) => {
|
|
if (value === null || value === undefined) {
|
|
return <Tag color="default">--</Tag>;
|
|
}
|
|
|
|
const isPositive = value > 0;
|
|
const icon = isPositive ? <ArrowUpOutlined /> : <ArrowDownOutlined />;
|
|
const color = isPositive ? '#ff4d4f' : '#52c41a';
|
|
|
|
return (
|
|
<Tag color={color}>
|
|
{icon} {Math.abs(value).toFixed(2)}%
|
|
</Tag>
|
|
);
|
|
};
|
|
|
|
const getImportanceColor = (importance) => {
|
|
const colors = {
|
|
S: 'red',
|
|
A: 'orange',
|
|
B: 'blue',
|
|
C: 'green'
|
|
};
|
|
return colors[importance] || 'default';
|
|
};
|
|
|
|
const handleCardClick = (eventId) => {
|
|
navigate(`/event-detail/${eventId}`);
|
|
};
|
|
|
|
// 计算总页数
|
|
const totalPages = Math.ceil((events?.length || 0) / 4);
|
|
|
|
// Carousel 配置
|
|
const carouselSettings = {
|
|
dots: false, // 隐藏圆点导航
|
|
infinite: true, // 始终启用无限循环,确保箭头显示
|
|
speed: 500,
|
|
slidesToShow: 4,
|
|
slidesToScroll: 1,
|
|
arrows: true, // 保留左右箭头
|
|
prevArrow: <CustomArrow direction="left" />,
|
|
nextArrow: <CustomArrow direction="right" />,
|
|
autoplay: false,
|
|
beforeChange: (_current, next) => {
|
|
// 计算实际页码(考虑无限循环)
|
|
const actualPage = next % totalPages;
|
|
setCurrentSlide(actualPage);
|
|
// 通知父组件页码变化
|
|
if (onPageChange) {
|
|
onPageChange(actualPage + 1, totalPages);
|
|
}
|
|
},
|
|
responsive: [
|
|
{
|
|
breakpoint: 1200,
|
|
settings: {
|
|
slidesToShow: 3,
|
|
slidesToScroll: 1,
|
|
}
|
|
},
|
|
{
|
|
breakpoint: 992,
|
|
settings: {
|
|
slidesToShow: 2,
|
|
slidesToScroll: 1,
|
|
}
|
|
},
|
|
{
|
|
breakpoint: 576,
|
|
settings: {
|
|
slidesToShow: 1,
|
|
slidesToScroll: 1,
|
|
}
|
|
}
|
|
]
|
|
};
|
|
|
|
return (
|
|
<div className="hot-events-section">
|
|
{events && events.length > 0 ? (
|
|
<Carousel {...carouselSettings} className="hot-events-carousel">
|
|
{events.map((event, index) => (
|
|
<div key={event.id} className="carousel-item">
|
|
<Card
|
|
hoverable
|
|
className="hot-event-card"
|
|
onClick={() => handleCardClick(event.id)}
|
|
cover={
|
|
<div className="event-cover">
|
|
<img
|
|
alt={event.title}
|
|
src={`/images/events/${['first', 'second', 'third', 'fourth'][index] || 'first'}.jpg`}
|
|
onError={e => {
|
|
e.target.onerror = null;
|
|
e.target.src = defaultEventImage;
|
|
}}
|
|
/>
|
|
{event.importance && (
|
|
<Badge
|
|
className="importance-badge"
|
|
color={getImportanceColor(event.importance)}
|
|
text={`${event.importance}级`}
|
|
/>
|
|
)}
|
|
</div>
|
|
}
|
|
>
|
|
{/* Custom layout without Card.Meta */}
|
|
<div className="event-header">
|
|
<Tooltip title={event.title}>
|
|
<span className="event-title">
|
|
{event.title}
|
|
</span>
|
|
</Tooltip>
|
|
<span className="event-tag">
|
|
{renderPriceChange(event.related_avg_chg)}
|
|
</span>
|
|
</div>
|
|
|
|
<Tooltip title={event.description}>
|
|
<div className="event-description">
|
|
{event.description}
|
|
</div>
|
|
</Tooltip>
|
|
|
|
<div className="event-footer">
|
|
<span className="creator">{event.creator?.username || 'Anonymous'}</span>
|
|
<span className="time">
|
|
<span className="time-date">{moment(event.created_at).format('YYYY-MM-DD')}</span>
|
|
{' '}
|
|
<span className="time-hour">{moment(event.created_at).format('HH:mm')}</span>
|
|
</span>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
))}
|
|
</Carousel>
|
|
) : (
|
|
<Card>
|
|
<Empty description="暂无热点信息" />
|
|
</Card>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default HotEvents; |