| import React, { useState } from 'react'; |
| import './PromotionCarousel.css'; |
| |
| const PromotionCarousel = ({ |
| promotions, |
| isAdmin, |
| openCreateDialog, |
| openCategoryDialog, |
| fetchColdTorrents, |
| handleDeletePromotion, |
| fetchPromotionDetail |
| }) => { |
| // 1. 新增状态:跟踪当前轮播项的索引 |
| const [currentIndex, setCurrentIndex] = useState(0); |
| |
| // 2. 上一个/下一个轮播的逻辑 |
| const prevPromo = () => { |
| if (promotions.length === 0) return; |
| setCurrentIndex(prev => |
| prev === 0 ? promotions.length - 1 : prev - 1 |
| ); |
| }; |
| |
| const nextPromo = () => { |
| if (promotions.length === 0) return; |
| setCurrentIndex(prev => |
| prev === promotions.length - 1 ? 0 : prev + 1 |
| ); |
| }; |
| |
| // 3. 当前显示的促销项(从数组中取) |
| const currentPromo = promotions[currentIndex]; |
| |
| // 原有工具函数保持不变 |
| const formatDateTime = (dateTime) => { |
| if (!dateTime) return '未知'; |
| // dateTime [2025,1,3,12,10] |
| return new Date(...dateTime).toLocaleString(); |
| |
| }; |
| |
| // 修改为一个统一的处理函数,避免混淆 |
| const getUploadBonusDisplay = (promo) => { |
| if (!promo || typeof promo.discountPercentage !== 'number') return '无'; |
| const bonus = promo.discountPercentage; |
| return bonus > 0 ? `${(bonus * 100).toFixed(0)}%` : '无'; |
| }; |
| |
| const getDownloadDiscountDisplay = (promo) => { |
| if (!promo || typeof promo.discountPercentage !== 'number') return '无'; |
| const discount = promo.discountPercentage; |
| return discount < 0 ? `${Math.abs(discount * 100).toFixed(0)}%` : '无'; |
| }; |
| |
| |
| if (!Array.isArray(promotions) || promotions.length === 0 || !promotions[currentIndex]) { |
| return ( |
| <section className="carousel-section"> |
| <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2> |
| {isAdmin && ( |
| <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}> |
| <button className="create-btn" onClick={openCreateDialog}> |
| +创建冷门资源促销 |
| </button> |
| <button className="create-btn" onClick={openCategoryDialog}> |
| +创建特定分类促销 |
| </button> |
| </div> |
| )} |
| <div className="empty-state">暂无促销活动</div> |
| </section> |
| ); |
| } |
| |
| |
| return ( |
| <section className="carousel-section"> |
| <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2> |
| |
| {isAdmin && ( |
| <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}> |
| <button className="create-btn" onClick={openCreateDialog}> |
| +创建冷门资源促销 |
| </button> |
| <button className="create-btn" onClick={openCategoryDialog}> |
| +创建特定分类促销 |
| </button> |
| </div> |
| )} |
| |
| <div |
| className="carousel" |
| onMouseEnter={() => {}} |
| onMouseLeave={() => {}} |
| > |
| |
| <button className="arrow left" onClick={prevPromo}><</button> |
| <div className="slide"> |
| <div className='promotion-name'><strong>{currentPromo?.name ?? '未知'}</strong></div> |
| <div style={{ color: '#135c69' }}><strong>促销时间:</strong> |
| {currentPromo?.startTime && currentPromo?.endTime |
| ? `${formatDateTime(currentPromo.startTime)} ~ ${formatDateTime(currentPromo.endTime)}` |
| : '未知'} |
| </div> |
| <div style={{ color: '#135c69' }}><strong>上传奖励:</strong>{getUploadBonusDisplay(currentPromo)}</div> |
| <div style={{ color: '#135c69' }}><strong>下载折扣:</strong>{getDownloadDiscountDisplay(currentPromo)}</div> |
| {currentPromo?.description && ( |
| <div><strong>描述:</strong>{currentPromo.description}</div> |
| )} |
| |
| <div className="action-buttons" style={{ display: 'flex', gap: '10px' }}> |
| {isAdmin && ( |
| <button className="delete-btn" onClick={() => handleDeletePromotion(currentPromo.id)}> |
| 删除活动 |
| </button> |
| )} |
| <button |
| className="view-btn" |
| onClick={() => fetchPromotionDetail(currentPromo.id)} |
| aria-label={`查看${currentPromo.name}的详情`} |
| > |
| 查看详情 |
| </button> |
| </div> |
| </div> |
| <button className="arrow right" onClick={nextPromo}>></button> |
| |
| {/* 4. 新增:底部指示器 */} |
| <div className="carousel-indicators"> |
| {promotions.map((_, index) => ( |
| <div |
| key={index} |
| className={`indicator ${currentIndex === index ? 'active' : ''}`} |
| onClick={() => setCurrentIndex(index)} // 点击切换轮播项 |
| /> |
| ))} |
| </div> |
| </div> |
| </section> |
| ); |
| }; |
| |
| export default PromotionCarousel; |