| // src/components/ActivityBoard.jsx |
| import React, { useEffect, useState } from 'react'; |
| import { Card, Row, Col, Typography, Spin, message, Modal } from 'antd'; |
| import { getFullActivities } from '../api/activity'; |
| import './ActivityBoard.css'; |
| |
| const { Paragraph, Text } = Typography; |
| |
| const ActivityBoard = () => { |
| const [activities, setActivities] = useState([]); |
| const [loading, setLoading] = useState(true); |
| const [modalVisible, setModalVisible] = useState(false); |
| const [selectedActivity, setSelectedActivity] = useState(null); |
| |
| useEffect(() => { |
| getFullActivities() |
| .then((res) => { |
| setActivities(res.data); |
| setLoading(false); |
| }) |
| .catch(() => { |
| message.error('获取公告失败'); |
| setLoading(false); |
| }); |
| }, []); |
| |
| const showModal = (activity) => { |
| setSelectedActivity(activity); |
| setModalVisible(true); |
| }; |
| |
| const handleClose = () => { |
| setModalVisible(false); |
| setSelectedActivity(null); |
| }; |
| |
| return ( |
| <> |
| {loading ? ( |
| <div className="loading-container"> |
| <Spin size="large" /> |
| </div> |
| ) : ( |
| <Row gutter={[24, 24]}> |
| {activities.map((activity) => ( |
| <Col xs={24} sm={12} md={8} lg={6} key={activity.activityid}> |
| <Card |
| hoverable |
| className="activity-card" |
| cover={ |
| <img |
| alt="活动图片" |
| src={`http://localhost:8080${activity.photo}`} |
| className="activity-photo" |
| onClick={() => showModal(activity)} |
| /> |
| } |
| > |
| <Card.Meta |
| title={<div className="activity-title">{activity.title}</div>} |
| /> |
| </Card> |
| </Col> |
| ))} |
| </Row> |
| )} |
| |
| {/* 弹窗展示公告详情 */} |
| <Modal |
| open={modalVisible} |
| title={selectedActivity?.title} |
| footer={null} |
| onCancel={handleClose} |
| centered |
| width={700} |
| bodyStyle={{ padding: '24px', maxHeight: '80vh', overflowY: 'auto' }} |
| > |
| {selectedActivity && ( |
| <div> |
| {selectedActivity.photo && ( |
| <img |
| src={`http://localhost:8080${selectedActivity.photo}`} |
| alt="公告图片" |
| style={{ width: '100%', maxHeight: 400, objectFit: 'cover', borderRadius: 8, marginBottom: 20 }} |
| /> |
| )} |
| <Paragraph style={{ fontSize: 16 }}>{selectedActivity.content}</Paragraph> |
| <Text type="secondary"> |
| 发布时间:{new Date(selectedActivity.time).toLocaleString()} |
| </Text> |
| </div> |
| )} |
| </Modal> |
| </> |
| ); |
| }; |
| |
| export default ActivityBoard; |