import React, { useMemo, useState } from 'react';
import { Button, Segmented, Select } from 'antd';
import { PlusOutlined, GlobalOutlined, BranchesOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import styles from './ActivityCalendar.less';
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const calendarEvents = [
{
id: 'earth-day',
title: '世界环保日',
start: dayjs('2020-12-14'),
end: dayjs('2020-12-15'),
tone: 'sand',
icon: ,
},
{
id: 'tree-day',
title: '全国植树日',
start: dayjs('2020-12-24'),
end: dayjs('2020-12-31'),
tone: 'mint',
icon: ,
},
];
const buildGrid = (referenceDate, viewMode) => {
if (viewMode === 'week') {
const startOfWeek = referenceDate.startOf('week');
const days = Array.from({ length: 7 }, (_, index) => startOfWeek.add(index, 'day'));
return { days, gridStart: startOfWeek, weeks: 1 };
}
const startOfMonth = referenceDate.startOf('month');
const gridStart = startOfMonth.startOf('week');
const days = Array.from({ length: 42 }, (_, index) => gridStart.add(index, 'day'));
return { days, gridStart, weeks: 6 };
};
const buildEventSegments = (events, gridStart, weeks) => {
const gridEnd = gridStart.add(weeks * 7 - 1, 'day').endOf('day');
const segments = [];
events.forEach((event) => {
const start = event.start;
const end = event.end;
if (end.isBefore(gridStart) || start.isAfter(gridEnd)) {
return;
}
for (let weekIndex = 0; weekIndex < weeks; weekIndex += 1) {
const weekStart = gridStart.add(weekIndex * 7, 'day');
const weekEnd = weekStart.add(6, 'day').endOf('day');
const segmentStart = start.isAfter(weekStart) ? start : weekStart;
const segmentEnd = end.isBefore(weekEnd) ? end : weekEnd;
if (segmentEnd.isBefore(weekStart) || segmentStart.isAfter(weekEnd)) {
continue;
}
const columnStart = segmentStart.diff(weekStart, 'day') + 1;
const columnEnd = segmentEnd.diff(weekStart, 'day') + 2;
segments.push({
id: `${event.id}-${weekIndex}`,
title: event.title,
tone: event.tone,
icon: event.icon,
rowStart: weekIndex + 1,
rowEnd: weekIndex + 2,
columnStart,
columnEnd,
});
}
});
return segments;
};
const ActivityCalendar = () => {
const [currentDate, setCurrentDate] = useState(dayjs('2020-12-01'));
const [viewMode, setViewMode] = useState('month');
const { days, gridStart, weeks } = useMemo(() => buildGrid(currentDate, viewMode), [currentDate, viewMode]);
const segments = useMemo(() => buildEventSegments(calendarEvents, gridStart, weeks), [gridStart, weeks]);
const yearOptions = useMemo(() => {
const baseYear = dayjs().year();
const startYear = Math.min(2020, baseYear - 4);
return Array.from({ length: 10 }, (_, index) => startYear + index);
}, []);
const handleYearChange = (year) => {
setCurrentDate((prev) => prev.year(year));
};
const handleMonthChange = (month) => {
setCurrentDate((prev) => prev.month(month - 1));
};
const handleViewChange = (mode) => {
setViewMode(mode);
};
const handleBackToToday = () => {
const today = dayjs();
setCurrentDate(today);
setViewMode('month');
};
return (
} className={styles.createButton}>
新建活动
{weekDays.map((day) => (
{day}
))}
{days.map((day) => {
const isCurrentMonth = day.month() === currentDate.month();
return (
{day.date()}
);
})}
{segments.map((segment) => (
{segment.title}
{segment.icon}
))}
);
};
export default ActivityCalendar;