Replace literal Unicode special chars with HTML entities across all 233 views

Sweeps em dashes, en dashes, multiplication signs, ellipses, and curly quotes
to their HTML entity equivalents (— – × … ‘ ’)
in all .cshtml files, skipping <script> blocks. Prevents encoding corruption
from AI tools and Windows encoding mismatches that caused recurring symbol bugs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 19:16:17 -04:00
parent cefdf3e35c
commit 3eda91f170
233 changed files with 0 additions and 72627 deletions
@@ -1,316 +0,0 @@
@model PowderCoating.Application.DTOs.Maintenance.MaintenanceRecordDto
@{
ViewData["Title"] = "Maintenance Details";
ViewData["PageIcon"] = "bi-wrench";
ViewData["PageHelpTitle"] = "Maintenance Details";
ViewData["PageHelpContent"] = "The status banner shows the current state and highlights Critical or High priority tasks. Recurring tasks display their frequency and series size. The Timeline on the right shows when this record was created, when service is scheduled, and when it was completed. Setting Status to Completed and saving updates the equipment&apos;s Next Scheduled date.";
}
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<p class="text-muted mb-0">@Model.MaintenanceType for @Model.EquipmentName</p>
</div>
<div class="d-flex gap-2">
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-warning">
<i class="bi bi-pencil me-2"></i>Edit
</a>
<a asp-action="Index" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-2"></i>Back to List
</a>
</div>
</div>
<!-- Status Banner -->
@{
var statusClass = Model.Status switch
{
"Scheduled" => "alert-primary",
"InProgress" => "alert-warning",
"Completed" => "alert-success",
"Overdue" => "alert-danger",
"Cancelled" => "alert-secondary",
_ => "alert-secondary"
};
var statusIcon = Model.Status switch
{
"Scheduled" => "bi-calendar-check",
"InProgress" => "bi-hourglass-split",
"Completed" => "bi-check-circle",
"Overdue" => "bi-exclamation-triangle",
"Cancelled" => "bi-x-circle",
_ => "bi-info-circle"
};
}
<div class="alert @statusClass alert-permanent d-flex align-items-center mb-4">
<i class="bi @statusIcon me-2" style="font-size: 1.5rem;"></i>
<div class="flex-grow-1">
<strong>Status:</strong> @Model.StatusDisplay
@if (Model.Priority == "Critical" || Model.Priority == "High")
{
<span class="ms-2">• Priority: <strong>@Model.PriorityDisplay</strong></span>
}
@if (Model.IsRecurring)
{
<span class="ms-3">
<span class="badge bg-info text-dark">
<i class="bi bi-arrow-repeat me-1"></i>Recurring — @Model.RecurrenceFrequency
</span>
@if (Model.RecurrenceEndDate.HasValue)
{
<small class="text-muted ms-1">until @Model.RecurrenceEndDate.Value.ToString("MMM dd, yyyy")</small>
}
@if (ViewBag.SeriesCount is int sc)
{
<small class="text-muted ms-1">(@sc occurrence@(sc == 1 ? "" : "s") in series)</small>
}
</span>
}
</div>
</div> <div class="row g-4">
<!-- Left Column -->
<div class="col-lg-8">
<!-- Maintenance Information -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-info-circle me-2 text-primary"></i>Maintenance Information
</h5>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<label class="text-muted small mb-1">Maintenance Type</label>
<p class="fw-semibold mb-0">@Model.MaintenanceType</p>
</div>
<div class="col-md-6">
<label class="text-muted small mb-1">Priority</label>
<p class="mb-0">
@{
var priorityClass = Model.Priority switch
{
"Critical" => "danger",
"High" => "warning",
"Normal" => "primary",
"Low" => "secondary",
_ => "secondary"
};
}
<span class="badge bg-@priorityClass bg-opacity-10 text-@priorityClass">
@Model.PriorityDisplay
</span>
</p>
</div>
<div class="col-md-6">
<label class="text-muted small mb-1">Scheduled Date</label>
<p class="mb-0">@Model.ScheduledDate.ToString("MMMM dd, yyyy")</p>
</div>
<div class="col-md-6">
<label class="text-muted small mb-1">Completed Date</label>
<p class="mb-0">
@(Model.CompletedDate.HasValue ? Model.CompletedDate.Value.ToString("MMMM dd, yyyy") : "Not completed")
</p>
</div>
<div class="col-md-12">
<label class="text-muted small mb-1">Performed By</label>
<p class="mb-0">@(Model.PerformedByName ?? "Not assigned")</p>
</div>
</div>
</div>
</div>
<!-- Equipment Details -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-tools me-2 text-primary"></i>Equipment
</h5>
</div>
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<p class="fw-semibold mb-1">@Model.EquipmentName</p>
<a asp-controller="Equipment" asp-action="Details" asp-route-id="@Model.EquipmentId" class="text-decoration-none">
<i class="bi bi-box-arrow-up-right me-1"></i>View Equipment Details
</a>
</div>
</div>
</div>
</div>
<!-- Work Description -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-file-text me-2 text-primary"></i>Description
</h5>
</div>
<div class="card-body">
<p class="mb-0">@Model.Description</p>
</div>
</div>
@if (!string.IsNullOrWhiteSpace(Model.WorkPerformed))
{
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-clipboard-check me-2 text-primary"></i>Work Performed
</h5>
</div>
<div class="card-body">
<p class="mb-0">@Model.WorkPerformed</p>
</div>
</div>
}
@if (!string.IsNullOrWhiteSpace(Model.PartsReplaced))
{
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-gear me-2 text-primary"></i>Parts Replaced
</h5>
</div>
<div class="card-body">
<p class="mb-0">@Model.PartsReplaced</p>
</div>
</div>
}
<!-- Costs Breakdown -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-currency-dollar me-2 text-primary"></i>Costs
</h5>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-4">
<label class="text-muted small mb-1">Labor Cost</label>
<p class="fw-semibold mb-0">@Model.LaborCost.ToString("C")</p>
</div>
<div class="col-md-4">
<label class="text-muted small mb-1">Parts Cost</label>
<p class="fw-semibold mb-0">@Model.PartsCost.ToString("C")</p>
</div>
<div class="col-md-4">
<label class="text-muted small mb-1">Total Cost</label>
<p class="fw-bold text-primary mb-0" style="font-size: 1.25rem;">@Model.TotalCost.ToString("C")</p>
</div>
<div class="col-md-12">
<label class="text-muted small mb-1">Downtime</label>
<p class="mb-0">@Model.DowntimeHours hours</p>
</div>
</div>
</div>
</div>
@if (!string.IsNullOrWhiteSpace(Model.Notes) || !string.IsNullOrWhiteSpace(Model.TechnicianNotes))
{
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-journal-text me-2 text-primary"></i>Notes
</h5>
</div>
<div class="card-body">
@if (!string.IsNullOrWhiteSpace(Model.Notes))
{
<div class="mb-3">
<label class="text-muted small mb-1">General Notes</label>
<p class="mb-0">@Model.Notes</p>
</div>
}
@if (!string.IsNullOrWhiteSpace(Model.TechnicianNotes))
{
<div>
<label class="text-muted small mb-1">Technician Notes</label>
<p class="mb-0">@Model.TechnicianNotes</p>
</div>
}
</div>
</div>
}
</div>
<!-- Right Column -->
<div class="col-lg-4">
<!-- Quick Actions -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-lightning me-2 text-primary"></i>Quick Actions
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-warning">
<i class="bi bi-pencil me-2"></i>Edit Maintenance
</a>
<a asp-controller="Equipment" asp-action="Details" asp-route-id="@Model.EquipmentId" class="btn btn-outline-primary">
<i class="bi bi-tools me-2"></i>View Equipment
</a>
<hr />
<a asp-action="Delete" asp-route-id="@Model.Id" class="btn btn-outline-danger">
<i class="bi bi-trash me-2"></i>Delete Record
</a>
</div>
</div>
</div>
<!-- Timeline -->
<div class="card border-0 shadow-sm">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-clock-history me-2 text-primary"></i>Timeline
</h5>
</div>
<div class="card-body">
<div class="timeline">
<div class="timeline-item mb-3">
<div class="d-flex align-items-start">
<div class="rounded-circle bg-primary bg-opacity-10 p-2 me-3">
<i class="bi bi-plus-circle text-primary"></i>
</div>
<div>
<small class="text-muted">Created</small>
<p class="mb-0 fw-semibold">@Model.CreatedAt.ToString("MMM dd, yyyy")</p>
</div>
</div>
</div>
<div class="timeline-item mb-3">
<div class="d-flex align-items-start">
<div class="rounded-circle bg-info bg-opacity-10 p-2 me-3">
<i class="bi bi-calendar-check text-info"></i>
</div>
<div>
<small class="text-muted">Scheduled For</small>
<p class="mb-0 fw-semibold">@Model.ScheduledDate.ToString("MMM dd, yyyy")</p>
</div>
</div>
</div>
@if (Model.CompletedDate.HasValue)
{
<div class="timeline-item">
<div class="d-flex align-items-start">
<div class="rounded-circle bg-success bg-opacity-10 p-2 me-3">
<i class="bi bi-check-circle text-success"></i>
</div>
<div>
<small class="text-muted">Completed</small>
<p class="mb-0 fw-semibold">@Model.CompletedDate.Value.ToString("MMM dd, yyyy")</p>
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -1,234 +0,0 @@
@model PagedResult<PowderCoating.Application.DTOs.Maintenance.MaintenanceListDto>
@{
ViewData["Title"] = "Maintenance Records";
ViewData["PageIcon"] = "bi-wrench";
ViewData["PageHelpTitle"] = "Maintenance";
ViewData["PageHelpContent"] = "Track all scheduled and completed maintenance for your shop equipment. Overdue records are those past their scheduled date without a Completed status. Recurring tasks auto-generate future occurrences based on the frequency you set. Click any row to view full details, or use Add Maintenance to schedule new service for any piece of equipment.";
var equipmentId = ViewBag.EquipmentId as int?;
var equipmentName = ViewBag.EquipmentName as string;
}
<div class="pcl-metric-strip">
<div class="pcl-metric-strip-cell">
@await Html.PartialAsync("_Metric", (Label: "TOTAL", Value: Model.TotalCount.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
</div>
<div class="pcl-metric-strip-cell">
@await Html.PartialAsync("_Metric", (Label: "SCHEDULED", Value: Model.Items.Count(m => m.Status == "Scheduled").ToString(), Delta: (string?)null, DeltaDir: (string?)null))
</div>
<div class="pcl-metric-strip-cell">
@await Html.PartialAsync("_Metric", (Label: "IN PROGRESS", Value: Model.Items.Count(m => m.Status == "InProgress").ToString(), Delta: (string?)null, DeltaDir: (string?)null))
</div>
<div class="pcl-metric-strip-cell">
@await Html.PartialAsync("_Metric", (Label: "OVERDUE", Value: Model.Items.Count(m => m.Status == "Overdue").ToString(), Delta: (string?)null, DeltaDir: (string?)null))
</div>
</div>
@if ((bool)(ViewBag.PendingOnly ?? false))
{
<div class="alert alert-warning alert-permanent d-flex justify-content-between align-items-center mb-3">
<div>
<i class="bi bi-funnel-fill me-2"></i>
Showing <strong>@Model.TotalCount</strong> pending maintenance record@(Model.TotalCount == 1 ? "" : "s") — Scheduled, In Progress, or Overdue
</div>
<a href="@Url.Action("Index")" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-x me-1"></i>Show All
</a>
</div>
}
<!-- Maintenance Records Table Card -->
<div class="card border-0 shadow-sm">
<div class="card-header bg-white border-0 py-3">
<div class="d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center gap-2">
<span class="fw-semibold">
@if (equipmentId.HasValue && !string.IsNullOrEmpty(equipmentName))
{
@equipmentName
}
else
{
<span>All Maintenance Records</span>
}
</span>
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Maintenance Records"
data-bs-content="Scheduled = upcoming work not yet started. In Progress = work has begun. Completed = service finished (updates Last Maintenance date on the equipment). Overdue = past the scheduled date with no completion recorded. Cancelled = task voided. Recurring tasks show a blue badge and auto-generate future occurrences when saved.">
<i class="bi bi-question-circle"></i>
</a>
</div>
<div class="d-flex gap-2">
@if (equipmentId.HasValue)
{
<a asp-controller="Equipment" asp-action="Details" asp-route-id="@equipmentId" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-2"></i>Back to Equipment
</a>
<a asp-action="Create" asp-route-equipmentId="@equipmentId" class="btn btn-primary">
<i class="bi bi-plus-circle me-2"></i>Add Maintenance
</a>
}
else
{
<a asp-action="Create" class="btn btn-primary">
<i class="bi bi-plus-circle me-2"></i>Add Maintenance
</a>
}
</div>
</div>
</div>
<div class="card-body p-0">
@if (!Model.Items.Any())
{
<div class="text-center py-5">
<i class="bi bi-inbox" style="font-size: 4rem; color: #d1d5db;"></i>
<h5 class="mt-3 text-muted">No maintenance records found</h5>
<p class="text-muted mb-4">Get started by scheduling maintenance</p>
<a asp-action="Create" asp-route-equipmentId="@equipmentId" class="btn btn-primary">
<i class="bi bi-plus-circle me-2"></i>Schedule Maintenance
</a>
</div>
}
else
{
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th class="ps-4">Equipment</th>
<th sortable="MaintenanceType" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Type</th>
<th sortable="ScheduledDate" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Scheduled Date</th>
<th sortable="Status" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Status</th>
<th sortable="Priority" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Priority</th>
<th sortable="Cost" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Cost</th>
<th class="text-end pe-4">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var maintenance in Model.Items)
{
<tr style="cursor: pointer;" onclick="window.location.href='@Url.Action("Details", "Maintenance", new { id = maintenance.Id })'">
<td class="ps-4">
<div class="fw-semibold">@maintenance.EquipmentName</div>
</td>
<td>
@maintenance.MaintenanceType
@if (maintenance.IsRecurring)
{
<br /><span class="badge bg-info text-dark" style="font-size:0.7em;"><i class="bi bi-arrow-repeat me-1"></i>Recurring</span>
}
</td>
<td>
<div>@maintenance.ScheduledDate.ToString("MMM dd, yyyy")</div>
@if (maintenance.CompletedDate.HasValue)
{
<small class="text-muted">Completed: @maintenance.CompletedDate.Value.ToString("MMM dd, yyyy")</small>
}
</td>
<td>
@await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.MaintenanceStatus(maintenance.Status), Text: maintenance.StatusDisplay))
</td>
<td>
@await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.MaintenancePriority(maintenance.Priority), Text: maintenance.PriorityDisplay))
</td>
<td>
<span class="fw-semibold">@maintenance.TotalCost.ToString("C")</span>
</td>
<td class="text-end pe-4" onclick="event.stopPropagation();">
<div class="btn-group btn-group-sm">
<a asp-action="Details" asp-route-id="@maintenance.Id" class="btn btn-outline-primary" title="View Details">
<i class="bi bi-eye"></i>
</a>
<a asp-action="Edit" asp-route-id="@maintenance.Id" class="btn btn-outline-warning" title="Edit">
<i class="bi bi-pencil"></i>
</a>
<a asp-action="Delete" asp-route-id="@maintenance.Id" class="btn btn-outline-danger" title="Delete">
<i class="bi bi-trash"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<!-- Mobile Card View -->
<div class="mobile-card-view">
<div class="mobile-card-list">
@foreach (var maintenance in Model.Items)
{
<div class="mobile-data-card"
data-id="@maintenance.Id"
onclick="window.location.href='@Url.Action("Details", new { id = maintenance.Id })'">
<div class="mobile-card-header">
<div class="mobile-card-icon" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
<i class="bi bi-wrench"></i>
</div>
<div class="mobile-card-title">
<h6>@maintenance.EquipmentName</h6>
<small>
@maintenance.MaintenanceType
@if (maintenance.IsRecurring)
{
<span class="badge bg-info text-dark ms-1" style="font-size:0.65em;"><i class="bi bi-arrow-repeat"></i> Recurring</span>
}
</small>
</div>
</div>
<div class="mobile-card-body">
<div class="mobile-card-row">
<span class="mobile-card-label">Scheduled</span>
<span class="mobile-card-value">@maintenance.ScheduledDate.ToString("MMM dd, yyyy")</span>
</div>
@if (maintenance.CompletedDate.HasValue)
{
<div class="mobile-card-row">
<span class="mobile-card-label">Completed</span>
<span class="mobile-card-value">@maintenance.CompletedDate.Value.ToString("MMM dd, yyyy")</span>
</div>
}
<div class="mobile-card-row">
<span class="mobile-card-label">Status</span>
<span class="mobile-card-value">
@await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.MaintenanceStatus(maintenance.Status), Text: maintenance.StatusDisplay))
</span>
</div>
<div class="mobile-card-row">
<span class="mobile-card-label">Priority</span>
<span class="mobile-card-value">
@await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.MaintenancePriority(maintenance.Priority), Text: maintenance.PriorityDisplay))
</span>
</div>
<div class="mobile-card-row">
<span class="mobile-card-label">Cost</span>
<span class="mobile-card-value fw-semibold text-primary">@maintenance.TotalCost.ToString("C")</span>
</div>
</div>
<div class="mobile-card-footer">
<a href="@Url.Action("Details", new { id = maintenance.Id })"
class="btn btn-sm btn-outline-primary"
onclick="event.stopPropagation();">
<i class="bi bi-eye me-1"></i>View
</a>
<a href="@Url.Action("Edit", new { id = maintenance.Id })"
class="btn btn-sm btn-outline-secondary"
onclick="event.stopPropagation();">
<i class="bi bi-pencil me-1"></i>Edit
</a>
</div>
</div>
}
</div>
</div>
}
</div>
@if (Model.TotalCount > 0)
{
@await Html.PartialAsync("_Pagination", Model)
}
</div>