feat: add MVC Razor admin UI for email templates

- GetAllEmailTemplatesQuery + handler (new GetAll use case)
- IEmailTemplateRepository.GetAllAsync + EF implementation
- AdminTemplatesController: Index, Create, Edit, Save, Delete
- EmailTemplateEditViewModel with IsNew/PageTitle helpers
- Views/_ViewStart, _ViewImports, Shared/_Layout (Bootstrap 5)
- Shared/_EditorLayout (chained layout for all edit screens)
- Views/AdminTemplates/Index (table with edit/delete actions)
- Views/AdminTemplates/Edit (card form, readonly composite key on edit)
- Program.cs: AddControllersWithViews, UseStaticFiles, MapDefaultControllerRoute

Ref: IT-634

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Anatolii Grynchuk
2026-05-02 02:06:08 +03:00
parent cec8f42ece
commit 2a0a5f737d
13 changed files with 432 additions and 1 deletions
@@ -0,0 +1,68 @@
@using HrynCo.NotificationService.DAL.Abstract.Templates
@model IReadOnlyList<EmailTemplate>
@{
ViewData["Title"] = "Email Templates";
}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0">📋 Email Templates</h2>
<a href="/admin/templates/create" class="btn btn-primary">+ Create New Template</a>
</div>
@if (!ViewData.ModelState.IsValid)
{
<div class="alert alert-danger">
@foreach (var error in ViewData.ModelState.Values.SelectMany(v => v.Errors))
{
<div>@error.ErrorMessage</div>
}
</div>
}
@if (Model is null || Model.Count == 0)
{
<div class="alert alert-info">No email templates found.</div>
}
else
{
<div class="card shadow-sm">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-dark">
<tr>
<th>Service Name</th>
<th>Key</th>
<th>Language</th>
<th>Subject</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var t in Model)
{
<tr>
<td>@t.ServiceName</td>
<td>@t.Key</td>
<td>@t.LanguageCode</td>
<td>@t.Subject</td>
<td class="text-end">
<a href="/admin/templates/@t.ServiceName/@t.Key/@t.LanguageCode"
class="btn btn-sm btn-outline-primary me-1">✏️ Edit</a>
<form method="post"
action="/admin/templates/@t.ServiceName/@t.Key/@t.LanguageCode/delete"
class="d-inline">
@Html.AntiForgeryToken()
<button type="submit"
class="btn btn-sm btn-outline-danger"
onclick="return confirm('Delete this template?')">
🗑️ Delete
</button>
</form>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}