Add member activity routes and UI enhancements in MembersView
Integrate member activity management by adding new routes in the backend for member activities. Update MembersView.vue to include a button for opening the activities modal and implement the MemberActivitiesDialog component for displaying member activities. Enhance the UI with new button styles for better user interaction.
This commit is contained in:
120
backend/controllers/memberActivityController.js
Normal file
120
backend/controllers/memberActivityController.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import { checkAccess } from '../utils/userUtils.js';
|
||||
import DiaryMemberActivity from '../models/DiaryMemberActivity.js';
|
||||
import DiaryDateActivity from '../models/DiaryDateActivity.js';
|
||||
import DiaryDates from '../models/DiaryDates.js';
|
||||
import Participant from '../models/Participant.js';
|
||||
import PredefinedActivity from '../models/PredefinedActivity.js';
|
||||
import { Op } from 'sequelize';
|
||||
|
||||
export const getMemberActivities = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { clubId, memberId } = req.params;
|
||||
const { period } = req.query; // 'month', '3months', '6months', 'year', 'all'
|
||||
|
||||
await checkAccess(userToken, clubId);
|
||||
|
||||
// Calculate date range based on period
|
||||
const now = new Date();
|
||||
let startDate = null;
|
||||
|
||||
switch (period) {
|
||||
case 'month':
|
||||
startDate = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate());
|
||||
break;
|
||||
case '3months':
|
||||
startDate = new Date(now.getFullYear(), now.getMonth() - 3, now.getDate());
|
||||
break;
|
||||
case '6months':
|
||||
startDate = new Date(now.getFullYear(), now.getMonth() - 6, now.getDate());
|
||||
break;
|
||||
case 'year':
|
||||
startDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
|
||||
break;
|
||||
case 'all':
|
||||
default:
|
||||
startDate = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get participant ID for this member
|
||||
const participants = await Participant.findAll({
|
||||
where: { memberId: memberId }
|
||||
});
|
||||
|
||||
if (participants.length === 0) {
|
||||
return res.status(200).json([]);
|
||||
}
|
||||
|
||||
const participantIds = participants.map(p => p.id);
|
||||
|
||||
// Get all diary member activities for this member
|
||||
const whereClause = {
|
||||
participantId: participantIds
|
||||
};
|
||||
|
||||
const memberActivities = await DiaryMemberActivity.findAll({
|
||||
where: whereClause,
|
||||
include: [
|
||||
{
|
||||
model: DiaryDateActivity,
|
||||
as: 'activity',
|
||||
include: [
|
||||
{
|
||||
model: DiaryDates,
|
||||
as: 'diaryDate',
|
||||
where: startDate ? {
|
||||
date: {
|
||||
[Op.gte]: startDate
|
||||
}
|
||||
} : {}
|
||||
},
|
||||
{
|
||||
model: PredefinedActivity,
|
||||
as: 'predefinedActivity'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
order: [[{ model: DiaryDateActivity, as: 'activity' }, { model: DiaryDates, as: 'diaryDate' }, 'date', 'DESC']]
|
||||
});
|
||||
|
||||
// Group activities by name and count occurrences
|
||||
const activityMap = new Map();
|
||||
|
||||
for (const ma of memberActivities) {
|
||||
if (!ma.activity || !ma.activity.predefinedActivity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const activity = ma.activity.predefinedActivity;
|
||||
const activityName = activity.name;
|
||||
const date = ma.activity.diaryDate?.date;
|
||||
|
||||
if (!activityMap.has(activityName)) {
|
||||
activityMap.set(activityName, {
|
||||
name: activityName,
|
||||
count: 0,
|
||||
dates: []
|
||||
});
|
||||
}
|
||||
|
||||
const activityData = activityMap.get(activityName);
|
||||
activityData.count++;
|
||||
if (date) {
|
||||
activityData.dates.push(date);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map to array and sort by count
|
||||
const activities = Array.from(activityMap.values())
|
||||
.sort((a, b) => b.count - a.count);
|
||||
|
||||
return res.status(200).json(activities);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fetching member activities:', error);
|
||||
return res.status(500).json({ error: 'Failed to fetch member activities' });
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user