Files
hrynco-notification-service/HrynCo.NotificationService.Web/Views/AdminChannels/Edit.cshtml
T
Anatolii Grynchuk 7587e7fd17 fix: move test modal to view body, wire button via addEventListener
Razor section forwarding across nested layouts is unreliable.
Modal div and script are now directly in Edit.cshtml body (not in
any section) so they are always in the DOM when the page renders.
Button uses addEventListener instead of inline onclick to decouple
from layout rendering order.

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:43:25 +03:00

201 lines
9.0 KiB
Plaintext

@using HrynCo.NotificationService.DAL.Abstract.Providers
@using HrynCo.NotificationService.Web.Controllers.Admin.ViewModels
@model EmailChannelEditViewModel
@{
Layout = "~/Views/Shared/_EditorLayout.cshtml";
ViewData["Title"] = Model.PageTitle;
ViewData["EditorTitle"] = Model.PageTitle;
}
<form id="channelForm" asp-action="Save" asp-controller="AdminChannels" method="post">
@Html.AntiForgeryToken()
<input asp-for="Id" type="hidden" />
@if (!ViewData.ModelState.IsValid)
{
<div class="alert alert-danger mb-3">
@foreach (var error in ViewData.ModelState.Values.SelectMany(v => v.Errors))
{
<div>@error.ErrorMessage</div>
}
</div>
}
@* Channel Settings section *@
<div class="form-section-title"><i class="bi bi-sliders me-1"></i> Channel Settings</div>
<div class="mb-4">
<label asp-for="ServiceName" class="form-label fw-semibold">Service Name</label>
<input asp-for="ServiceName" class="form-control" readonly="@(!Model.IsNew)" />
<span asp-validation-for="ServiceName" class="text-danger small"></span>
</div>
<div class="row mb-4">
<div class="col-md-4">
<label asp-for="Priority" class="form-label fw-semibold">Priority</label>
<input asp-for="Priority" class="form-control" type="number" min="1" />
<span asp-validation-for="Priority" class="text-danger small"></span>
</div>
<div class="col-md-4">
<label asp-for="EmailChannelType" class="form-label fw-semibold">Channel Type</label>
<select asp-for="EmailChannelType" class="form-select"
asp-items="Html.GetEnumSelectList<EmailChannelType>()">
</select>
</div>
<div class="col-md-4 d-flex align-items-end">
<div class="form-check mb-2">
<input asp-for="IsActive" class="form-check-input" type="checkbox" />
<label asp-for="IsActive" class="form-check-label fw-semibold">Active</label>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<label asp-for="DailyLimit" class="form-label fw-semibold">Daily Limit</label>
<input asp-for="DailyLimit" class="form-control" type="number" min="0" placeholder="Unlimited" />
<span asp-validation-for="DailyLimit" class="text-danger small"></span>
</div>
<div class="col-md-4">
<label asp-for="MonthlyLimit" class="form-label fw-semibold">Monthly Limit</label>
<input asp-for="MonthlyLimit" class="form-control" type="number" min="0" placeholder="Unlimited" />
<span asp-validation-for="MonthlyLimit" class="text-danger small"></span>
</div>
<div class="col-md-4">
<label asp-for="WarnThresholdPercent" class="form-label fw-semibold">Warn Threshold (%)</label>
<input asp-for="WarnThresholdPercent" class="form-control" type="number" min="1" max="100" />
<span asp-validation-for="WarnThresholdPercent" class="text-danger small"></span>
</div>
</div>
@* SMTP Settings section *@
<div class="form-section-title mt-4"><i class="bi bi-envelope-at me-1"></i> SMTP Settings</div>
<div class="row mb-4">
<div class="col-md-9">
<label asp-for="Host" class="form-label fw-semibold">Host</label>
<input asp-for="Host" class="form-control" placeholder="smtp.example.com" />
<span asp-validation-for="Host" class="text-danger small"></span>
</div>
<div class="col-md-3">
<label asp-for="Port" class="form-label fw-semibold">Port</label>
<input asp-for="Port" class="form-control" type="number" min="1" max="65535" />
<span asp-validation-for="Port" class="text-danger small"></span>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<label asp-for="Username" class="form-label fw-semibold">Username</label>
<input asp-for="Username" class="form-control" autocomplete="new-password" />
<span asp-validation-for="Username" class="text-danger small"></span>
</div>
<div class="col-md-6">
<label asp-for="Password" class="form-label fw-semibold">Password</label>
<input asp-for="Password" class="form-control" type="password" autocomplete="new-password" />
<span asp-validation-for="Password" class="text-danger small"></span>
</div>
</div>
<div class="mb-4">
<div class="form-check">
<input asp-for="UseSsl" class="form-check-input" type="checkbox" />
<label asp-for="UseSsl" class="form-check-label fw-semibold">Use SSL/TLS</label>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<label asp-for="FromEmail" class="form-label fw-semibold">From Email</label>
<input asp-for="FromEmail" class="form-control" type="email" placeholder="noreply@example.com" />
<span asp-validation-for="FromEmail" class="text-danger small"></span>
</div>
<div class="col-md-6">
<label asp-for="FromName" class="form-label fw-semibold">From Name</label>
<input asp-for="FromName" class="form-control" placeholder="My Service" />
<span asp-validation-for="FromName" class="text-danger small"></span>
</div>
</div>
@section FormActions {
<button type="submit" form="channelForm" class="btn btn-primary">
<i class="bi bi-floppy me-1"></i> Save
</button>
@if (!Model.IsNew)
{
<button type="button" class="btn btn-success" id="testModalBtn">
<i class="bi bi-send me-1"></i> Test
</button>
}
<a href="/admin/channels" class="btn btn-secondary">
<i class="bi bi-x-lg me-1"></i> Cancel
</a>
}
</form>
@if (!Model.IsNew)
{
<div class="modal fade" id="testModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="bi bi-send me-2"></i>Send Test Email</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<label for="testToEmail" class="form-label fw-semibold">Recipient Email</label>
<input type="email" id="testToEmail" class="form-control" placeholder="you@example.com" />
<div id="testResult" class="mt-3" style="display:none"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" id="testSendBtn" onclick="sendTestEmail('@Model.Id')">
<i class="bi bi-send me-1"></i> Send
</button>
</div>
</div>
</div>
</div>
<script>
document.getElementById('testModalBtn').addEventListener('click', function () {
bootstrap.Modal.getOrCreateInstance(document.getElementById('testModal')).show();
});
async function sendTestEmail(channelId) {
const toEmail = document.getElementById('testToEmail').value.trim();
const resultDiv = document.getElementById('testResult');
const sendBtn = document.getElementById('testSendBtn');
if (!toEmail) {
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<div class="alert alert-warning mb-0">Please enter a recipient email.</div>';
return;
}
sendBtn.disabled = true;
sendBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Sending…';
resultDiv.style.display = 'none';
try {
const resp = await fetch(`/admin/channels/${channelId}/test`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ toEmail })
});
const data = await resp.json();
resultDiv.style.display = 'block';
resultDiv.innerHTML = data.success
? `<div class="alert alert-success mb-0"><i class="bi bi-check-circle me-1"></i>${data.message}</div>`
: `<div class="alert alert-danger mb-0"><i class="bi bi-x-circle me-1"></i>${data.message}</div>`;
} catch (e) {
resultDiv.style.display = 'block';
resultDiv.innerHTML = `<div class="alert alert-danger mb-0">Request failed: ${e.message}</div>`;
} finally {
sendBtn.disabled = false;
sendBtn.innerHTML = '<i class="bi bi-send me-1"></i> Send';
}
}
</script>
}