From 077e7f7743b3c7940e9710890c3564822b013063 Mon Sep 17 00:00:00 2001 From: PCBZ Date: Wed, 23 Apr 2025 21:54:01 -0700 Subject: [PATCH 1/4] remove active status --- Server/src/routes/event.js | 5 +-- client/src/components/donors/Donors.jsx | 4 +-- .../src/components/events/EventManagement.css | 2 +- client/src/services/eventService.js | 16 +++------ client/src/utils/statusConversion.js | 34 ++++++++----------- 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/Server/src/routes/event.js b/Server/src/routes/event.js index 12ea8cea..3632cc76 100644 --- a/Server/src/routes/event.js +++ b/Server/src/routes/event.js @@ -114,9 +114,6 @@ router.get('/', protect, async (req, res) => { if (validStatuses.includes(status)) { where.status = status; - } else if (status === 'active') { - // 特殊情况: 'active' 可以映射到多个"活跃"状态 - where.status = { in: ['Planning', 'ListGeneration', 'Review', 'Ready'] }; } } @@ -241,7 +238,7 @@ router.post('/', protect, async (req, res) => { timelineListGenerationDate, timelineReviewDeadline, timelineInvitationDate, - status = 'Planning' + status } = req.body; // Validate required fields diff --git a/client/src/components/donors/Donors.jsx b/client/src/components/donors/Donors.jsx index b1151efb..c0ae4f0b 100644 --- a/client/src/components/donors/Donors.jsx +++ b/client/src/components/donors/Donors.jsx @@ -503,7 +503,7 @@ const Donors = () => { * @param {Object} donor - The donor to edit status for */ const handleOpenStatusModal = (donor) => { - if (selectedEvent.status !== 'active') { + if (selectedEvent.status !== 'ready') { alert('Only events in Ready status can edit donor information'); return; } @@ -584,7 +584,7 @@ const Donors = () => { // Check if the selected event is in Ready status const isEventReady = () => { if (!selectedEvent) return false; - return selectedEvent.status === 'active'; + return selectedEvent.status === 'ready'; }; // handle status filter diff --git a/client/src/components/events/EventManagement.css b/client/src/components/events/EventManagement.css index a9c64618..d2760fd3 100644 --- a/client/src/components/events/EventManagement.css +++ b/client/src/components/events/EventManagement.css @@ -480,7 +480,7 @@ } /* Ready - Light Green */ -.activity-status.active { +.activity-status.ready { background-color: #D1FAE5; color: #10B981; } diff --git a/client/src/services/eventService.js b/client/src/services/eventService.js index 791140dc..d374f570 100644 --- a/client/src/services/eventService.js +++ b/client/src/services/eventService.js @@ -15,18 +15,10 @@ export const getEvents = async (params = {}) => { try { const url = new URL(`${API_URL}/api/events`); - // Handle incoming active status, map to correct backend status value - const modifiedParams = { ...params }; - - // If status is "active", replace it with backend understood value "Ready" - if (modifiedParams.status === 'active') { - modifiedParams.status = 'Ready'; - } - // Add query parameters - Object.keys(modifiedParams).forEach(key => { - if (modifiedParams[key] !== undefined && modifiedParams[key] !== '') { - url.searchParams.append(key, modifiedParams[key]); + Object.keys(params).forEach(key => { + if (params[key] !== undefined && params[key] !== '') { + url.searchParams.append(key, params[key]); } }); @@ -36,7 +28,7 @@ export const getEvents = async (params = {}) => { if (data.events) { data.events = data.events.map(event => ({ ...event, - status: event.status === 'Ready' ? 'active' : event.status.toLowerCase() + status: event.status.toLowerCase() })); } diff --git a/client/src/utils/statusConversion.js b/client/src/utils/statusConversion.js index d2dfed79..6f606729 100644 --- a/client/src/utils/statusConversion.js +++ b/client/src/utils/statusConversion.js @@ -7,27 +7,23 @@ */ export const toFrontendStatus = (backendStatus) => { if (!backendStatus) return ''; - - switch(backendStatus) { - case 'Ready': return 'active'; - default: return backendStatus.toLowerCase(); - } - }; + return backendStatus.toLowerCase(); +}; - /** - * Converts frontend event status format to backend format - * @param {string} frontendStatus - Status string from the frontend - * @returns {string} Backend-formatted status matching Prisma EventStatus enum - */ - export const toBackendStatus = (frontendStatus) => { +/** + * Converts frontend event status format to backend format + * @param {string} frontendStatus - Status string from the frontend + * @returns {string} Backend-formatted status matching Prisma EventStatus enum + */ +export const toBackendStatus = (frontendStatus) => { if (!frontendStatus) return 'Planning'; // Default value switch(frontendStatus) { - case 'active': return 'Ready'; - case 'complete': return 'Complete'; - case 'planning': return 'Planning'; - case 'listgeneration': return 'ListGeneration'; - case 'review': return 'Review'; - default: return frontendStatus; // Fallback if already in correct format + case 'complete': return 'Complete'; + case 'planning': return 'Planning'; + case 'listgeneration': return 'ListGeneration'; + case 'review': return 'Review'; + case 'ready': return 'Ready'; + default: return frontendStatus; // Fallback if already in correct format } - }; \ No newline at end of file +}; \ No newline at end of file From 71a96e26290678a0bbda77eaa620912c01c680c6 Mon Sep 17 00:00:00 2001 From: PCBZ Date: Wed, 23 Apr 2025 21:57:23 -0700 Subject: [PATCH 2/4] set status --- client/src/services/eventService.js | 8 -------- client/src/utils/statusConversion.js | 12 ++++++------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/client/src/services/eventService.js b/client/src/services/eventService.js index d374f570..58eb710a 100644 --- a/client/src/services/eventService.js +++ b/client/src/services/eventService.js @@ -24,14 +24,6 @@ export const getEvents = async (params = {}) => { const data = await fetchWithAuth(url.toString()); - // Map backend status values back to frontend values - if (data.events) { - data.events = data.events.map(event => ({ - ...event, - status: event.status.toLowerCase() - })); - } - return { data: data.events || [], page: data.page || 1, diff --git a/client/src/utils/statusConversion.js b/client/src/utils/statusConversion.js index 6f606729..a358c430 100644 --- a/client/src/utils/statusConversion.js +++ b/client/src/utils/statusConversion.js @@ -7,7 +7,7 @@ */ export const toFrontendStatus = (backendStatus) => { if (!backendStatus) return ''; - return backendStatus.toLowerCase(); + return backendStatus; }; /** @@ -19,11 +19,11 @@ export const toBackendStatus = (frontendStatus) => { if (!frontendStatus) return 'Planning'; // Default value switch(frontendStatus) { - case 'complete': return 'Complete'; - case 'planning': return 'Planning'; - case 'listgeneration': return 'ListGeneration'; - case 'review': return 'Review'; - case 'ready': return 'Ready'; + case 'Complete': return 'Complete'; + case 'Planning': return 'Planning'; + case 'ListGeneration': return 'ListGeneration'; + case 'Review': return 'Review'; + case 'Ready': return 'Ready'; default: return frontendStatus; // Fallback if already in correct format } }; \ No newline at end of file From 5dda4a2e3c8bb3b3b4d8024147d6f223fd77931e Mon Sep 17 00:00:00 2001 From: PCBZ Date: Wed, 23 Apr 2025 22:48:16 -0700 Subject: [PATCH 3/4] set active to Ready --- client/src/components/Dashboard.jsx | 2 +- client/src/components/donors/Donors.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/Dashboard.jsx b/client/src/components/Dashboard.jsx index d05e6cfe..f59ac9c6 100644 --- a/client/src/components/Dashboard.jsx +++ b/client/src/components/Dashboard.jsx @@ -31,7 +31,7 @@ const Dashboard = () => { const summary = await getDonorListsSummary(); // Fetch active events - const eventsResult = await getEvents({ status: 'active', limit: 10 }); + const eventsResult = await getEvents({ status: 'Ready', limit: 10 }); const activeEvents = eventsResult.data || []; // 在设置状态前检查组件是否仍然挂载 diff --git a/client/src/components/donors/Donors.jsx b/client/src/components/donors/Donors.jsx index c0ae4f0b..980ea309 100644 --- a/client/src/components/donors/Donors.jsx +++ b/client/src/components/donors/Donors.jsx @@ -503,7 +503,7 @@ const Donors = () => { * @param {Object} donor - The donor to edit status for */ const handleOpenStatusModal = (donor) => { - if (selectedEvent.status !== 'ready') { + if (selectedEvent.status !== 'Ready') { alert('Only events in Ready status can edit donor information'); return; } @@ -584,7 +584,7 @@ const Donors = () => { // Check if the selected event is in Ready status const isEventReady = () => { if (!selectedEvent) return false; - return selectedEvent.status === 'ready'; + return selectedEvent.status === 'Ready'; }; // handle status filter From dd28be6fba9036982b0467d54b8da1d0b05d2ed9 Mon Sep 17 00:00:00 2001 From: PCBZ Date: Wed, 23 Apr 2025 22:53:16 -0700 Subject: [PATCH 4/4] resolve dashboard numbers --- Server/src/routes/donorList.js | 52 +++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/Server/src/routes/donorList.js b/Server/src/routes/donorList.js index 1104c838..3e49ba1f 100644 --- a/Server/src/routes/donorList.js +++ b/Server/src/routes/donorList.js @@ -638,8 +638,12 @@ router.get('/:listId/stats', protect, async (req, res) => { */ router.get('/stats/summary', protect, async (req, res) => { try { - // Get all donor lists - const donorLists = await prisma.eventDonorList.findMany(); + // Get all donor lists with their eventDonors + const donorLists = await prisma.eventDonorList.findMany({ + include: { + eventDonors: true + } + }); if (donorLists.length === 0) { return res.status(200).json({ @@ -656,18 +660,44 @@ router.get('/stats/summary', protect, async (req, res) => { }); } - // Calculate aggregated statistics + // Calculate aggregated statistics from eventDonors const totalLists = donorLists.length; - const totalDonors = donorLists.reduce((sum, list) => sum + list.totalDonors, 0); - const totalApproved = donorLists.reduce((sum, list) => sum + list.approved, 0); - const totalExcluded = donorLists.reduce((sum, list) => sum + list.excluded, 0); - const totalPending = donorLists.reduce((sum, list) => sum + list.pending, 0); - const totalAutoExcluded = donorLists.reduce((sum, list) => sum + list.autoExcluded, 0); - const totalReviewed = totalApproved + totalExcluded; - const completedLists = donorLists.filter(list => list.reviewStatus === 'completed').length; const pendingLists = donorLists.filter(list => list.reviewStatus === 'pending').length; - + + // Initialize counters + let totalDonors = 0; + let totalApproved = 0; + let totalExcluded = 0; + let totalPending = 0; + let totalAutoExcluded = 0; + + // Calculate statistics from eventDonors + donorLists.forEach(list => { + const donors = list.eventDonors; + totalDonors += donors.length; + + donors.forEach(donor => { + switch (donor.status) { + case 'Approved': + totalApproved++; + break; + case 'Excluded': + totalExcluded++; + break; + case 'Pending': + totalPending++; + break; + default: + break; + } + if (donor.autoExcluded) { + totalAutoExcluded++; + } + }); + }); + + const totalReviewed = totalApproved + totalExcluded; const overallApprovalRate = totalDonors > 0 ? Math.round((totalApproved / totalDonors) * 100) : 0;