167 lines
5.9 KiB
C#
167 lines
5.9 KiB
C#
|
|
using Microsoft.AspNetCore.Authorization;
|
||
|
|
using Microsoft.AspNetCore.Mvc;
|
||
|
|
using Microsoft.EntityFrameworkCore;
|
||
|
|
using RacePlannerApi.Data;
|
||
|
|
using RacePlannerApi.DTOs;
|
||
|
|
using RacePlannerApi.Models;
|
||
|
|
|
||
|
|
namespace RacePlannerApi.Controllers;
|
||
|
|
|
||
|
|
[ApiController]
|
||
|
|
[Route("api/[controller]")]
|
||
|
|
[Authorize]
|
||
|
|
public class DashboardController : ControllerBase
|
||
|
|
{
|
||
|
|
private readonly RacePlannerDbContext _context;
|
||
|
|
|
||
|
|
public DashboardController(RacePlannerDbContext context)
|
||
|
|
{
|
||
|
|
_context = context;
|
||
|
|
}
|
||
|
|
|
||
|
|
[HttpGet("organizer")]
|
||
|
|
[Authorize(Roles = "Organizer")]
|
||
|
|
public async Task<ActionResult<OrganizerDashboardDto>> GetOrganizerDashboard()
|
||
|
|
{
|
||
|
|
var userId = GetCurrentUserId();
|
||
|
|
if (userId == null)
|
||
|
|
{
|
||
|
|
return Unauthorized();
|
||
|
|
}
|
||
|
|
|
||
|
|
var events = await _context.Events
|
||
|
|
.Include(e => e.Registrations)
|
||
|
|
.ThenInclude(r => r.Payments)
|
||
|
|
.Where(e => e.OrganizerId == userId.Value)
|
||
|
|
.ToListAsync();
|
||
|
|
|
||
|
|
var totalEvents = events.Count;
|
||
|
|
var publishedEvents = events.Count(e => e.Status == EventStatus.Published);
|
||
|
|
var draftEvents = events.Count(e => e.Status == EventStatus.Draft);
|
||
|
|
|
||
|
|
var allRegistrations = events.SelectMany(e => e.Registrations).ToList();
|
||
|
|
var totalRegistrations = allRegistrations.Count;
|
||
|
|
var pendingRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Pending);
|
||
|
|
var confirmedRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Confirmed);
|
||
|
|
var cancelledRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Cancelled);
|
||
|
|
|
||
|
|
var totalRevenue = allRegistrations
|
||
|
|
.SelectMany(r => r.Payments)
|
||
|
|
.Sum(p => p.Amount);
|
||
|
|
|
||
|
|
var upcomingEvents = events
|
||
|
|
.Where(e => e.EventDate >= DateTime.UtcNow && e.EventDate <= DateTime.UtcNow.AddDays(30))
|
||
|
|
.OrderBy(e => e.EventDate)
|
||
|
|
.Take(5)
|
||
|
|
.Select(e => new EventSummaryDto
|
||
|
|
{
|
||
|
|
Id = e.Id,
|
||
|
|
Name = e.Name,
|
||
|
|
EventDate = e.EventDate,
|
||
|
|
Location = e.Location,
|
||
|
|
RegistrationCount = e.Registrations.Count(r => r.Status != RegistrationStatus.Cancelled),
|
||
|
|
MaxParticipants = e.MaxParticipants
|
||
|
|
})
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
var eventsNearCapacity = events
|
||
|
|
.Where(e => e.MaxParticipants.HasValue && e.Status == EventStatus.Published)
|
||
|
|
.Select(e => new EventCapacityDto
|
||
|
|
{
|
||
|
|
Id = e.Id,
|
||
|
|
Name = e.Name,
|
||
|
|
EventDate = e.EventDate,
|
||
|
|
RegistrationCount = e.Registrations.Count(r => r.Status != RegistrationStatus.Cancelled),
|
||
|
|
MaxParticipants = e.MaxParticipants
|
||
|
|
})
|
||
|
|
.Where(e => e.CapacityPercentage >= 80)
|
||
|
|
.OrderByDescending(e => e.CapacityPercentage)
|
||
|
|
.Take(5)
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
var dashboard = new OrganizerDashboardDto
|
||
|
|
{
|
||
|
|
TotalEvents = totalEvents,
|
||
|
|
PublishedEvents = publishedEvents,
|
||
|
|
DraftEvents = draftEvents,
|
||
|
|
TotalRegistrations = totalRegistrations,
|
||
|
|
PendingRegistrations = pendingRegistrations,
|
||
|
|
ConfirmedRegistrations = confirmedRegistrations,
|
||
|
|
CancelledRegistrations = cancelledRegistrations,
|
||
|
|
TotalRevenue = totalRevenue,
|
||
|
|
UpcomingEvents = upcomingEvents,
|
||
|
|
EventsNearCapacity = eventsNearCapacity
|
||
|
|
};
|
||
|
|
|
||
|
|
return Ok(dashboard);
|
||
|
|
}
|
||
|
|
|
||
|
|
[HttpGet("participant")]
|
||
|
|
public async Task<ActionResult<ParticipantDashboardDto>> GetParticipantDashboard()
|
||
|
|
{
|
||
|
|
var userId = GetCurrentUserId();
|
||
|
|
if (userId == null)
|
||
|
|
{
|
||
|
|
return Unauthorized();
|
||
|
|
}
|
||
|
|
|
||
|
|
var registrations = await _context.Registrations
|
||
|
|
.Include(r => r.Event)
|
||
|
|
.Where(r => r.ParticipantId == userId.Value)
|
||
|
|
.ToListAsync();
|
||
|
|
|
||
|
|
var totalRegistrations = registrations.Count;
|
||
|
|
var upcomingEvents = registrations.Count(r => r.Event.EventDate >= DateTime.UtcNow && r.Status != RegistrationStatus.Cancelled);
|
||
|
|
var completedEvents = registrations.Count(r => r.Event.EventDate < DateTime.UtcNow && r.Status == RegistrationStatus.Completed);
|
||
|
|
var cancelledRegistrations = registrations.Count(r => r.Status == RegistrationStatus.Cancelled);
|
||
|
|
|
||
|
|
var registrationSummaries = registrations
|
||
|
|
.OrderByDescending(r => r.Event.EventDate)
|
||
|
|
.Take(10)
|
||
|
|
.Select(r => new RegistrationSummaryDto
|
||
|
|
{
|
||
|
|
Id = r.Id,
|
||
|
|
EventId = r.EventId,
|
||
|
|
EventName = r.Event.Name,
|
||
|
|
EventDate = r.Event.EventDate,
|
||
|
|
Status = r.Status.ToString(),
|
||
|
|
RegisteredAt = r.CreatedAt
|
||
|
|
})
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
var upcomingEventList = registrations
|
||
|
|
.Where(r => r.Event.EventDate >= DateTime.UtcNow && r.Status != RegistrationStatus.Cancelled)
|
||
|
|
.OrderBy(r => r.Event.EventDate)
|
||
|
|
.Take(5)
|
||
|
|
.Select(r => new UpcomingEventDto
|
||
|
|
{
|
||
|
|
Id = r.EventId,
|
||
|
|
Name = r.Event.Name,
|
||
|
|
EventDate = r.Event.EventDate,
|
||
|
|
Location = r.Event.Location
|
||
|
|
})
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
var dashboard = new ParticipantDashboardDto
|
||
|
|
{
|
||
|
|
TotalRegistrations = totalRegistrations,
|
||
|
|
UpcomingEvents = upcomingEvents,
|
||
|
|
CompletedEvents = completedEvents,
|
||
|
|
CancelledRegistrations = cancelledRegistrations,
|
||
|
|
MyRegistrations = registrationSummaries,
|
||
|
|
UpcomingEventList = upcomingEventList
|
||
|
|
};
|
||
|
|
|
||
|
|
return Ok(dashboard);
|
||
|
|
}
|
||
|
|
|
||
|
|
private Guid? GetCurrentUserId()
|
||
|
|
{
|
||
|
|
var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
|
||
|
|
if (Guid.TryParse(userIdClaim, out var userId))
|
||
|
|
{
|
||
|
|
return userId;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|