@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
{
@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
}
@if (selectedShape != null)
{
- 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;
}
}
}