a0bdd2b5b4
Replace all corruption variants with HTML entities across 226 view files: - 3-char UTF-8-as-Win1252 sequences (ae-corruption) - Standalone smart/curly quotes that break C# Razor expressions - Partially re-corrupted variants where the 3rd byte was normalised to ASCII tools/Fix-Encoding.ps1: re-runnable sweep; uses [char] code points so the script itself never contains a literal non-ASCII character; supports -DryRun .githooks/pre-commit: blocks commits containing the ae-corruption byte signature (xc3xa2xe2x82xac); git core.hooksPath = .githooks so the hook is repo-committed and active for all future work on this machine. Build clean; 225 unit tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
136 lines
6.2 KiB
Plaintext
136 lines
6.2 KiB
Plaintext
@using PowderCoating.Web.Controllers
|
|
@model AdminEmailPreviewModel
|
|
@{
|
|
ViewData["Title"] = "Preview Admin Email";
|
|
}
|
|
|
|
<div class="container-fluid py-4" style="max-width:1150px">
|
|
<div class="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-4">
|
|
<div>
|
|
<h3 class="mb-1"><i class="bi bi-eye me-2 text-primary"></i>Admin Email Wizard</h3>
|
|
<p class="text-muted mb-0">Step 3 of 3: preview one merged sample, then send sequentially.</p>
|
|
</div>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<span class="badge text-bg-success">@Model.EligibleCount ready to send</span>
|
|
@if (Model.SkippedCount > 0)
|
|
{
|
|
<span class="badge text-bg-warning">@Model.SkippedCount missing email</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-5">
|
|
<div class="card shadow-sm border-0 h-100">
|
|
<div class="card-header bg-transparent fw-semibold py-3">Sample Preview</div>
|
|
<div class="card-body">
|
|
<div class="small text-muted text-uppercase fw-semibold mb-1">Recipient Sample</div>
|
|
<div class="mb-3">
|
|
<div class="fw-semibold">@Model.SamplePreview.RecipientName</div>
|
|
<div class="text-muted">@Model.SamplePreview.RecipientEmail</div>
|
|
<div class="small text-muted">@Model.SamplePreview.CompanyName</div>
|
|
</div>
|
|
|
|
<div class="small text-muted text-uppercase fw-semibold mb-1">Rendered Subject</div>
|
|
<div class="fw-semibold mb-3">@Model.SamplePreview.RenderedSubject</div>
|
|
|
|
<div class="small text-muted text-uppercase fw-semibold mb-2">Rendered HTML Body</div>
|
|
<div class="border rounded-3 p-3 bg-light-subtle" style="min-height:320px">
|
|
@Html.Raw(Model.SamplePreview.RenderedHtmlBody)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-7">
|
|
<div class="card shadow-sm border-0 mb-4">
|
|
<div class="card-header bg-transparent fw-semibold py-3">Delivery Summary</div>
|
|
<div class="card-body">
|
|
<div class="alert alert-info alert-permanent mb-0">
|
|
The system will process each selected company one at a time.
|
|
The sample shown on the left uses the first available recipient after token replacement.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-transparent fw-semibold py-3">Selected Companies</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Company</th>
|
|
<th>Recipient</th>
|
|
<th>Company Admin</th>
|
|
<th>Ready</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var row in Model.SelectedCompanies)
|
|
{
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold">@row.CompanyName</div>
|
|
<div class="small text-muted">#@row.CompanyId</div>
|
|
</td>
|
|
<td>
|
|
<div>@row.RecipientName</div>
|
|
<div class="small text-muted">@(string.IsNullOrWhiteSpace(row.RecipientEmail) ? "No primary contact email configured" : row.RecipientEmail)</div>
|
|
</td>
|
|
<td>
|
|
<div>@(string.IsNullOrWhiteSpace(row.CompanyAdminName) ? "—" : row.CompanyAdminName)</div>
|
|
@if (!string.IsNullOrWhiteSpace(row.CompanyAdminEmail))
|
|
{
|
|
<div class="small text-muted">@row.CompanyAdminEmail</div>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (row.CanSend)
|
|
{
|
|
<span class="badge text-bg-success">Ready</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge text-bg-warning">@row.SkipReason</span>
|
|
}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" asp-action="Send" class="mt-4">
|
|
@Html.AntiForgeryToken()
|
|
<input type="hidden" asp-for="Subject" />
|
|
<input type="hidden" asp-for="BodyHtml" />
|
|
@foreach (var companyId in Model.CompanyIds ?? Array.Empty<int>())
|
|
{
|
|
<input type="hidden" name="CompanyIds" value="@companyId" />
|
|
}
|
|
|
|
<div class="d-flex flex-wrap justify-content-between gap-3">
|
|
<button type="submit"
|
|
formaction="@Url.Action("BackToSelectCompanies")"
|
|
class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-2"></i>Back to Companies
|
|
</button>
|
|
|
|
@if (Model.EligibleCount > 0)
|
|
{
|
|
<button type="submit" class="btn btn-primary"
|
|
onclick="return confirm('Send this message one company at a time to @Model.EligibleCount ready recipient(s)?');">
|
|
<i class="bi bi-send me-2"></i>Send Admin Email
|
|
</button>
|
|
}
|
|
else
|
|
{
|
|
<button type="button" class="btn btn-secondary" disabled>No deliverable recipients selected</button>
|
|
}
|
|
</div>
|
|
</form>
|
|
</div>
|