Project Details Page + Employees

This commit is contained in:
Marc Wieland
2025-10-15 15:01:00 +02:00
parent 910ed8b8f8
commit de2c369350
66 changed files with 367 additions and 128 deletions

View File

@@ -139,8 +139,17 @@ else
<td>@o.Planstunden</td>
<td>@o.Iststunden</td>
<td>
<!-- Mitarbeiter-Zuordnung (später) -->
<span class="text-muted small">noch offen</span>
@if (o.Mitarbeiter?.Any() == true)
{
@foreach (var m in o.Mitarbeiter)
{
<span class="badge bg-info text-dark me-1">@m.FirstName @m.LastName</span>
}
}
else
{
<span class="text-muted small">keine zugewiesen</span>
}
</td>
<td class="text-end">
<button class="btn btn-outline-danger btn-sm" @onclick="() => DeleteOrder(o.Id)">
@@ -232,10 +241,38 @@ else
case "members":
<div>
<h5>Mitarbeiter</h5>
<p>Teamzuordnung, Rollenverwaltung, People Picker.</p>
@if (projectMembers == null || !projectMembers.Any())
{
<div class="alert alert-info mt-3 text-center">
Keine Mitarbeiter zugewiesen.
</div>
}
else
{
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 mt-3">
@foreach (var member in projectMembers)
{
<div class="col">
<div class="card h-100 shadow-sm border-0">
<div class="card-body">
<h6 class="card-title mb-1 text-primary">
@member.FirstName @member.LastName
</h6>
<p class="card-text text-muted small mb-1">@member.Username</p>
<p class="card-text text-muted small mb-0">
<i class="bi bi-envelope"></i> @member.Email
</p>
</div>
</div>
</div>
}
</div>
}
</div>
break;
case "documents":
<div>
<h5>Dokumente</h5>
@@ -275,9 +312,10 @@ else
protected override async Task OnInitializedAsync()
{
await LoadProjectAsync();
await LoadOrderAsync();
await LoadUsersAsync();
var result = await OrderService.GetOrdersByProjectAsync(1);
Console.WriteLine($"Orders loaded: {result.Data?.Count}");
}
@@ -361,6 +399,7 @@ else
if(result.Success)
{
orders = result.Data;
RefreshProjectMembers();
}
else
{
@@ -370,8 +409,11 @@ else
private async Task CreateOrderAsync()
{
// Mitarbeiter mit reinpacken
newOrder.Mitarbeiter = users.Where(u => selectedUserIds.Contains(u.Id)).ToList();
var result = await OrderService.CreateOrderAsync(newOrder);
if(!result.Success)
if (!result.Success)
{
errorMessage = result.Error;
return;
@@ -395,6 +437,35 @@ else
}
}
private async Task LoadUsersAsync()
{
var result = await UserService.GetUsersAsync();
if (result.Success && result.Data != null)
{
users = result.Data;
Console.WriteLine($"Loaded {users.Count} users.");
}
else
{
errorMessage = result.Error ?? "Fehler beim Laden der Benutzer.";
}
}
private List<UserDto> projectMembers = new();
private void RefreshProjectMembers()
{
if (orders == null) return;
projectMembers = orders
.Where(o => o.Mitarbeiter != null)
.SelectMany(o => o.Mitarbeiter!)
.GroupBy(u => u.Id)
.Select(g => g.First())
.OrderBy(u => u.LastName)
.ThenBy(u => u.FirstName)
.ToList();
}
}
<style>

View File

@@ -184,10 +184,10 @@ else
private string? errorMessage;
private bool showAddModal = false;
private ProjectCreateDto newProject = new();
private List<User> users = new();
private List<UserDto> users = new();
private string searchText = "";
private IEnumerable<User> FilteredUsers => string.IsNullOrWhiteSpace(searchText)
private IEnumerable<UserDto> FilteredUsers => string.IsNullOrWhiteSpace(searchText)
? users
: users.Where(u => $"{u.FirstName} {u.LastName} {u.Username}"
.Contains(searchText, StringComparison.OrdinalIgnoreCase));

View File

@@ -1,6 +1,7 @@
@page "/users"
@using OnProfNext.Client.Services
@using OnProfNext.Shared.Models
@using OnProfNext.Shared.Models.DTOs
@inject UserApiService UserService
@inject AuthService AuthService
@inject NavigationManager Nav
@@ -139,9 +140,9 @@ else
@code {
private List<User>? users;
private List<UserDto>? users;
private string? errorMessage;
private User? selectedUser;
private UserDto? selectedUser;
private bool showDeleteConfirm = false;
private string deleteConfirmInput = string.Empty;