using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using ROLAC.API.DTOs.Giving; using ROLAC.API.Hubs; using ROLAC.API.Services; namespace ROLAC.API.Controllers; /// /// Anonymous endpoints powering the mobile Sunday offering-entry page. The page /// has no login yet, so it cannot reach the auth-gated members/categories/ /// offering-sessions APIs — these expose just what it needs (active categories, /// a name-only member typeahead, and append-one-line). /// [ApiController] [Route("api/offering-entry")] [AllowAnonymous] public class OfferingEntryController : ControllerBase { private readonly IOfferingSessionService _sessions; private readonly IGivingCategoryService _categories; private readonly IHubContext _hub; public OfferingEntryController( IOfferingSessionService sessions, IGivingCategoryService categories, IHubContext hub) { _sessions = sessions; _categories = categories; _hub = hub; } // Seed the page in one round-trip: active categories + today's session state. [HttpGet("bootstrap")] public async Task Bootstrap([FromQuery] DateOnly date) => Ok(new OfferingEntryBootstrapDto { SessionDate = date.ToString("yyyy-MM-dd"), Categories = await _categories.GetAllAsync(false), Summary = await _sessions.GetEntrySummaryAsync(date), }); // Name-only member suggestions for the giver typeahead. [HttpGet("members")] public async Task SearchMembers([FromQuery] string? search, [FromQuery] int take = 10) => Ok(await _sessions.SearchMembersForEntryAsync(search, Math.Clamp(take, 1, 25))); // Append one offering line to the date's session (find-or-create), then // broadcast it to everyone viewing that date. [HttpPost("lines")] public async Task AppendLine([FromBody] AppendOfferingLineRequest request) { var result = await _sessions.AppendLineAsync(request.Date, request.Line); await _hub.Clients.Group(result.SessionDate).SendAsync("LineAdded", result); return Ok(result); } }