Files
CalendarReminder/CalendarReminder.Api/Controllers/RemindersController.cs
T
2026-06-05 21:39:38 +02:00

204 lines
7.3 KiB
C#

using CalendarReminder.Api.Data;
using CalendarReminder.Api.Services;
using CalendarReminder.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
namespace CalendarReminder.Api.Controllers;
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class RemindersController : ControllerBase
{
private readonly AppDbContext _db;
private readonly EmailService _email;
public RemindersController(AppDbContext db, EmailService email)
{
_db = db;
_email = email;
}
private int UserId => int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
// GET api/reminders — moje + zdieľané so mnou
[HttpGet]
public async Task<IActionResult> GetAll()
{
var myId = UserId;
var reminders = await _db.Reminders
.Include(r => r.User)
.Include(r => r.Shares).ThenInclude(s => s.SharedWithUser)
.Where(r => r.UserId == myId || r.Shares.Any(s => s.SharedWithUserId == myId))
.OrderBy(r => r.ReminderDate)
.Select(r => new
{
r.Id, r.Title, r.Description, r.ReminderDate,
r.IsCompleted, r.NotificationSent, r.UserId, r.CreatedAt,
Owner = r.User!.Username,
IsOwner = r.UserId == myId,
SharedWith = r.Shares.Select(s => new { s.SharedWithUser!.Id, s.SharedWithUser.Username })
})
.ToListAsync();
return Ok(reminders);
}
// GET api/reminders/5
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
var myId = UserId;
var r = await _db.Reminders
.Include(r => r.Shares)
.FirstOrDefaultAsync(r => r.Id == id &&
(r.UserId == myId || r.Shares.Any(s => s.SharedWithUserId == myId)));
return r is null ? NotFound() : Ok(r);
}
// POST api/reminders
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateReminderRequest req)
{
var reminder = new Reminder
{
Title = req.Title,
Description = req.Description,
ReminderDate = req.ReminderDate,
IsCompleted = false,
NotificationSent = false,
UserId = UserId,
CreatedAt = DateTime.UtcNow
};
_db.Reminders.Add(reminder);
await _db.SaveChangesAsync();
// Zdieľaj s vybranými používateľmi
foreach (var uid in req.ShareWithUserIds ?? [])
{
_db.ReminderShares.Add(new ReminderShare { ReminderId = reminder.Id, SharedWithUserId = uid });
}
if (req.ShareWithUserIds?.Count > 0)
await _db.SaveChangesAsync();
return CreatedAtAction(nameof(GetById), new { id = reminder.Id }, reminder);
}
// PUT api/reminders/5
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, [FromBody] UpdateReminderRequest req)
{
var reminder = await _db.Reminders
.Include(r => r.Shares)
.FirstOrDefaultAsync(r => r.Id == id && r.UserId == UserId);
if (reminder is null) return NotFound();
bool dateChanged = reminder.ReminderDate != req.ReminderDate;
reminder.Title = req.Title;
reminder.Description = req.Description;
reminder.ReminderDate = req.ReminderDate;
reminder.IsCompleted = req.IsCompleted;
if (dateChanged) reminder.NotificationSent = false;
// Aktualizuj zdieľanie
_db.ReminderShares.RemoveRange(reminder.Shares);
foreach (var uid in req.ShareWithUserIds ?? [])
_db.ReminderShares.Add(new ReminderShare { ReminderId = id, SharedWithUserId = uid });
await _db.SaveChangesAsync();
return Ok(reminder);
}
// DELETE api/reminders/5
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var reminder = await _db.Reminders
.FirstOrDefaultAsync(r => r.Id == id && r.UserId == UserId);
if (reminder is null) return NotFound();
_db.Reminders.Remove(reminder);
await _db.SaveChangesAsync();
return NoContent();
}
// POST api/reminders/5/send-email
[HttpPost("{id}/send-email")]
public async Task<IActionResult> SendEmail(int id)
{
var myId = UserId;
var reminder = await _db.Reminders
.Include(r => r.User)
.Include(r => r.Shares).ThenInclude(s => s.SharedWithUser)
.FirstOrDefaultAsync(r => r.Id == id && r.UserId == myId);
if (reminder is null) return NotFound();
if (!reminder.Shares.Any()) return BadRequest("Pripomienka nie je zdieľaná so žiadnym používateľom.");
var date = reminder.ReminderDate.ToLocalTime();
var dateStr = date.ToString("dd.MM.yyyy");
var timeStr = date.ToString("HH:mm");
var body = $"""
<div style="font-family:Segoe UI,sans-serif;max-width:520px;margin:auto;background:#161b22;color:#e1e4e8;border-radius:10px;overflow:hidden">
<div style="background:#1f6feb;padding:1.2rem 1.5rem">
<h2 style="margin:0;color:#fff;font-size:1.1rem">📅 Calendar Reminder</h2>
</div>
<div style="padding:1.5rem">
<h3 style="margin:0 0 1rem;color:#58a6ff;font-size:1.2rem">{reminder.Title}</h3>
<table style="width:100%;border-collapse:collapse">
<tr>
<td style="padding:0.4rem 0;color:#8b949e;width:80px">Dátum</td>
<td style="padding:0.4rem 0;font-weight:600">{dateStr}</td>
</tr>
<tr>
<td style="padding:0.4rem 0;color:#8b949e">Čas</td>
<td style="padding:0.4rem 0;font-weight:600">{timeStr}</td>
</tr>
{(reminder.Description != null ? $"""
<tr>
<td style="padding:0.4rem 0;color:#8b949e;vertical-align:top">Popis</td>
<td style="padding:0.4rem 0">{reminder.Description}</td>
</tr>
""" : "")}
<tr>
<td style="padding:0.4rem 0;color:#8b949e">Od</td>
<td style="padding:0.4rem 0">{reminder.User!.Username}</td>
</tr>
</table>
</div>
<div style="padding:0.75rem 1.5rem;border-top:1px solid #30363d;font-size:0.78rem;color:#6e7681">
Calendar Reminder automatická správa
</div>
</div>
""";
var tasks = reminder.Shares
.Where(s => s.SharedWithUser != null)
.Select(s => _email.SendAsync(
s.SharedWithUser!.Email,
s.SharedWithUser.Username,
$"📅 Pripomienka: {reminder.Title} — {dateStr} {timeStr}",
body));
await Task.WhenAll(tasks);
return Ok(new { sent = reminder.Shares.Count });
}
}
public record CreateReminderRequest(
string Title,
string? Description,
DateTime ReminderDate,
List<int>? ShareWithUserIds);
public record UpdateReminderRequest(
string Title,
string? Description,
DateTime ReminderDate,
bool IsCompleted,
List<int>? ShareWithUserIds);