first commit
All checks were successful
Deploy to Server / deploy (push) Successful in 19s

This commit is contained in:
爽哒哒
2026-03-20 23:30:57 +08:00
commit 290be5d5be
328 changed files with 37215 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
import React from 'react';
import { Card, Tag, Typography, Space, Divider } from 'antd';
import { CalendarOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import dayjs from 'dayjs';
import ReactMarkdown from 'react-markdown';
const { Title } = Typography;
const CompetitionCard = ({ competition }) => {
const navigate = useNavigate();
const getStatusColor = (status) => {
switch(status) {
case 'published': return 'cyan';
case 'registration': return 'green';
case 'submission': return 'blue';
case 'judging': return 'orange';
case 'ended': return 'red';
default: return 'default';
}
};
const getStatusText = (status) => {
switch(status) {
case 'published': return '即将开始';
case 'registration': return '报名中';
case 'submission': return '作品提交中';
case 'judging': return '评审中';
case 'ended': return '已结束';
default: return '草稿';
}
};
return (
<Card
hoverable
cover={
<div style={{ height: 280, overflow: 'hidden', position: 'relative' }}>
<img
alt={competition.title}
src={competition.display_cover_image || 'https://images.unsplash.com/photo-1556761175-5973dc0f32e7?w=400&h=280&fit=crop'}
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
<div style={{ position: 'absolute', top: 10, right: 10 }}>
<Tag color={getStatusColor(competition.status)} style={{ marginRight: 0, fontSize: 14, padding: '4px 12px' }}>
{getStatusText(competition.status)}
</Tag>
</div>
</div>
}
style={{ height: '100%', display: 'flex', flexDirection: 'column', fontSize: 16 }}
bodyStyle={{ flex: 1, display: 'flex', flexDirection: 'column', padding: 24 }}
onClick={() => navigate(`/competitions/${competition.id}`)}
>
<Title level={3} ellipsis={{ rows: 2 }} style={{ marginBottom: 12, height: 64, fontSize: 20 }}>
{competition.title}
</Title>
<div style={{
flex: 1,
color: 'rgba(255,255,255,0.65)',
overflow: 'hidden',
display: '-webkit-box',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
marginBottom: 0,
fontSize: '15px',
lineHeight: 1.6
}}>
<ReactMarkdown
allowedElements={['p', 'text', 'strong', 'em', 'del']}
unwrapDisallowed={true}
components={{
p: (props) => <span {...props} />,
}}
>
{competition.description}
</ReactMarkdown>
</div>
<Divider style={{ margin: '12px 0' }} />
<Space direction="vertical" style={{ width: '100%' }} size={8}>
<Space>
<CalendarOutlined style={{ color: '#1890ff', fontSize: 16 }} />
<span style={{ fontSize: 14 }}>
{dayjs(competition.start_time).format('YYYY-MM-DD')} ~ {dayjs(competition.end_time).format('YYYY-MM-DD')}
</span>
</Space>
</Space>
</Card>
);
};
export default CompetitionCard;