204 lines
7.3 KiB
C#
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);
|