feat: 热点事件UI调整成轮播图

This commit is contained in:
zdl
2025-10-27 17:22:03 +08:00
parent 03c113fe1b
commit 31a7500388
4 changed files with 257 additions and 51 deletions

View File

@@ -1,13 +1,34 @@
// src/views/Community/components/HotEvents.js
import React from 'react';
import { Card, Row, Col, Badge, Tag, Empty } from 'antd';
import { ArrowUpOutlined, ArrowDownOutlined, FireOutlined } from '@ant-design/icons';
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 HotEvents = ({ events }) => {
// 自定义箭头组件
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) {
@@ -39,12 +60,60 @@ const HotEvents = ({ events }) => {
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 ? (
<Row gutter={[16, 16]}>
<Carousel {...carouselSettings} className="hot-events-carousel">
{events.map((event, index) => (
<Col lg={6} md={12} sm={24} key={event.id}>
<div key={event.id} className="carousel-item">
<Card
hoverable
className="hot-event-card"
@@ -69,33 +138,36 @@ const HotEvents = ({ events }) => {
</div>
}
>
<Card.Meta
title={
<div className="event-header">
{renderPriceChange(event.related_avg_chg)}
<span className="event-title">
{event.title}
</span>
</div>
}
description={
<>
<p className="event-description">
{event.description && event.description.length > 80
? `${event.description.substring(0, 80)}...`
: event.description}
</p>
<div className="event-footer">
<span className="creator">{event.creator?.username || 'Anonymous'}</span>
<span className="time">{moment(event.created_at).format('MM-DD HH:mm')}</span>
</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>
</Col>
</div>
))}
</Row>
</Carousel>
) : (
<Card>
<Empty description="暂无热点信息" />