Initial commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
@page
|
||||
@model ListmonkIntegration.Pages.Campaigns.IndexModel
|
||||
@{
|
||||
ViewData["Title"] = "Управление рассылками";
|
||||
}
|
||||
|
||||
<h1> Управление рассылками</h1>
|
||||
<hr />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="mb-4">
|
||||
<a asp-page="/Templates/Create" class="btn btn-primary btn-lg">
|
||||
Создать шаблон письма
|
||||
</a>
|
||||
<a asp-page="/Campaigns/Send" class="btn btn-warning btn-lg">
|
||||
Отправить письмо
|
||||
</a>
|
||||
<a asp-page="/Subscribers/Upload" class="btn btn-success btn-lg">
|
||||
Загрузить подписчиков
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h5>Функционал:</h5>
|
||||
<ul>
|
||||
<li>Загрузка Excel файлов с подписчиками</li>
|
||||
<li>Создание шаблонов писем</li>
|
||||
<li>Просмотр существующих кампаний</li>
|
||||
<li>Запуск рассылок</li>
|
||||
<li>Просмотр статистики</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a asp-page="/Index" class="btn btn-secondary">← На главную</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (TempData["SuccessMessage"] != null)
|
||||
{
|
||||
<div class="alert alert-success mt-3">
|
||||
@TempData["SuccessMessage"]
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace ListmonkIntegration.Pages.Campaigns
|
||||
{
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
@page
|
||||
@model ListmonkIntegration.Pages.Campaigns.SendModel
|
||||
@{
|
||||
ViewData["Title"] = "Отправка письма";
|
||||
}
|
||||
|
||||
<h1>Отправка письма</h1>
|
||||
<hr />
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
|
||||
{
|
||||
<div class="alert alert-danger">@Model.ErrorMessage</div>
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.SuccessMessage))
|
||||
{
|
||||
<div class="alert alert-success">@Model.SuccessMessage</div>
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Название кампании</label>
|
||||
<input type="text" asp-for="CampaignName" class="form-control" required placeholder="Например: Рассылка 08.07.2026" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Выберите шаблон письма</label>
|
||||
<select asp-for="SelectedTemplateId" class="form-select" asp-items="Model.Templates" id="templateSelect" required>
|
||||
<option value="">-- Выберите шаблон --</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Список получателей</label>
|
||||
<select asp-for="SelectedListId" class="form-select" asp-items="Model.Lists" required>
|
||||
<option value="">-- Выберите список --</option>
|
||||
</select>
|
||||
<div class="form-text">
|
||||
<span id="selectedListInfo"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Предпросмотр шаблона</label>
|
||||
<div id="templatePreview" class="border p-3 bg-light" style="min-height: 200px;">
|
||||
<p class="text-muted">Выберите шаблон для предпросмотра</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Отправить</button>
|
||||
<a asp-page="/Campaigns/Index" class="btn btn-secondary">Отмена</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<script>
|
||||
document.getElementById('templateSelect').addEventListener('change', async function() {
|
||||
const templateId = this.value;
|
||||
const previewDiv = document.getElementById('templatePreview');
|
||||
|
||||
if (templateId) {
|
||||
previewDiv.innerHTML = '<p class="text-muted">Загрузка...</p>';
|
||||
try {
|
||||
const response = await fetch(`/api/templates/${templateId}/preview`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
previewDiv.innerHTML = data.body || '<p class="text-muted">Шаблон пуст</p>';
|
||||
} else {
|
||||
previewDiv.innerHTML = '<p class="text-danger">Ошибка загрузки шаблона</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
previewDiv.innerHTML = '<p class="text-danger">Ошибка загрузки шаблона</p>';
|
||||
}
|
||||
} else {
|
||||
previewDiv.innerHTML = '<p class="text-muted">Выберите шаблон для предпросмотра</p>';
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('select[asp-for="SelectedListId"]').addEventListener('change', function() {
|
||||
const select = this;
|
||||
const infoSpan = document.getElementById('selectedListInfo');
|
||||
const selectedOption = select.options[select.selectedIndex];
|
||||
if (selectedOption.value) {
|
||||
infoSpan.textContent = `Выбран список: ${selectedOption.text}`;
|
||||
} else {
|
||||
infoSpan.textContent = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using ListmonkIntegration.Services;
|
||||
|
||||
namespace ListmonkIntegration.Pages.Campaigns
|
||||
{
|
||||
public class SendModel : PageModel
|
||||
{
|
||||
private readonly IListmonkService _listmonkService;
|
||||
private readonly ILogger<SendModel> _logger;
|
||||
|
||||
[BindProperty]
|
||||
public string CampaignName { get; set; } = string.Empty;
|
||||
|
||||
[BindProperty]
|
||||
public int? SelectedTemplateId { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public int? SelectedListId { get; set; }
|
||||
|
||||
public SelectList Templates { get; set; } = new SelectList(Enumerable.Empty<SelectListItem>());
|
||||
public SelectList Lists { get; set; } = new SelectList(Enumerable.Empty<SelectListItem>());
|
||||
|
||||
public string? ErrorMessage { get; set; }
|
||||
public string? SuccessMessage { get; set; }
|
||||
|
||||
public SendModel(IListmonkService listmonkService, ILogger<SendModel> logger)
|
||||
{
|
||||
_listmonkService = listmonkService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task OnGetAsync()
|
||||
{
|
||||
await LoadDataAsync();
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostAsync()
|
||||
{
|
||||
if (!SelectedTemplateId.HasValue || !SelectedListId.HasValue || string.IsNullOrWhiteSpace(CampaignName))
|
||||
{
|
||||
ErrorMessage = "Çàïîëíèòå âñå ïîëÿ";
|
||||
await LoadDataAsync();
|
||||
return Page();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var templates = await _listmonkService.GetTemplatesAsync();
|
||||
var template = templates.FirstOrDefault(t => t.Id == SelectedTemplateId.Value);
|
||||
|
||||
if (template == null)
|
||||
{
|
||||
ErrorMessage = "Øàáëîí íå íàéäåí";
|
||||
await LoadDataAsync();
|
||||
return Page();
|
||||
}
|
||||
|
||||
var campaignId = await _listmonkService.CreateCampaignAsync(
|
||||
CampaignName,
|
||||
SelectedListId.Value,
|
||||
SelectedTemplateId.Value,
|
||||
template.Subject
|
||||
);
|
||||
|
||||
var started = await _listmonkService.StartCampaignAsync(campaignId);
|
||||
|
||||
if (started)
|
||||
{
|
||||
SuccessMessage = $"Êàìïàíèÿ \"{CampaignName}\" óñïåøíî ñîçäàíà è çàïóùåíà!";
|
||||
_logger.LogInformation($"Campaign {campaignId} started successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorMessage = $"Êàìïàíèÿ ñîçäàíà (ID: {campaignId}), íî íå óäàëîñü çàïóñòèòü";
|
||||
}
|
||||
|
||||
await LoadDataAsync();
|
||||
return Page();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error sending campaign");
|
||||
ErrorMessage = $"Îøèáêà: {ex.Message}";
|
||||
await LoadDataAsync();
|
||||
return Page();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var templates = await _listmonkService.GetTemplatesAsync();
|
||||
Templates = new SelectList(templates, "Id", "Name");
|
||||
|
||||
var lists = await _listmonkService.GetListsAsync();
|
||||
Lists = new SelectList(lists, "Id", "Name");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error loading data");
|
||||
ErrorMessage = $"Îøèáêà çàãðóçêè äàííûõ: {ex.Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user