feat: Add CutList.Web Blazor Server application

Add a new web-based frontend for cut list optimization using:
- Blazor Server with .NET 8
- Entity Framework Core with MSSQL LocalDB
- Full CRUD for Materials, Suppliers, Projects, and Cutting Tools
- Supplier stock length management for quick project setup
- Integration with CutList.Core for bin packing optimization
- Print-friendly HTML reports with efficiency statistics

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-01 21:56:21 -05:00
parent 6db8ab21f4
commit 9868df162d
43 changed files with 4452 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
@using CutList.Core.Formatting
<div class="length-input">
<input type="text"
class="form-control @(HasError ? "is-invalid" : "")"
value="@DisplayValue"
@onchange="OnInputChange"
placeholder="e.g., 12' 6&quot; or 144" />
@if (HasError)
{
<div class="invalid-feedback">@ErrorMessage</div>
}
</div>
@code {
[Parameter]
public decimal Value { get; set; }
[Parameter]
public EventCallback<decimal> ValueChanged { get; set; }
[Parameter]
public string? Placeholder { get; set; }
private string DisplayValue { get; set; } = string.Empty;
private bool HasError { get; set; }
private string ErrorMessage { get; set; } = string.Empty;
protected override void OnParametersSet()
{
if (Value > 0 && string.IsNullOrEmpty(DisplayValue))
{
DisplayValue = ArchUnits.FormatFromInches((double)Value);
}
}
private async Task OnInputChange(ChangeEventArgs e)
{
var input = e.Value?.ToString() ?? string.Empty;
DisplayValue = input;
HasError = false;
ErrorMessage = string.Empty;
if (string.IsNullOrWhiteSpace(input))
{
await ValueChanged.InvokeAsync(0);
return;
}
try
{
// Try to parse as architectural units
var inches = ArchUnits.ParseToInches(input);
await ValueChanged.InvokeAsync((decimal)inches);
}
catch
{
// Try to parse as plain decimal (inches)
if (decimal.TryParse(input, out var decimalValue))
{
await ValueChanged.InvokeAsync(decimalValue);
}
else
{
HasError = true;
ErrorMessage = "Invalid format. Use feet (12'), inches (6\"), or decimal (144)";
}
}
}
public static string FormatLength(decimal inches)
{
return ArchUnits.FormatFromInches((double)inches);
}
}