Overview
The Dashboard API provides role-specific statistics and insights for administrators, organizers, and students. Two versions are available:
/api/dashboard/stats - Original dashboard with basic statistics
/api/dashboard/stats-v2 - Enhanced dashboard with additional insights and analytics
Get Dashboard Stats
curl -X GET https://api.example.com/api/dashboard/stats \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/dashboard/stats
Authorization: Bearer YOUR_TOKEN
Retrieve dashboard statistics. The response varies based on the user’s role.
Authentication
Requires a valid JWT token. The response is customized based on the authenticated user’s role.
Response for ADMIN Role
Total number of students in the system
Total number of organizers (ORGANIZER + EVENT_ORGANIZER roles)
data.pendingProposalsCount
Number of proposals pending review for admin’s department
Number of event update requests pending L1 review
Number of upcoming events
Array of all active event objects (EventDTO[])
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"totalStudents": 1250,
"totalOrganizers": 45,
"pendingProposalsCount": 8,
"pendingUpdatesCount": 3,
"activeEventsCount": 12,
"activeEvents": [
{
"eventID": 1,
"title": "Spring Career Fair",
"eventDate": "2024-04-15",
"status": "UPCOMING",
"currentRegistrations": 234,
"capacity": 500
}
]
},
"timestamp": "2024-03-07T10:30:00"
}
Response for ORGANIZER Role
Number of active events organized by the user
data.totalRegistrationsForMyEvents
Total registrations across all organizer’s events
Object with proposal counts by status: {"APPROVED": 5, "PENDING": 2, "REJECTED": 1}
Array of events organized by the user
Array of all proposals submitted by the organizer
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"myActiveEvents": 3,
"totalRegistrationsForMyEvents": 145,
"myProposalStats": {
"APPROVED": 5,
"PENDING": 2,
"REJECTED": 1
},
"activeEvents": [
{
"eventID": 1,
"title": "Tech Workshop",
"eventDate": "2024-04-20",
"currentRegistrations": 28,
"capacity": 30,
"isOwner": true
}
],
"myProposals": [
{
"proposalID": 1,
"title": "Spring Conference",
"status": "APPROVED",
"submittedAt": "2024-03-01T10:00:00"
}
]
},
"timestamp": "2024-03-07T10:30:00"
}
Response for STUDENT Role
data.myTotalRegistrations
Total number of events the student is registered for
Array of events the student is registered for (deduplicated)
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"myTotalRegistrations": 5,
"activeEvents": [
{
"eventID": 1,
"title": "Career Fair",
"eventDate": "2024-04-15",
"venue": "Main Hall",
"isRegistered": true
},
{
"eventID": 3,
"title": "Tech Workshop",
"eventDate": "2024-04-20",
"venue": "Lab 201",
"isRegistered": true
}
]
},
"timestamp": "2024-03-07T10:30:00"
}
Get Dashboard Stats V2
curl -X GET https://api.example.com/api/dashboard/stats-v2 \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/dashboard/stats-v2
Authorization: Bearer YOUR_TOKEN
Retrieve enhanced dashboard statistics with additional insights and activity feeds.
Enhanced Fields for ADMIN (V2)
Includes all fields from V1 plus:
Number of post-event reports pending review for admin’s department
Array of recent activity/audit log entries (top 20)
data.recentActivity[].actorName
Email of the user who performed the action
data.recentActivity[].actorRole
Role of the actor: STUDENT, ORGANIZER, ADMIN
data.recentActivity[].action
Description of the action performed
data.recentActivity[].targetName
Name or identifier of the target entity
data.recentActivity[].timestamp
ISO 8601 timestamp of the activity
data.recentActivity[].navigationUrl
URL to navigate to the related resource
data.weeklyRegistrationCount
Number of registrations in the past 7 days
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"totalStudents": 1250,
"totalOrganizers": 45,
"pendingProposalsCount": 8,
"pendingUpdatesCount": 3,
"pendingReportsCount": 2,
"activeEventsCount": 12,
"weeklyRegistrationCount": 87,
"activeEvents": [...],
"recentActivity": [
{
"actorName": "[email protected]",
"actorRole": "STUDENT",
"action": "registered for Spring Career Fair",
"targetName": "Spring Career Fair",
"timestamp": "2024-03-07T09:15:00",
"navigationUrl": "/events/1"
},
{
"actorName": "[email protected]",
"actorRole": "ORGANIZER",
"action": "submitted proposal Tech Conference 2024",
"targetName": "Tech Conference 2024",
"timestamp": "2024-03-07T08:30:00",
"navigationUrl": "/proposals/5"
},
{
"actorName": "[email protected]",
"actorRole": "ADMIN",
"action": "approved proposal Alumni Networking",
"targetName": "Alumni Networking",
"timestamp": "2024-03-06T16:45:00",
"navigationUrl": "/proposals/3"
}
]
},
"timestamp": "2024-03-07T10:30:00"
}
Enhanced Fields for ORGANIZER (V2)
Includes all fields from V1 plus:
data.eventsNeedingAttention
Events requiring organizer attention (low attendance or near capacity)
data.oldestPendingProposalDays
Age in days of the oldest pending proposal
data.totalParticipantsAllTime
Total number of participants across all organizer’s events (all time)
Events Needing Attention Logic:
- Low attendance: less than 30% filled AND within 14 days
- Near capacity: greater than 90% filled AND greater than 3 days out
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"myActiveEvents": 2,
"totalRegistrationsForMyEvents": 145,
"myProposalStats": {
"APPROVED": 5,
"PENDING": 2,
"REJECTED": 1
},
"oldestPendingProposalDays": 7,
"totalParticipantsAllTime": 523,
"activeEvents": [...],
"myProposals": [...],
"eventsNeedingAttention": [
{
"eventID": 3,
"title": "Workshop on AI",
"eventDate": "2024-03-20",
"currentRegistrations": 8,
"capacity": 30,
"venue": "Lab 201"
}
]
},
"timestamp": "2024-03-07T10:30:00"
}
Enhanced Fields for STUDENT (V2)
Includes all fields from V1 plus:
Next upcoming event the student is registered for (EventDTO)
Number of upcoming events student is registered for
Number of past events student was registered for
data.thisMonthRegistrations
Number of registrations created this month
{
"statusCode": 200,
"message": "Stats fetched",
"data": {
"myTotalRegistrations": 5,
"upcomingEventsCount": 3,
"pastEventsCount": 2,
"thisMonthRegistrations": 2,
"nextEvent": {
"eventID": 1,
"title": "Career Fair",
"eventDate": "2024-04-15",
"startTime": "09:00:00",
"venue": "Main Hall",
"isRegistered": true
},
"activeEvents": [...]
},
"timestamp": "2024-03-07T10:30:00"
}
Implementation Details
Admin Proposal Counting Logic
From DashboardController.java:416-427:
private long countPendingProposalsForAdmin(User user) {
if (!(user instanceof Administrator admin) || admin.getDepartment() == null) {
return proposalRepository.countByStatus(ProposalStatus.PENDING_L1);
}
return switch (admin.getDepartment()) {
case YOUTH_UNION -> proposalRepository.countByStatusAndOrganizationType(
ProposalStatus.PENDING_L1, OrganizationType.YOUTH_UNION);
case STUDENT_ASSOCIATION -> proposalRepository.countByStatusAndOrganizationType(
ProposalStatus.PENDING_L1, OrganizationType.STUDENT_ASSOCIATION);
case FACULTY -> proposalRepository.countByStatus(ProposalStatus.PENDING_L2);
case RECTOR -> proposalRepository.countByStatus(ProposalStatus.PENDING_L3);
};
}
Admins only see proposal counts relevant to their department and approval level.
Next Event Calculation (Student)
From DashboardController.java:242-249:
Event nextEvent = registrations.stream()
.map(Registration::getEvent)
.filter(e -> e.getEventDate().isAfter(today) ||
(e.getEventDate().isEqual(today) &&
e.getStartTime().isAfter(now)))
.min(Comparator.comparing(Event::getEventDate)
.thenComparing(Event::getStartTime))
.orElse(null);
Finds the soonest future event based on both date and time.
Response Wrapper
All dashboard endpoints use the standard Response<T> wrapper:
{
statusCode: number; // HTTP status code
message: string; // Success message
data: T; // Dashboard data (varies by role)
timestamp: string; // ISO 8601 timestamp
errors?: string[]; // Error messages (if any)
}