Files
raceplanner/backend/Controllers/EventsController.cs
T
2026-04-03 21:06:38 +02:00

242 lines
7.0 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 EventsController : ControllerBase
{
private readonly RacePlannerDbContext _context;
public EventsController(RacePlannerDbContext context)
{
_context = context;
}
[HttpPost]
[Authorize(Roles = "Organizer")]
public async Task<ActionResult<EventDto>> CreateEvent(CreateEventRequest request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return Unauthorized();
}
var eventEntity = new Event
{
Name = request.Name,
Description = request.Description,
EventDate = request.EventDate,
Location = request.Location,
Category = request.Category,
Tags = request.Tags ?? new List<string>(),
MaxParticipants = request.MaxParticipants,
OrganizerId = userId.Value,
Status = EventStatus.Draft
};
_context.Events.Add(eventEntity);
await _context.SaveChangesAsync();
// Load organizer for response
await _context.Entry(eventEntity).Reference(e => e.Organizer).LoadAsync();
return CreatedAtAction(
nameof(GetEvent),
new { id = eventEntity.Id },
MapToEventDto(eventEntity));
}
[HttpGet]
[AllowAnonymous]
public async Task<ActionResult<IEnumerable<EventDto>>> GetEvents(
[FromQuery] EventFilterRequest? filter = null)
{
var query = _context.Events
.Include(e => e.Organizer)
.Include(e => e.Registrations)
.AsQueryable();
// Apply filters
if (filter?.Category != null)
{
query = query.Where(e => e.Category == filter.Category);
}
if (filter?.Tags != null && filter.Tags.Any())
{
query = query.Where(e => e.Tags.Any(t => filter.Tags.Contains(t)));
}
if (filter?.FromDate != null)
{
query = query.Where(e => e.EventDate >= filter.FromDate);
}
if (filter?.ToDate != null)
{
query = query.Where(e => e.EventDate <= filter.ToDate);
}
if (filter?.Status != null && Enum.TryParse<EventStatus>(filter.Status, out var status))
{
query = query.Where(e => e.Status == status);
}
if (filter?.OrganizerId != null)
{
query = query.Where(e => e.OrganizerId == filter.OrganizerId);
}
// Default to showing published events only for anonymous users
if (!User.Identity?.IsAuthenticated ?? true)
{
query = query.Where(e => e.Status == EventStatus.Published);
}
var events = await query
.OrderBy(e => e.EventDate)
.ToListAsync();
return Ok(events.Select(MapToEventDto));
}
[HttpGet("{id}")]
[AllowAnonymous]
public async Task<ActionResult<EventDto>> GetEvent(Guid id)
{
var eventEntity = await _context.Events
.Include(e => e.Organizer)
.Include(e => e.Registrations)
.FirstOrDefaultAsync(e => e.Id == id);
if (eventEntity == null)
{
return NotFound();
}
// Draft events only visible to organizers
if (eventEntity.Status == EventStatus.Draft)
{
var userId = GetCurrentUserId();
if (userId == null || eventEntity.OrganizerId != userId)
{
return NotFound();
}
}
return Ok(MapToEventDto(eventEntity));
}
[HttpPut("{id}")]
[Authorize(Roles = "Organizer")]
public async Task<ActionResult<EventDto>> UpdateEvent(Guid id, UpdateEventRequest request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return Unauthorized();
}
var eventEntity = await _context.Events
.Include(e => e.Organizer)
.FirstOrDefaultAsync(e => e.Id == id);
if (eventEntity == null)
{
return NotFound();
}
// Only organizer can update their event
if (eventEntity.OrganizerId != userId)
{
return Forbid();
}
// Update fields
if (request.Name != null) eventEntity.Name = request.Name;
if (request.Description != null) eventEntity.Description = request.Description;
if (request.EventDate != null) eventEntity.EventDate = request.EventDate.Value;
if (request.Location != null) eventEntity.Location = request.Location;
if (request.Status != null) eventEntity.Status = request.Status.Value;
if (request.Category != null) eventEntity.Category = request.Category;
if (request.Tags != null) eventEntity.Tags = request.Tags;
if (request.MaxParticipants != null) eventEntity.MaxParticipants = request.MaxParticipants;
eventEntity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return Ok(MapToEventDto(eventEntity));
}
[HttpDelete("{id}")]
[Authorize(Roles = "Organizer")]
public async Task<IActionResult> DeleteEvent(Guid id)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return Unauthorized();
}
var eventEntity = await _context.Events.FindAsync(id);
if (eventEntity == null)
{
return NotFound();
}
if (eventEntity.OrganizerId != userId)
{
return Forbid();
}
_context.Events.Remove(eventEntity);
await _context.SaveChangesAsync();
return NoContent();
}
private Guid? GetCurrentUserId()
{
var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
if (Guid.TryParse(userIdClaim, out var userId))
{
return userId;
}
return null;
}
private static EventDto MapToEventDto(Event eventEntity)
{
return new EventDto
{
Id = eventEntity.Id,
Name = eventEntity.Name,
Description = eventEntity.Description,
EventDate = eventEntity.EventDate,
Location = eventEntity.Location,
Status = eventEntity.Status.ToString(),
Category = eventEntity.Category,
Tags = eventEntity.Tags,
MaxParticipants = eventEntity.MaxParticipants,
CurrentRegistrations = eventEntity.Registrations?.Count ?? 0,
CreatedAt = eventEntity.CreatedAt,
UpdatedAt = eventEntity.UpdatedAt,
Organizer = new UserSummaryDto
{
Id = eventEntity.Organizer.Id,
Name = eventEntity.Organizer.Name,
Email = eventEntity.Organizer.Email
}
};
}
}