@page "/materials/new" @page "/materials/{Id:int}" @inject MaterialService MaterialService @inject NavigationManager Navigation @using CutList.Core.Formatting @using CutList.Web.Data.Entities @using CutList.Web.Components.Shared @(IsNew ? "Add Material" : "Edit Material")

@(IsNew ? "Add Material" : material.DisplayName)

@if (loading) {

Loading...

} else {
Material Details
@foreach (var shape in Enum.GetValues()) { } @if (!IsNew) {
Shape cannot be changed after creation.
}
@foreach (var type in Enum.GetValues()) { }
@if (selectedShape != null) { @RenderDimensionInputs() }
Leave blank to auto-generate from dimensions, or customize as needed.
@if (!string.IsNullOrEmpty(errorMessage)) {
@errorMessage
}
@(IsNew ? "Cancel" : "Back to List")
@if (selectedShape != null) {
Preview
Shape
@selectedShape.Value.GetDisplayName()
Type
@material.Type
@if (!string.IsNullOrWhiteSpace(material.Grade)) {
Grade
@material.Grade
}
Size
@GetPreviewSize()
@if (!string.IsNullOrWhiteSpace(material.Description)) {
Description
@material.Description
}
}
} @code { [Parameter] public int? Id { get; set; } private Material material = new(); private MaterialShape? selectedShape; private bool loading = true; private bool saving; private string? errorMessage; // Typed dimension objects for each shape private RoundBarDimensions roundBarDims = new(); private RoundTubeDimensions roundTubeDims = new(); private FlatBarDimensions flatBarDims = new(); private SquareBarDimensions squareBarDims = new(); private SquareTubeDimensions squareTubeDims = new(); private RectangularTubeDimensions rectTubeDims = new(); private AngleDimensions angleDims = new(); private ChannelDimensions channelDims = new(); private IBeamDimensions ibeamDims = new(); private PipeDimensions pipeDims = new(); private bool IsNew => !Id.HasValue; protected override async Task OnInitializedAsync() { if (Id.HasValue) { var existing = await MaterialService.GetByIdAsync(Id.Value); if (existing == null) { Navigation.NavigateTo("materials"); return; } material = existing; selectedShape = existing.Shape; LoadDimensionsFromMaterial(existing); } loading = false; } private void LoadDimensionsFromMaterial(Material m) { if (m.Dimensions == null) return; switch (m.Dimensions) { case RoundBarDimensions d: roundBarDims = d; break; case RoundTubeDimensions d: roundTubeDims = d; break; case FlatBarDimensions d: flatBarDims = d; break; case SquareBarDimensions d: squareBarDims = d; break; case SquareTubeDimensions d: squareTubeDims = d; break; case RectangularTubeDimensions d: rectTubeDims = d; break; case AngleDimensions d: angleDims = d; break; case ChannelDimensions d: channelDims = d; break; case IBeamDimensions d: ibeamDims = d; break; case PipeDimensions d: pipeDims = d; break; } } private MaterialDimensions GetCurrentDimensions() => selectedShape switch { MaterialShape.RoundBar => roundBarDims, MaterialShape.RoundTube => roundTubeDims, MaterialShape.FlatBar => flatBarDims, MaterialShape.SquareBar => squareBarDims, MaterialShape.SquareTube => squareTubeDims, MaterialShape.RectangularTube => rectTubeDims, MaterialShape.Angle => angleDims, MaterialShape.Channel => channelDims, MaterialShape.IBeam => ibeamDims, MaterialShape.Pipe => pipeDims, _ => throw new InvalidOperationException("No shape selected") }; private void OnShapeChanged() { if (selectedShape.HasValue) { material.Shape = selectedShape.Value; } } private string GetPreviewSize() { if (!string.IsNullOrWhiteSpace(material.Size)) { return material.Size; } if (selectedShape.HasValue) { try { var generated = GetCurrentDimensions().GenerateSizeString(); return string.IsNullOrWhiteSpace(generated) ? "(enter dimensions)" : generated; } catch { return "(enter dimensions)"; } } return "(select shape and enter dimensions)"; } private RenderFragment RenderDimensionInputs() => __builder => { switch (selectedShape!.Value) { case MaterialShape.RoundBar:
break; case MaterialShape.RoundTube:
break; case MaterialShape.FlatBar:
break; case MaterialShape.SquareBar:
break; case MaterialShape.SquareTube:
break; case MaterialShape.RectangularTube:
break; case MaterialShape.Angle:
break; case MaterialShape.Channel:
break; case MaterialShape.IBeam:
break; case MaterialShape.Pipe:
break; } }; private async Task SaveAsync() { errorMessage = null; saving = true; try { if (!selectedShape.HasValue) { errorMessage = "Shape is required"; return; } material.Shape = selectedShape.Value; var dimensions = GetCurrentDimensions(); // Auto-generate Size if empty if (string.IsNullOrWhiteSpace(material.Size)) { material.Size = dimensions.GenerateSizeString(); } if (string.IsNullOrWhiteSpace(material.Size)) { errorMessage = "Size is required. Please enter dimensions or provide a size string."; return; } // Check for duplicates if (await MaterialService.ExistsAsync(material.Shape, material.Size, Id)) { errorMessage = "A material with this shape and size already exists"; return; } if (IsNew) { var created = await MaterialService.CreateWithDimensionsAsync(material, dimensions); Navigation.NavigateTo($"materials/{created.Id}"); } else { await MaterialService.UpdateWithDimensionsAsync(material, dimensions); } } finally { saving = false; } } }