Files
CutList/CutList.Web/Components/Pages/Projects/Index.razor
AJ Isaacs c99de55fe1 feat: Update Project pages for multi-material parts
Redesigns Project Edit with a tabbed interface and adds material
selection (shape -> size) when adding parts. Updates Index to show
customer instead of material.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 23:56:19 -05:00

95 lines
3.0 KiB
Plaintext

@page "/projects"
@inject ProjectService ProjectService
@inject NavigationManager Navigation
<PageTitle>Projects</PageTitle>
<div class="d-flex justify-content-between align-items-center mb-3">
<h1>Projects</h1>
<a href="projects/new" class="btn btn-primary">New Project</a>
</div>
@if (loading)
{
<p><em>Loading...</em></p>
}
else if (projects.Count == 0)
{
<div class="alert alert-info">
No projects found. <a href="projects/new">Create your first project</a>.
</div>
}
else
{
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Customer</th>
<th>Cutting Tool</th>
<th>Last Modified</th>
<th style="width: 200px;">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var project in projects)
{
<tr>
<td><a href="projects/@project.Id">@project.Name</a></td>
<td>@(project.Customer ?? "-")</td>
<td>@(project.CuttingTool?.Name ?? "-")</td>
<td>@((project.UpdatedAt ?? project.CreatedAt).ToLocalTime().ToString("g"))</td>
<td>
<a href="projects/@project.Id" class="btn btn-sm btn-outline-primary">Edit</a>
<a href="projects/@project.Id/results" class="btn btn-sm btn-success">Optimize</a>
<button class="btn btn-sm btn-outline-secondary" @onclick="() => DuplicateProject(project)">Copy</button>
<button class="btn btn-sm btn-outline-danger" @onclick="() => ConfirmDelete(project)">Delete</button>
</td>
</tr>
}
</tbody>
</table>
}
<ConfirmDialog @ref="deleteDialog"
Title="Delete Project"
Message="@deleteMessage"
ConfirmText="Delete"
OnConfirm="DeleteConfirmed" />
@code {
private List<Project> projects = new();
private bool loading = true;
private ConfirmDialog deleteDialog = null!;
private Project? projectToDelete;
private string deleteMessage = "";
protected override async Task OnInitializedAsync()
{
projects = await ProjectService.GetAllAsync();
loading = false;
}
private void ConfirmDelete(Project project)
{
projectToDelete = project;
deleteMessage = $"Are you sure you want to delete \"{project.Name}\"? This will also delete all parts and stock bins.";
deleteDialog.Show();
}
private async Task DeleteConfirmed()
{
if (projectToDelete != null)
{
await ProjectService.DeleteAsync(projectToDelete.Id);
projects = await ProjectService.GetAllAsync();
}
}
private async Task DuplicateProject(Project project)
{
var duplicate = await ProjectService.DuplicateAsync(project.Id);
Navigation.NavigateTo($"projects/{duplicate.Id}");
}
}