Add Events, Registrations, and Payments controllers with DTOs
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
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
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user