Sistema de Notificaciones y Baja One-Click
This commit is contained in:
@@ -18,8 +18,28 @@ public class NotificationService : INotificationService
|
||||
_frontendUrl = config["AppSettings:FrontendUrl"]?.Split(',')[0].Trim() ?? "http://localhost:5173";
|
||||
}
|
||||
|
||||
private string GetEmailShell(string title, string content)
|
||||
// ─── Shell del correo ──────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Genera el HTML completo del correo con header, contenido y footer.
|
||||
/// Si se provee unsubscribeUrl, agrega el enlace de baja en el footer.
|
||||
/// </summary>
|
||||
private string GetEmailShell(string title, string content, string? unsubscribeUrl = null)
|
||||
{
|
||||
// Footer de baja: solo se muestra si el correo tiene categoría de preferencia
|
||||
var unsubscribeBlock = string.IsNullOrEmpty(unsubscribeUrl)
|
||||
? string.Empty
|
||||
: $@"
|
||||
<div style='margin-top: 18px; padding-top: 18px; border-top: 1px solid #1f2937;'>
|
||||
<p style='color: #4b5563; font-size: 11px; margin: 0; text-align: center;'>
|
||||
¿No querés recibir más este tipo de correos?
|
||||
<a href='{unsubscribeUrl}'
|
||||
style='color: #6b7280; text-decoration: underline; font-size: 11px;'>
|
||||
Darte de baja
|
||||
</a>
|
||||
</p>
|
||||
</div>";
|
||||
|
||||
return $@"
|
||||
<div style='background-color: #0a0c10; color: #e5e7eb; font-family: sans-serif; padding: 40px; line-height: 1.6;'>
|
||||
<div style='max-width: 600px; margin: 0 auto; background-color: #12141a; border: 1px solid #1f2937; border-radius: 24px; overflow: hidden; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);'>
|
||||
@@ -34,12 +54,20 @@ public class NotificationService : INotificationService
|
||||
</div>
|
||||
<div style='padding: 20px; border-top: 1px solid #1f2937; text-align: center; background-color: #0d0f14;'>
|
||||
<p style='color: #4b5563; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; margin: 0;'>Motores Argentinos - La Plata, Buenos Aires, Argentina</p>
|
||||
{unsubscribeBlock}
|
||||
</div>
|
||||
</div>
|
||||
</div>";
|
||||
}
|
||||
|
||||
public async Task SendChatNotificationEmailAsync(string toEmail, string fromUser, string message, int adId)
|
||||
// ─── Implementaciones ──────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Notificación de nuevo mensaje de chat. Categoría: mensajes.
|
||||
/// </summary>
|
||||
public async Task SendChatNotificationEmailAsync(
|
||||
string toEmail, string fromUser, string message, int adId,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Tienes un nuevo mensaje - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -53,10 +81,15 @@ public class NotificationService : INotificationService
|
||||
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>VER MENSAJES</a>
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Nuevo Mensaje", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Nuevo Mensaje", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
public async Task SendAdStatusChangedEmailAsync(string toEmail, string adTitle, string status, string? reason = null)
|
||||
/// <summary>
|
||||
/// Aviso de cambio de estado del aviso. Categoría: sistema.
|
||||
/// </summary>
|
||||
public async Task SendAdStatusChangedEmailAsync(
|
||||
string toEmail, string adTitle, string status, string? reason = null,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Estado de tu aviso - Motores Argentinos";
|
||||
string color = status.ToUpper() == "APROBADO" ? "#10b981" : "#ef4444";
|
||||
@@ -70,9 +103,12 @@ public class NotificationService : INotificationService
|
||||
{(string.IsNullOrEmpty(reason) ? "" : $"<p style='background: #1f2937; padding: 15px; border-radius: 8px; border-left: 4px solid #ef4444;'><strong>Motivo:</strong> {reason}</p>")}
|
||||
<p style='margin-top: 20px;'>Gracias por confiar en nosotros.</p>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Cambio de Estado", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Cambio de Estado", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alerta de seguridad crítica. SIN enlace de baja (siempre se envía).
|
||||
/// </summary>
|
||||
public async Task SendSecurityAlertEmailAsync(string toEmail, string actionDescription)
|
||||
{
|
||||
string subject = "Alerta de Seguridad - Motores Argentinos";
|
||||
@@ -85,10 +121,16 @@ public class NotificationService : INotificationService
|
||||
<p>Si no fuiste tú, te recomendamos cambiar tu contraseña inmediatamente y contactar a nuestro equipo de soporte.</p>
|
||||
<p style='margin-top: 20px;'>Atentamente,<br>Equipo de Seguridad.</p>";
|
||||
|
||||
// Sin unsubscribeUrl: los correos de seguridad no tienen baja
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Alerta de Seguridad", content));
|
||||
}
|
||||
|
||||
public async Task SendExpirationWarningEmailAsync(string toEmail, string userName, string adTitle, DateTime expirationDate)
|
||||
/// <summary>
|
||||
/// Aviso de próximo vencimiento. Categoría: sistema.
|
||||
/// </summary>
|
||||
public async Task SendExpirationWarningEmailAsync(
|
||||
string toEmail, string userName, string adTitle, DateTime expirationDate,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Tu aviso está por vencer - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -99,10 +141,15 @@ public class NotificationService : INotificationService
|
||||
<a href='{_frontendUrl}/mis-avisos' style='background-color: #f59e0b; color: #000; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>RENOVAR AVISO</a>
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso por Vencer", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso por Vencer", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
public async Task SendAdExpiredEmailAsync(string toEmail, string userName, string adTitle)
|
||||
/// <summary>
|
||||
/// Aviso de vencimiento consumado. Categoría: sistema.
|
||||
/// </summary>
|
||||
public async Task SendAdExpiredEmailAsync(
|
||||
string toEmail, string userName, string adTitle,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Tu aviso ha finalizado - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -113,10 +160,15 @@ public class NotificationService : INotificationService
|
||||
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>REPUBLICAR AHORA</a>
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso Finalizado", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso Finalizado", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
public async Task SendWeeklyPerformanceEmailAsync(string toEmail, string userName, string adTitle, int views, int favorites)
|
||||
/// <summary>
|
||||
/// Resumen semanal de rendimiento del aviso. Categoría: rendimiento.
|
||||
/// </summary>
|
||||
public async Task SendWeeklyPerformanceEmailAsync(
|
||||
string toEmail, string userName, string adTitle, int views, int favorites,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Resumen semanal de tu aviso - Motores Argentinos";
|
||||
|
||||
@@ -158,10 +210,15 @@ public class NotificationService : INotificationService
|
||||
<![endif]-->
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Rendimiento Semanal", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Rendimiento Semanal", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
public async Task SendPaymentReminderEmailAsync(string toEmail, string userName, string adTitle, string link)
|
||||
/// <summary>
|
||||
/// Recordatorio de carrito abandonado. Categoría: marketing.
|
||||
/// </summary>
|
||||
public async Task SendPaymentReminderEmailAsync(
|
||||
string toEmail, string userName, string adTitle, string link,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Finaliza la publicación de tu aviso - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -172,10 +229,14 @@ public class NotificationService : INotificationService
|
||||
<a href='{link}' style='background-color: #10b981; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>FINALIZAR PUBLICACIÓN</a>
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Acción Requerida", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Acción Requerida", content, unsubscribeUrl));
|
||||
}
|
||||
|
||||
public async Task SendPaymentReceiptEmailAsync(string toEmail, string userName, string adTitle, decimal amount, string operationCode)
|
||||
/// <summary>
|
||||
/// Recibo de pago transaccional. SIN enlace de baja (siempre se envía).
|
||||
/// </summary>
|
||||
public async Task SendPaymentReceiptEmailAsync(
|
||||
string toEmail, string userName, string adTitle, decimal amount, string operationCode)
|
||||
{
|
||||
string subject = "Comprobante de Pago - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -191,10 +252,16 @@ public class NotificationService : INotificationService
|
||||
</div>
|
||||
<p>Tu aviso ha pasado a la etapa de moderación y será activado a la brevedad.</p>";
|
||||
|
||||
// Sin unsubscribeUrl: los comprobantes de pago son transaccionales obligatorios
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Recibo de Pago", content));
|
||||
}
|
||||
|
||||
public async Task SendUnreadMessagesReminderEmailAsync(string toEmail, string userName, int unreadCount)
|
||||
/// <summary>
|
||||
/// Recordatorio de mensajes sin leer. Categoría: mensajes.
|
||||
/// </summary>
|
||||
public async Task SendUnreadMessagesReminderEmailAsync(
|
||||
string toEmail, string userName, int unreadCount,
|
||||
string? unsubscribeUrl = null)
|
||||
{
|
||||
string subject = "Tienes mensajes sin leer - Motores Argentinos";
|
||||
string content = $@"
|
||||
@@ -205,6 +272,6 @@ public class NotificationService : INotificationService
|
||||
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>IR A MIS MENSAJES</a>
|
||||
</div>";
|
||||
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Mensajes Pendientes", content));
|
||||
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Mensajes Pendientes", content, unsubscribeUrl));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user