Files
PowderCoatingLogix/src/PowderCoating.Web/Views/OvenScheduler/_BatchCard.cshtml
T
2026-04-23 21:38:24 -04:00

195 lines
8.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@model PowderCoating.Application.DTOs.Scheduling.OvenBatchDto
@{
var statusClass = Model.Status switch
{
"Planned" => "status-planned",
"Loading" => "status-loading",
"InProgress" => "status-inprogress",
"Completed" => "status-completed",
_ => ""
};
var capPct = Model.MaxLoadSqFt.HasValue ? (double)Model.CapacityPct : 0;
var capClass = capPct >= 100 ? "cap-over" : capPct >= 80 ? "cap-warn" : "cap-ok";
var isEditable = Model.Status == "Planned" || Model.Status == "Loading";
}
<div class="batch-card card shadow-sm @statusClass"
id="batch-@Model.Id"
data-batch-id="@Model.Id"
data-oven-id="@Model.OvenCostId"
data-status="@Model.Status"
data-status-id="@Model.StatusId"
data-total-sqft="@Model.TotalSurfaceAreaSqFt"
data-max-sqft="@Model.MaxLoadSqFt">
<div class="card-header py-2 px-3">
<div class="d-flex align-items-center">
<span class="fw-semibold small me-auto">@Model.BatchNumber</span>
@if (Model.AiSuggested)
{
<span class="badge me-1" style="background:#6f42c1;font-size:.7rem;" title="@Model.AiReasoning">
<i class="bi bi-stars me-1"></i>AI
</span>
}
<span class="badge @GetStatusBadge(Model.Status) small">@Model.Status</span>
</div>
@if (Model.ScheduledStartTime.HasValue)
{
<div class="text-muted small mt-1">
<i class="bi bi-clock me-1"></i>
@Model.ScheduledStartTime.Value.ToString("h:mm tt")
@if (Model.EstimatedEndTime.HasValue)
{
<span> @Model.EstimatedEndTime.Value.ToString("h:mm tt")</span>
}
<span class="ms-1">(@Model.CycleMinutes min)</span>
</div>
}
else
{
<div class="text-muted small mt-1"><i class="bi bi-clock me-1"></i>@Model.CycleMinutes min cycle</div>
}
</div>
<div class="card-body p-2">
<!-- Color + temp badge -->
@if (!string.IsNullOrEmpty(Model.PrimaryColorName))
{
<div class="d-flex align-items-center gap-1 mb-2">
<span class="badge bg-secondary small">
<i class="bi bi-palette me-1"></i>@Model.PrimaryColorName
@if (!string.IsNullOrEmpty(Model.PrimaryColorCode)) { <span>(@Model.PrimaryColorCode)</span> }
</span>
@if (Model.CureTemperatureF.HasValue)
{
<span class="badge bg-danger small"><i class="bi bi-thermometer-half me-1"></i>@Model.CureTemperatureF°F</span>
}
</div>
}
<!-- Capacity bar -->
<div class="mb-2">
<div class="d-flex justify-content-between mb-1" style="font-size:.75rem;">
<span class="text-muted">Capacity</span>
<span class="fw-semibold batch-sqft" data-batch-id="@Model.Id">
@Model.TotalSurfaceAreaSqFt.ToString("F1")
@if (Model.MaxLoadSqFt.HasValue) { <span>/ @Model.MaxLoadSqFt.Value.ToString("F0") sqft</span> }
else { <span>sqft</span> }
</span>
</div>
@if (Model.MaxLoadSqFt.HasValue)
{
<div class="capacity-bar-wrap">
<div class="capacity-bar-fill @capClass batch-cap-bar"
data-batch-id="@Model.Id"
style="width: @(Math.Min(capPct, 100).ToString("F1"))%"></div>
</div>
}
</div>
<!-- Items list (drop target) -->
<div class="batch-items-list" id="items-@Model.Id">
@foreach (var item in Model.Items.OrderBy(i => i.CoatPassNumber))
{
<div class="batch-item-row d-flex align-items-center"
id="bitem-@item.Id"
data-batch-item-id="@item.Id"
data-batch-id="@Model.Id"
data-sqft="@item.SurfaceAreaContribution"
draggable="@(isEditable ? "true" : "false")"
@(isEditable ? "" : "style='cursor:default;'")>
<div class="flex-grow-1 overflow-hidden">
<div class="d-flex align-items-center gap-1 text-truncate">
<span class="badge bg-light text-dark border" style="font-size:.7rem;">Pass @item.CoatPassNumber</span>
@if (!string.IsNullOrEmpty(item.ColorName))
{
<span class="text-truncate fw-medium small">@item.ColorName</span>
}
<span class="text-muted small text-truncate">@item.ItemDescription</span>
</div>
<div class="text-muted d-flex align-items-center gap-2" style="font-size:.73rem;">
<span>@item.JobNumber</span>
<span>·</span>
<span>@item.SurfaceAreaContribution.ToString("F1") sqft</span>
@if (!string.IsNullOrEmpty(item.Priority) && item.Priority != "Normal")
{
<span class="badge @GetPriorityBadge(item.Priority) ms-1" style="font-size:.65rem;">@item.Priority</span>
}
</div>
</div>
@if (isEditable)
{
<div class="d-flex align-items-center ms-1 gap-1">
<i class="bi bi-grip-vertical text-muted"></i>
<button class="btn btn-sm p-0 text-danger" style="line-height:1;"
onclick="removeFromBatch(@item.Id, @Model.Id)" title="Remove from batch">
<i class="bi bi-x"></i>
</button>
</div>
}
</div>
}
@if (isEditable)
{
<div class="batch-drop-hint @(!Model.Items.Any() ? "batch-drop-hint-empty" : "")"
id="empty-items-@Model.Id">
<i class="bi bi-plus-circle me-1"></i>
<span>@(Model.Items.Any() ? "Drop more here" : "Drag coats here")</span>
</div>
}
</div>
<!-- Batch action buttons -->
<div class="d-flex gap-1 mt-2 flex-wrap">
@if (Model.Status == "Planned" || Model.Status == "Loading")
{
<button class="btn btn-sm btn-success flex-grow-1"
onclick="startBatch(@Model.Id)">
<i class="bi bi-play-fill me-1"></i>Start
</button>
<button class="btn btn-sm btn-outline-danger"
onclick="deleteBatch(@Model.Id, '@Model.BatchNumber')">
<i class="bi bi-trash"></i>
</button>
}
else if (Model.Status == "InProgress")
{
<button class="btn btn-sm btn-warning flex-grow-1"
onclick="completeBatch(@Model.Id)">
<i class="bi bi-check-circle me-1"></i>Complete
</button>
}
else if (Model.Status == "Completed")
{
<div class="text-success small w-100 text-center">
<i class="bi bi-check-circle-fill me-1"></i>
Completed @Model.ActualEndTime?.ToString("h:mm tt")
</div>
}
</div>
</div>
</div>
@functions {
string GetStatusBadge(string status) => status switch
{
"Planned" => "bg-secondary",
"Loading" => "bg-primary",
"InProgress" => "bg-warning text-dark",
"Completed" => "bg-success",
"Cancelled" => "bg-danger",
_ => "bg-light text-dark"
};
string GetPriorityBadge(string priority) => priority switch
{
"Rush" => "bg-danger",
"Urgent" => "bg-warning text-dark",
"High" => "bg-primary",
_ => "bg-secondary"
};
}