Compare commits
5 Commits
dc83bd10a4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
059218eb19 | ||
|
|
de2c369350 | ||
|
|
910ed8b8f8 | ||
|
|
789d44a344 | ||
|
|
77ef3ff591 |
36
.gitignore
vendored
Normal file
36
.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Visual Studio / .NET allgemein
|
||||
.vs/
|
||||
bin/
|
||||
obj/
|
||||
*.user
|
||||
*.suo
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Build artefacts
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
|
||||
# Blazor / WASM
|
||||
wwwroot/*.gz
|
||||
wwwroot/*.br
|
||||
|
||||
# Rider / VS Code
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Logs & temp files
|
||||
*.log
|
||||
*.tlog
|
||||
*.cache
|
||||
*.pdb
|
||||
*.tmp
|
||||
|
||||
# System Files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
.DS_Store
|
||||
@@ -1,4 +1,6 @@
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
@@ -11,3 +13,12 @@
|
||||
</NotFound>
|
||||
</Router>
|
||||
|
||||
@code{
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if(firstRender)
|
||||
{
|
||||
await JS.InvokeVoidAsync("hideLoader");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<!-- Navbar -->
|
||||
<div class="top-row px-4 d-flex align-items-center justify-content-between">
|
||||
<div class="flex-grow-1">
|
||||
<a class="fw-semibold text-decoration-none text-dark" href="/"> OnProf Next</a>
|
||||
@@ -25,7 +24,9 @@
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
<div class="page-transition">
|
||||
@Body
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
@@ -34,10 +35,18 @@
|
||||
private string? username;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
AuthService.OnAuthStateChanged += async () => await LoadUsername();
|
||||
await LoadUsername();
|
||||
}
|
||||
|
||||
private async Task LoadUsername()
|
||||
{
|
||||
username = await AuthService.GetUsernameAsync();
|
||||
if (string.IsNullOrEmpty(username))
|
||||
username = "Gast";
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task Logout()
|
||||
@@ -45,8 +54,14 @@
|
||||
await AuthService.LogoutAsync();
|
||||
Nav.NavigateTo("/login", forceLoad: true);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AuthService.OnAuthStateChanged -= async () => await LoadUsername();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<style>
|
||||
.top-row {
|
||||
background-color: #f8f9fa;
|
||||
@@ -79,4 +94,24 @@
|
||||
border-radius: 0.4rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.page-transition {
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
@@keyframes fadeIn {
|
||||
from
|
||||
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
148
OnProfNext.Client/Components/Modals/ProjectModal.razor
Normal file
148
OnProfNext.Client/Components/Modals/ProjectModal.razor
Normal file
@@ -0,0 +1,148 @@
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
@inject ProjectApiService ProjectService
|
||||
@inject UserApiService UserService
|
||||
|
||||
<div class="modal fade @(ShowModal ? "show d-block" : "")" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered" @onclick:stopPropagation>
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title">Neues Projekt anlegen</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if (users == null)
|
||||
{
|
||||
<div class="text-center mt-3">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-2 text-secondary">Benutzer werden geladen...</p>
|
||||
</div>
|
||||
@if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
<div class="alert alert-danger mt-3">@errorMessage</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<EditForm Model="NewProject" OnValidSubmit="CreateProjectAsync">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Projektname</label>
|
||||
<InputText class="form-control" @bind-Value="NewProject.ProjectName" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Beschreibung</label>
|
||||
<InputTextArea class="form-control" rows="3" @bind-Value="NewProject.Description" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Projektleiter</label>
|
||||
<InputText class="form-control mb-2" @bind-Value="SearchText" placeholder="Projektleiter suchen..." />
|
||||
<div class="list-group" style="max-height: 150px; overflow-y: auto;">
|
||||
@if (!FilteredUsers.Any())
|
||||
{
|
||||
<div class="list-group-item text-muted">Keine Benutzer gefunden</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var user in FilteredUsers)
|
||||
{
|
||||
<label class="list-group-item">
|
||||
<input type="checkbox"
|
||||
value="@user.Id"
|
||||
checked="@(NewProject.ProjectManagerIds.Contains(user.Id))"
|
||||
@onchange="@(e => ToggleProjectManager(user.Id, e.Value != null && (bool)e.Value))" />
|
||||
@user.FirstName @user.LastName (@user.Username)
|
||||
</label>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Status</label>
|
||||
<InputSelect class="form-select" @bind-Value="NewProject.Status">
|
||||
<option value="Geplant">Geplant</option>
|
||||
<option value="In Arbeit">In Arbeit</option>
|
||||
<option value="Abgeschlossen">Abgeschlossen</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="CloseModal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public bool ShowModal { get; set; }
|
||||
[Parameter] public EventCallback<bool> ShowModalChanged { get; set; }
|
||||
[Parameter] public ProjectCreateDto NewProject { get; set; } = new();
|
||||
[Parameter] public EventCallback<ProjectCreateDto> OnProjectCreated { get; set; }
|
||||
[Parameter] public string SearchText { get; set; } = "";
|
||||
|
||||
private List<UserDto>? users;
|
||||
private string? errorMessage;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadUsersAsync();
|
||||
}
|
||||
|
||||
private async Task LoadUsersAsync()
|
||||
{
|
||||
var userResult = await UserService.GetUsersAsync();
|
||||
Console.WriteLine($"UserService.GetUsersAsync result: Success={userResult.Success}, Data={userResult.Data?.Count}, Error={userResult.Error}");
|
||||
if (userResult.Success && userResult.Data != null)
|
||||
{
|
||||
users = userResult.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = userResult.Error ?? "Fehler beim Laden der Benutzer.";
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<UserDto> FilteredUsers => users is null || string.IsNullOrWhiteSpace(SearchText)
|
||||
? Enumerable.Empty<UserDto>()
|
||||
: users.Where(u => $"{u.FirstName} {u.LastName} {u.Username}"
|
||||
.Contains(SearchText, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
private void CloseModal()
|
||||
{
|
||||
ShowModal = false;
|
||||
ShowModalChanged.InvokeAsync(ShowModal);
|
||||
}
|
||||
|
||||
private void ToggleProjectManager(int userId, bool isChecked)
|
||||
{
|
||||
if (isChecked)
|
||||
{
|
||||
if (!NewProject.ProjectManagerIds.Contains(userId))
|
||||
NewProject.ProjectManagerIds.Add(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewProject.ProjectManagerIds.Remove(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateProjectAsync()
|
||||
{
|
||||
var result = await ProjectService.CreateProjectAsync(NewProject);
|
||||
if (result.Success)
|
||||
{
|
||||
await OnProjectCreated.InvokeAsync(NewProject);
|
||||
CloseModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazor.Bootstrap" Version="3.4.0" />
|
||||
<PackageReference Include="Blazored.Typeahead" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.9" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.9" />
|
||||
<PackageReference Include="MudBlazor" Version="8.13.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
139
OnProfNext.Client/Pages/Bookings/BookingEntry.razor
Normal file
139
OnProfNext.Client/Pages/Bookings/BookingEntry.razor
Normal file
@@ -0,0 +1,139 @@
|
||||
@page "/booking-entry"
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
@inject BookingApiService BookingService
|
||||
@inject OrderApiService OrderService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
<h3 class="mb-4 d-flex justify-content-between align-items-center">
|
||||
<span class="text-primary">Zeit buchen</span>
|
||||
<button class="btn btn-outline-secondary" @onclick="GoBack">
|
||||
<i class="bi bi-arrow-left"></i> Zurück
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
@if (isLoading)
|
||||
{
|
||||
<div class="text-center mt-5">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-3 text-secondary">Daten werden geladen...</p>
|
||||
</div>
|
||||
}
|
||||
else if (errorMessage is not null)
|
||||
{
|
||||
<div class="alert alert-danger">@errorMessage</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ul class="nav nav-tabs mb-3">
|
||||
<li class="nav-item">
|
||||
<button class="nav-link @(activeView == ViewType.Classic ? "active" : "")"
|
||||
@onclick="() => activeView = ViewType.Classic">
|
||||
<i class="bi bi-calendar-month me-1"></i> Klassische Ansicht
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link @(activeView == ViewType.Fancy ? "active" : "")"
|
||||
@onclick="() => activeView = ViewType.Fancy">
|
||||
<i class="bi bi-calendar-week me-1"></i> Fancy Ansicht
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content p-3 border rounded bg-white shadow-sm">
|
||||
@if (activeView == ViewType.Classic)
|
||||
{
|
||||
<ClassicView Bookings="MyBookings" Orders="AvailableOrders"
|
||||
OnBookingCreated="ReloadBookings" OnError="ShowError" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<FancyView Bookings="MyBookings" Orders="AvailableOrders"
|
||||
OnBookingCreated="ReloadBookings" OnError="ShowError" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private enum ViewType { Classic, Fancy }
|
||||
private ViewType activeView = ViewType.Classic;
|
||||
private bool isLoading = true;
|
||||
private string? errorMessage;
|
||||
private List<BookingDto> MyBookings = new();
|
||||
private List<OrderDto> AvailableOrders = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadDataAsync();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Lade Bookings des Users
|
||||
var (bookingSuccess, bookings, bookingError) = await BookingService.GetMyBookingsAsync();
|
||||
if (!bookingSuccess)
|
||||
{
|
||||
errorMessage = bookingError;
|
||||
return;
|
||||
}
|
||||
MyBookings = bookings ?? new();
|
||||
|
||||
// Lade Orders des Users
|
||||
var (orderSuccess, orders, orderError) = await OrderService.GetMyOrdersAsync();
|
||||
if (!orderSuccess)
|
||||
{
|
||||
errorMessage = orderError;
|
||||
return;
|
||||
}
|
||||
AvailableOrders = orders ?? new();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"Fehler beim Laden der Daten: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReloadBookings()
|
||||
{
|
||||
var (success, bookings, error) = await BookingService.GetMyBookingsAsync();
|
||||
if (success)
|
||||
{
|
||||
MyBookings = bookings ?? new();
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = error;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowError(string error)
|
||||
{
|
||||
errorMessage = error;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void GoBack() => Navigation.NavigateTo("/projects");
|
||||
}
|
||||
|
||||
<style>
|
||||
.nav-tabs .nav-link {
|
||||
color: #495057;
|
||||
border: none;
|
||||
border-bottom: 3px solid transparent;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
color: #0d6efd;
|
||||
font-weight: 600;
|
||||
border-color: #0d6efd;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
209
OnProfNext.Client/Pages/Bookings/ClassicView.razor
Normal file
209
OnProfNext.Client/Pages/Bookings/ClassicView.razor
Normal file
@@ -0,0 +1,209 @@
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
@inject BookingApiService BookingService
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<button class="btn btn-outline-primary" @onclick="PreviousMonth">
|
||||
<i class="bi bi-chevron-left"></i> Vorheriger Monat
|
||||
</button>
|
||||
<h5 class="text-primary m-0">@CurrentMonth.ToString("MMMM yyyy")</h5>
|
||||
<button class="btn btn-outline-primary" @onclick="NextMonth">
|
||||
Nächster Monat <i class="bi bi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="monthly-calendar">
|
||||
<table class="table table-bordered text-center">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Mo</th>
|
||||
<th>Di</th>
|
||||
<th>Mi</th>
|
||||
<th>Do</th>
|
||||
<th>Fr</th>
|
||||
<th>Sa</th>
|
||||
<th>So</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var week in GetCalendarWeeks())
|
||||
{
|
||||
<tr>
|
||||
@foreach (var day in week)
|
||||
{
|
||||
<td class="@(day.Month == CurrentMonth.Month ? "" : "text-muted") @(IsWeekend(day) ? "weekend" : "")"
|
||||
@onclick="() => OpenModal(day)">
|
||||
@day.Day
|
||||
<br />
|
||||
<small class="@GetHoursColorClass(day)">@GetHoursForDay(day) h</small>
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (showModal)
|
||||
{
|
||||
<div class="modal fade show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered" @onclick:stopPropagation>
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title">Buchung für @selectedDate.ToString("dd.MM.yyyy")</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<EditForm Model="newBooking" OnValidSubmit="SaveBookingAsync">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Auftrag</label>
|
||||
<InputSelect class="form-select" @bind-Value="newBooking.OrderId">
|
||||
<option value="0" disabled>Auswählen...</option>
|
||||
@foreach (var order in Orders)
|
||||
{
|
||||
<option value="@order.Id">@order.Titel (@order.Auftragsnummer)</option>
|
||||
}
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Stunden</label>
|
||||
<InputNumber class="form-control" @bind-Value="newBooking.Hours" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Beschreibung</label>
|
||||
<InputTextArea class="form-control" @bind-Value="newBooking.Description" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="CloseModal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public List<BookingDto> Bookings { get; set; } = new();
|
||||
[Parameter] public List<OrderDto> Orders { get; set; } = new();
|
||||
[Parameter] public EventCallback OnBookingCreated { get; set; }
|
||||
[Parameter] public EventCallback<string> OnError { get; set; }
|
||||
|
||||
private DateTime CurrentMonth = DateTime.Today;
|
||||
private bool showModal;
|
||||
private DateTime selectedDate;
|
||||
private BookingCreateDto newBooking = new();
|
||||
|
||||
private void PreviousMonth()
|
||||
{
|
||||
CurrentMonth = CurrentMonth.AddMonths(-1);
|
||||
}
|
||||
|
||||
private void NextMonth()
|
||||
{
|
||||
CurrentMonth = CurrentMonth.AddMonths(1);
|
||||
}
|
||||
|
||||
private List<DateTime[]> GetCalendarWeeks()
|
||||
{
|
||||
var weeks = new List<DateTime[]>();
|
||||
var firstDayOfMonth = new DateTime(CurrentMonth.Year, CurrentMonth.Month, 1);
|
||||
var firstMonday = firstDayOfMonth.AddDays(-(int)firstDayOfMonth.DayOfWeek + (firstDayOfMonth.DayOfWeek == DayOfWeek.Sunday ? 0 : 1));
|
||||
var currentDay = firstMonday;
|
||||
|
||||
for (int weekCount = 0; weekCount < 6; weekCount++)
|
||||
{
|
||||
// Prüfe, ob currentDay noch im gültigen DateTime-Bereich liegt
|
||||
if (currentDay.Year >= DateTime.MaxValue.Year)
|
||||
break;
|
||||
|
||||
var week = new DateTime[7];
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
week[i] = currentDay;
|
||||
// Prüfe, ob das Hinzufügen eines Tages möglich ist
|
||||
if (currentDay < DateTime.MaxValue.AddDays(-1))
|
||||
currentDay = currentDay.AddDays(1);
|
||||
else
|
||||
break;
|
||||
}
|
||||
weeks.Add(week);
|
||||
|
||||
// Wenn currentDay nicht mehr incrementiert werden kann, beende die Schleife
|
||||
if (currentDay >= DateTime.MaxValue.AddDays(-1))
|
||||
break;
|
||||
}
|
||||
return weeks;
|
||||
}
|
||||
|
||||
private bool IsWeekend(DateTime day)
|
||||
{
|
||||
return day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday;
|
||||
}
|
||||
|
||||
private decimal GetHoursForDay(DateTime day)
|
||||
{
|
||||
return Bookings.Where(b => b.Date.Date == day.Date).Sum(b => b.Hours);
|
||||
}
|
||||
|
||||
private string GetHoursColorClass(DateTime day)
|
||||
{
|
||||
var hours = GetHoursForDay(day);
|
||||
if (hours >= 8)
|
||||
return "text-success";
|
||||
else if (hours > 6 && hours < 8)
|
||||
return "text-warning";
|
||||
else
|
||||
return "text-danger";
|
||||
}
|
||||
|
||||
private void OpenModal(DateTime date)
|
||||
{
|
||||
selectedDate = date;
|
||||
newBooking = new() { Date = date, MandantId = 1 };
|
||||
showModal = true;
|
||||
}
|
||||
|
||||
private void CloseModal() => showModal = false;
|
||||
|
||||
private async Task SaveBookingAsync()
|
||||
{
|
||||
var (success, error) = await BookingService.CreateBookingAsync(newBooking);
|
||||
if (success)
|
||||
{
|
||||
await OnBookingCreated.InvokeAsync();
|
||||
CloseModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
await OnError.InvokeAsync(error ?? "Fehler beim Speichern der Buchung.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<style>
|
||||
.monthly-calendar td {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
vertical-align: top;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.monthly-calendar td:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.monthly-calendar td.weekend {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
</style>
|
||||
282
OnProfNext.Client/Pages/Bookings/FancyView.razor
Normal file
282
OnProfNext.Client/Pages/Bookings/FancyView.razor
Normal file
@@ -0,0 +1,282 @@
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
@inject BookingApiService BookingService
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="fancy-layout d-flex">
|
||||
<div class="orders-sidebar card shadow-sm border-0 me-3" style="width: 250px;">
|
||||
<div class="card-body">
|
||||
<h5 class="text-primary mb-3">Verfügbare Aufträge</h5>
|
||||
<div class="list-group">
|
||||
@if (Orders == null || !Orders.Any())
|
||||
{
|
||||
<p class="text-muted">Keine Aufträge verfügbar</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var order in Orders)
|
||||
{
|
||||
<div class="list-group-item list-group-item-action draggable-order"
|
||||
draggable="true" @ondragstart="() => StartDrag(order.Id)">
|
||||
@order.Titel (@order.Auftragsnummer)
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="week-calendar flex-grow-1">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<button class="btn btn-outline-primary" @onclick="PreviousWeek">
|
||||
<i class="bi bi-chevron-left"></i> Vorherige Woche
|
||||
</button>
|
||||
<h5 class="text-primary m-0">
|
||||
Woche vom @CurrentWeekStart.ToString("dd.MM.yyyy") bis @CurrentWeekStart.AddDays(6).ToString("dd.MM.yyyy")
|
||||
</h5>
|
||||
<button class="btn btn-outline-primary" @onclick="NextWeek">
|
||||
Nächste Woche <i class="bi bi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
<table class="table table-bordered text-center">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width: 80px;">Zeit</th>
|
||||
@foreach (var day in WeekDays)
|
||||
{
|
||||
<th class="@(IsWeekend(day) ? "weekend" : "")">
|
||||
@day.ToString("dd.MM") (@day.ToString("ddd"))
|
||||
<br />
|
||||
<small class="@GetHoursColorClass(day)">@GetHoursForDay(day) h</small>
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (int hour = 8; hour <= 18; hour++)
|
||||
{
|
||||
var localHour = hour;
|
||||
<tr>
|
||||
<td>@localHour:00</td>
|
||||
@foreach (var day in WeekDays)
|
||||
{
|
||||
var localDay = day;
|
||||
<td class="@(IsWeekend(localDay) ? "weekend" : "")"
|
||||
@ondrop="() => DropOnSlot(localDay, localHour)" @ondragover="AllowDrop"
|
||||
style="height: 50px; position: relative;">
|
||||
@foreach (var booking in GetBookingsForSlot(localDay, localHour))
|
||||
{
|
||||
<div class="booking-item bg-primary text-white p-1"
|
||||
style="position: absolute; top: 0; left: 0; right: 0; height: @(booking.Hours * 50)px;"
|
||||
title="@booking.OrderTitle: @booking.Hours h">
|
||||
@booking.OrderTitle - @booking.Hours h
|
||||
<button class="btn btn-sm btn-danger float-end"
|
||||
@onclick="() => DeleteBooking(booking.Id)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public List<BookingDto>? Bookings { get; set; }
|
||||
[Parameter] public List<OrderDto>? Orders { get; set; }
|
||||
[Parameter] public EventCallback OnBookingCreated { get; set; }
|
||||
[Parameter] public EventCallback<string> OnError { get; set; }
|
||||
|
||||
private DateTime CurrentWeekStart = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + 1);
|
||||
private List<DateTime> WeekDays => Enumerable.Range(0, 7).Select(d => CurrentWeekStart.AddDays(d)).ToList();
|
||||
private int? draggedOrderId;
|
||||
|
||||
private void PreviousWeek()
|
||||
{
|
||||
if (CurrentWeekStart.Year > DateTime.MinValue.Year)
|
||||
{
|
||||
CurrentWeekStart = CurrentWeekStart.AddDays(-7);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void NextWeek()
|
||||
{
|
||||
if (CurrentWeekStart.Year < DateTime.MaxValue.Year)
|
||||
{
|
||||
CurrentWeekStart = CurrentWeekStart.AddDays(7);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartDrag(int orderId)
|
||||
{
|
||||
draggedOrderId = orderId;
|
||||
Console.WriteLine($"Start drag for Order ID: {orderId}");
|
||||
}
|
||||
|
||||
private async Task AllowDrop()
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("onProfNext.preventDefault");
|
||||
}
|
||||
|
||||
private async Task DropOnSlot(DateTime day, int hour)
|
||||
{
|
||||
if (draggedOrderId == null) return;
|
||||
|
||||
var bookingDate = new DateTime(day.Year, day.Month, day.Day, hour, 0, 0, DateTimeKind.Local);
|
||||
Console.WriteLine($"Calculated booking date: {bookingDate.ToString("dd.MM.yyyy HH:mm")} (Kind: {bookingDate.Kind})");
|
||||
|
||||
var newBooking = new BookingCreateDto
|
||||
{
|
||||
OrderId = draggedOrderId.Value,
|
||||
Date = bookingDate,
|
||||
Hours = 1,
|
||||
MandantId = 1
|
||||
};
|
||||
|
||||
Console.WriteLine($"Sending to API: Date={newBooking.Date.ToString("dd.MM.yyyy HH:mm")} (Kind: {newBooking.Date.Kind})");
|
||||
|
||||
try
|
||||
{
|
||||
var (success, error) = await BookingService.CreateBookingAsync(newBooking);
|
||||
if (success)
|
||||
{
|
||||
await OnBookingCreated.InvokeAsync();
|
||||
Console.WriteLine("Booking created successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
await OnError.InvokeAsync(error ?? "Fehler beim Erstellen der Buchung.");
|
||||
Console.WriteLine($"API error: {error}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await OnError.InvokeAsync($"Fehler beim Erstellen der Buchung: {ex.Message}");
|
||||
Console.WriteLine($"Exception in DropOnSlot: {ex.Message}");
|
||||
}
|
||||
|
||||
draggedOrderId = null;
|
||||
}
|
||||
|
||||
private async Task DeleteBooking(int bookingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var (success, error) = await BookingService.DeleteBookingAsync(bookingId);
|
||||
if (success)
|
||||
{
|
||||
await OnBookingCreated.InvokeAsync();
|
||||
Console.WriteLine("Booking deleted successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
await OnError.InvokeAsync(error ?? "Fehler beim Löschen der Buchung.");
|
||||
Console.WriteLine($"API error: {error}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await OnError.InvokeAsync($"Fehler beim Löschen der Buchung: {ex.Message}");
|
||||
Console.WriteLine($"Exception in DeleteBooking: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private List<BookingDto> GetBookingsForSlot(DateTime day, int hour)
|
||||
{
|
||||
var bookings = Bookings?.Where(b => b.Date.Date == day.Date && b.Date.Hour == hour).ToList() ?? new();
|
||||
if (bookings.Any())
|
||||
{
|
||||
Console.WriteLine($"Bookings for {day.ToString("dd.MM.yyyy")} {hour}:00: {bookings.Count}");
|
||||
foreach (var booking in bookings)
|
||||
{
|
||||
Console.WriteLine($"Booking ID={booking.Id}, Date={booking.Date.ToString("dd.MM.yyyy HH:mm")}, Hours={booking.Hours}");
|
||||
}
|
||||
}
|
||||
return bookings;
|
||||
}
|
||||
|
||||
private bool IsWeekend(DateTime day)
|
||||
{
|
||||
return day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday;
|
||||
}
|
||||
|
||||
private decimal GetHoursForDay(DateTime day)
|
||||
{
|
||||
var hours = Bookings?.Where(b => b.Date.Date == day.Date).Sum(b => b.Hours) ?? 0;
|
||||
if (hours > 0)
|
||||
{
|
||||
Console.WriteLine($"Hours for {day.ToString("dd.MM.yyyy")}: {hours}");
|
||||
}
|
||||
return hours;
|
||||
}
|
||||
|
||||
private string GetHoursColorClass(DateTime day)
|
||||
{
|
||||
var hours = GetHoursForDay(day);
|
||||
if (hours >= 8)
|
||||
return "text-success";
|
||||
else if (hours > 6 && hours < 8)
|
||||
return "text-warning";
|
||||
else
|
||||
return "text-danger";
|
||||
}
|
||||
}
|
||||
|
||||
<style>
|
||||
.orders-sidebar {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.draggable-order {
|
||||
cursor: grab;
|
||||
padding: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.week-calendar td {
|
||||
vertical-align: top;
|
||||
min-height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.week-calendar th.weekend {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.week-calendar td.weekend {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.week-calendar td:hover {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
.week-calendar td.weekend:hover {
|
||||
background-color: #e2e6ea;
|
||||
}
|
||||
|
||||
.booking-item {
|
||||
border-radius: 4px;
|
||||
margin: 2px;
|
||||
font-size: 0.9em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
0
OnProfNext.Client/Pages/Component.razor
Normal file
0
OnProfNext.Client/Pages/Component.razor
Normal file
@@ -1,7 +1,106 @@
|
||||
@page "/"
|
||||
@inject NavigationManager Nav
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
<h3 class="mb-4">Willkommen bei OnProf Next</h3>
|
||||
<p class="text-muted">Wähle einen Bereich aus, um fortzufahren:</p>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
<div class="row g-4 mt-3">
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="card dashboard-card text-center" @onclick="() => GoToUsers()">
|
||||
<div class="card-body">
|
||||
<i class="bi bi-people fs-1 text-primary"></i>
|
||||
<h5 class="card-title mt-3">Benutzer</h5>
|
||||
<p class="text-muted small">Verwalte Benutzer und Rechte.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Welcome to your new app.
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="card dashboard-card text-center" @onclick="() => GoToProjects()">
|
||||
<div class="card-body">
|
||||
<i class="bi bi-folder2-open fs-1 text-success"></i>
|
||||
<h5 class="card-title mt-3">Projekte</h5>
|
||||
<p class="text-muted small">Verwalte laufende Projekte und Aufträge.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="card dashboard-card text-center" @onclick="() => GoToBookings()">
|
||||
<div class="card-body">
|
||||
<i class="bi bi-stopwatch fs-1 text-warning"></i>
|
||||
<h5 class="card-title mt-3">Buchungen</h5>
|
||||
<p class="text-muted small">Erfasse Arbeitszeiten auf Projekte.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="card dashboard-card text-center" @onclick="() => GoToAnalysis()">
|
||||
<div class="card-body">
|
||||
<i class="bi bi-graph-up fs-1 text-danger"></i>
|
||||
<h5 class="card-title mt-3">Auswertungen</h5>
|
||||
<p class="text-muted small">Analysiere Projektzeiten und Fortschritt.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="card dashboard-card text-center" @onclick="() => GoToMandants()">
|
||||
<div class="card-body">
|
||||
<i class="bi bi-graph-up fs-1 text-danger"></i>
|
||||
<h5 class="card-title mt-3">Mandanten</h5>
|
||||
<p class="text-muted small">Verwaltung von Mandanten</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code{
|
||||
private void GoToUsers()
|
||||
{
|
||||
Nav.NavigateTo("/users");
|
||||
}
|
||||
|
||||
private void GoToProjects()
|
||||
{
|
||||
Nav.NavigateTo("/projects");
|
||||
}
|
||||
|
||||
private void GoToBookings()
|
||||
{
|
||||
Nav.NavigateTo("/booking-entry");
|
||||
}
|
||||
|
||||
private void GoToAnalysis()
|
||||
{
|
||||
Nav.NavigateTo("/analysis");
|
||||
}
|
||||
|
||||
private void GoToMandants()
|
||||
{
|
||||
Nav.NavigateTo("/mandants");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
<style>
|
||||
.dashboard-card {
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.dashboard-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.card-body i {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.dashboard-card:hover i {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@page "/login"
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models
|
||||
@inject HttpClient Http
|
||||
@inject NavigationManager Nav
|
||||
@inject IJSRuntime JS
|
||||
@inject AuthService AuthService
|
||||
|
||||
<h3>Anmeldung</h3>
|
||||
|
||||
@@ -26,6 +28,11 @@
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">Login</button>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<span>Noch keinen Account? </span>
|
||||
<a href="/createuser" class="link-primary text-decoration-none">Registrieren</a>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
|
||||
@@ -45,9 +52,9 @@
|
||||
}
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<LoginResponse>();
|
||||
await JS.InvokeVoidAsync("localStorage.setItem", "authToken", result!.Token);
|
||||
|
||||
Nav.NavigateTo("/users");
|
||||
await AuthService.LoginAsync(result!.Token);
|
||||
Nav.NavigateTo("/");
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
496
OnProfNext.Client/Pages/Projects/ProjectDetails.razor
Normal file
496
OnProfNext.Client/Pages/Projects/ProjectDetails.razor
Normal file
@@ -0,0 +1,496 @@
|
||||
@page "/projects/{id:int}"
|
||||
@using OnProfNext.Client.Services
|
||||
@inject ProjectApiService ProjectService
|
||||
@inject NavigationManager Nav
|
||||
@inject OrderApiService OrderService
|
||||
@inject UserApiService UserService
|
||||
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
|
||||
<h3 class="mb-4 d-flex justify-content-between align-items-center">
|
||||
<span class="text-primary">📁 Projekt-Details</span>
|
||||
<button class="btn btn-outline-secondary" @onclick="GoBack">
|
||||
<i class="bi bi-arrow-left"></i> Zurück
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
@if (isLoading)
|
||||
{
|
||||
<div class="text-center mt-5">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-3 text-secondary">Projekt wird geladen...</p>
|
||||
</div>
|
||||
}
|
||||
else if (errorMessage is not null)
|
||||
{
|
||||
<div class="alert alert-danger">@errorMessage</div>
|
||||
}
|
||||
else if (project is null)
|
||||
{
|
||||
<div class="alert alert-warning">Projekt nicht gefunden.</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- HEADER -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<h3 class="text-primary mb-1">@project.ProjectName</h3>
|
||||
<span class="badge bg-@GetStatusColor(project.Status)">
|
||||
@project.Status
|
||||
</span>
|
||||
<p class="mt-3 text-muted">@project.Description</p>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<small class="text-muted d-block">
|
||||
<i class="bi bi-calendar"></i>
|
||||
@project.StartDate.ToString("dd.MM.yyyy")
|
||||
@if (project.EndDate is not null)
|
||||
{
|
||||
<span> – @project.EndDate?.ToString("dd.MM.yyyy")</span>
|
||||
}
|
||||
</small>
|
||||
<small class="text-muted d-block mt-1">
|
||||
<i class="bi bi-building"></i> Mandant: @project.MandantId
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (project.ProjectManagers?.Any() == true)
|
||||
{
|
||||
<div class="mt-3">
|
||||
<h6 class="fw-bold text-secondary">Projektleiter</h6>
|
||||
@foreach (var manager in project.ProjectManagers)
|
||||
{
|
||||
<span class="badge bg-primary me-1">@manager.FullName</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TABS -->
|
||||
<ul class="nav nav-tabs mb-3">
|
||||
@foreach (var tab in tabs)
|
||||
{
|
||||
<li class="nav-item">
|
||||
<button class="nav-link @(activeTab == tab.Key ? "active" : "")"
|
||||
@onclick="() => SetActiveTab(tab.Key)">
|
||||
<i class="@tab.Icon me-1"></i> @tab.Title
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content p-3 border rounded bg-white shadow-sm">
|
||||
@switch (activeTab)
|
||||
{
|
||||
case "overview":
|
||||
<div>
|
||||
<h5>Projektübersicht</h5>
|
||||
<p>Hier kommt später ein Überblick über Fortschritt, KPIs und Aktivitäten.</p>
|
||||
</div>
|
||||
break;
|
||||
|
||||
case "tasks":
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5 class="m-0">Aufträge</h5>
|
||||
<button class="btn btn-success btn-sm" @onclick="ShowAddOrderModal">
|
||||
<i class="bi bi-plus-circle"></i> Neuer Auftrag
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (orders is null)
|
||||
{
|
||||
<div class="text-center text-muted mt-3">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
<p>Aufträge werden geladen...</p>
|
||||
</div>
|
||||
}
|
||||
else if (!orders.Any())
|
||||
{
|
||||
<div class="alert alert-info text-center">Keine Aufträge vorhanden.</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Nr.</th>
|
||||
<th>Titel</th>
|
||||
<th>Status</th>
|
||||
<th>Plan (h)</th>
|
||||
<th>Ist (h)</th>
|
||||
<th>Mitarbeiter</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var o in orders)
|
||||
{
|
||||
<tr>
|
||||
<td>@o.Auftragsnummer</td>
|
||||
<td>@o.Titel</td>
|
||||
<td>
|
||||
<span class="badge bg-@GetStatusColor(o.Status)">@o.Status</span>
|
||||
</td>
|
||||
<td>@o.Planstunden</td>
|
||||
<td>@o.Iststunden</td>
|
||||
<td>
|
||||
@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)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (showAddOrderModal)
|
||||
{
|
||||
<div class="modal fade show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered" @onclick:stopPropagation>
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title">Neuen Auftrag anlegen</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseAddOrderModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<EditForm Model="newOrder" OnValidSubmit="CreateOrderAsync">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Auftragsnummer</label>
|
||||
<InputText class="form-control" @bind-Value="newOrder.Auftragsnummer" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Titel</label>
|
||||
<InputText class="form-control" @bind-Value="newOrder.Titel" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Planstunden</label>
|
||||
<InputNumber class="form-control" @bind-Value="newOrder.Planstunden" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Status</label>
|
||||
<InputSelect class="form-select" @bind-Value="newOrder.Status">
|
||||
<option value="Geplant">Geplant</option>
|
||||
<option value="In Arbeit">In Arbeit</option>
|
||||
<option value="Abgeschlossen">Abgeschlossen</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Mitarbeiter zuweisen</label>
|
||||
<InputText class="form-control mb-2" @bind-Value="searchText" placeholder="Mitarbeiter suchen..." />
|
||||
<div class="list-group" style="max-height: 150px; overflow-y: auto;">
|
||||
@foreach (var u in FilteredUsers)
|
||||
{
|
||||
<label class="list-group-item small">
|
||||
<input type="checkbox"
|
||||
value="@u.Id"
|
||||
checked="@(selectedUserIds.Contains(u.Id))"
|
||||
@onchange="(e => ToggleUser(u.Id, (bool)e.Value!))" />
|
||||
@u.FirstName @u.LastName (@u.Username)
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="CloseAddOrderModal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "bookings":
|
||||
<div>
|
||||
<h5>Buchungen</h5>
|
||||
<p>Zeiterfassungen und Plan/Ist-Vergleiche werden hier erscheinen.</p>
|
||||
</div>
|
||||
break;
|
||||
|
||||
case "members":
|
||||
<div>
|
||||
<h5>Mitarbeiter</h5>
|
||||
|
||||
@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>
|
||||
<p>Dateiupload, SharePoint-Verknüpfung, Projektreports.</p>
|
||||
</div>
|
||||
break;
|
||||
|
||||
case "comments":
|
||||
<div>
|
||||
<h5>Kommentare</h5>
|
||||
<p>Chat/Kommentarbereich für Projektkommunikation.</p>
|
||||
</div>
|
||||
break;
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public int id { get; set; }
|
||||
|
||||
private ProjectDto? project;
|
||||
private string? errorMessage;
|
||||
private bool isLoading = true;
|
||||
|
||||
// Tabs
|
||||
private string activeTab = "overview";
|
||||
private readonly List<(string Key, string Title, string Icon)> tabs = new()
|
||||
{
|
||||
("overview", "Übersicht", "bi bi-house"),
|
||||
("tasks", "Aufträge", "bi bi-list-task"),
|
||||
("bookings", "Buchungen", "bi bi-clock-history"),
|
||||
("members", "Mitarbeiter", "bi bi-people"),
|
||||
("documents", "Dokumente", "bi bi-folder2-open"),
|
||||
("comments", "Kommentare", "bi bi-chat-left-text")
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadProjectAsync();
|
||||
await LoadOrderAsync();
|
||||
await LoadUsersAsync();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async Task LoadProjectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await ProjectService.GetProjectAsync(id);
|
||||
if (!result.Success)
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
return;
|
||||
}
|
||||
project = result.Data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"Fehler beim Laden: {ex.Message}";
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetStatusColor(string? status) => status switch
|
||||
{
|
||||
"Geplant" => "secondary",
|
||||
"In Arbeit" => "info",
|
||||
"Abgeschlossen" => "success",
|
||||
_ => "light"
|
||||
};
|
||||
|
||||
private void SetActiveTab(string key) => activeTab = key;
|
||||
private void GoBack() => Nav.NavigateTo("/projects");
|
||||
|
||||
|
||||
|
||||
private List<OrderDto>? orders;
|
||||
private bool showAddOrderModal = false;
|
||||
private OrderDto newOrder = new();
|
||||
private List<UserDto> users = new();
|
||||
private string searchText = "";
|
||||
private List<int> selectedUserIds = new();
|
||||
|
||||
private IEnumerable<UserDto> FilteredUsers => string.IsNullOrWhiteSpace(searchText)
|
||||
? users
|
||||
: users.Where(u => $"{u.FirstName} {u.LastName} {u.Username}".Contains(searchText, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
private void ToggleUser(int id, bool selected)
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
selectedUserIds.Add(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedUserIds.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowAddOrderModal()
|
||||
{
|
||||
newOrder = new OrderDto
|
||||
{
|
||||
ProjectId = project!.Id,
|
||||
Status = "Geplant",
|
||||
MandantId = project.MandantId
|
||||
};
|
||||
|
||||
selectedUserIds.Clear();
|
||||
searchText = "";
|
||||
showAddOrderModal = true;
|
||||
}
|
||||
|
||||
private void CloseAddOrderModal() => showAddOrderModal = false;
|
||||
|
||||
private async Task LoadOrderAsync()
|
||||
{
|
||||
var result = await OrderService.GetOrdersByProjectAsync(project!.Id);
|
||||
if(result.Success)
|
||||
{
|
||||
orders = result.Data;
|
||||
RefreshProjectMembers();
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
CloseAddOrderModal();
|
||||
await LoadOrderAsync();
|
||||
}
|
||||
|
||||
private async Task DeleteOrder(int id)
|
||||
{
|
||||
var result = await OrderService.DeleteOrderAsync(id);
|
||||
if (result.Success)
|
||||
{
|
||||
await LoadOrderAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
.nav-tabs .nav-link {
|
||||
color: #495057;
|
||||
border: none;
|
||||
border-bottom: 3px solid transparent;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
color: #0d6efd;
|
||||
font-weight: 600;
|
||||
border-color: #0d6efd;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
</style>
|
||||
331
OnProfNext.Client/Pages/Projects/Projects.razor
Normal file
331
OnProfNext.Client/Pages/Projects/Projects.razor
Normal file
@@ -0,0 +1,331 @@
|
||||
@page "/projects"
|
||||
@using OnProfNext.Client.Services
|
||||
@using OnProfNext.Shared.Models
|
||||
@using OnProfNext.Shared.Models.DTOs
|
||||
@inject ProjectApiService ProjectService
|
||||
@inject UserApiService UserService
|
||||
@inject NavigationManager Nav
|
||||
|
||||
<h3 class="mb-4 text-primary d-flex justify-content-between align-items-center">
|
||||
<span>📁 Projektübersicht</span>
|
||||
<button class="btn btn-success" @onclick="ShowAddModal">
|
||||
<i class="bi bi-plus-circle"></i> Neues Projekt
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
@if (errorMessage is not null)
|
||||
{
|
||||
<div class="alert alert-danger">@errorMessage</div>
|
||||
}
|
||||
else if (projects is null)
|
||||
{
|
||||
<div class="text-center mt-5">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-3 text-secondary">Projekte werden geladen...</p>
|
||||
</div>
|
||||
}
|
||||
else if (!projects.Any())
|
||||
{
|
||||
<div class="alert alert-info text-center">
|
||||
Es sind aktuell keine Projekte vorhanden.
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var group in projects.GroupBy(p => p.Status))
|
||||
{
|
||||
<h5 class="mt-4 mb-3 fw-bold text-secondary">
|
||||
<i class="bi bi-kanban"></i> @group.Key
|
||||
</h5>
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3">
|
||||
@foreach (var p in group)
|
||||
{
|
||||
<div class="col">
|
||||
<div class="card shadow-sm h-100 border-0 position-relative card-hover"
|
||||
style="cursor: pointer;" @onclick="@(() => OpenProjectDetails(p.Id))"
|
||||
>
|
||||
<button class="btn btn-sm btn-outline-danger position-absolute top-0 end-0 m-2"
|
||||
title="Projekt löschen"
|
||||
@onclick="() => ConfirmDelete(p)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-primary">@p.ProjectName</h5>
|
||||
@if (p.ProjectManagers?.Any() == true)
|
||||
{
|
||||
<div class="mb-2">
|
||||
@foreach (var manager in p.ProjectManagers)
|
||||
{
|
||||
<span class="badge bg-primary me-1">@manager.FullName</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-muted small mb-2"><i class="bi bi-person-circle"></i> Keine Projektleiter</p>
|
||||
}
|
||||
<p class="card-text">@p.Description</p>
|
||||
</div>
|
||||
<div class="card-footer bg-white border-0 text-end small text-muted">
|
||||
<i class="bi bi-calendar"></i>
|
||||
@p.StartDate.ToString("dd.MM.yyyy")
|
||||
@if (p.EndDate is not null)
|
||||
{
|
||||
<span> – @p.EndDate?.ToString("dd.MM.yyyy")</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
<!-- Neues Projekt Modal -->
|
||||
@if (showAddModal)
|
||||
{
|
||||
<div class="modal fade show d-block"
|
||||
tabindex="-1"
|
||||
style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered"
|
||||
@onclick:stopPropagation>
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title">Neues Projekt anlegen</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseAddModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<EditForm Model="newProject" OnValidSubmit="CreateProjectAsync">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Projektname</label>
|
||||
<InputText class="form-control" @bind-Value="newProject.ProjectName" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Beschreibung</label>
|
||||
<InputTextArea class="form-control" rows="3" @bind-Value="newProject.Description" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Projektleiter</label>
|
||||
<InputText class="form-control mb-2" @bind-Value="searchText" placeholder="Projektleiter suchen..." />
|
||||
<div class="list-group" style="max-height: 150px; overflow-y: auto;">
|
||||
@if (!FilteredUsers.Any())
|
||||
{
|
||||
<div class="list-group-item text-muted">Keine Benutzer gefunden</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var user in FilteredUsers)
|
||||
{
|
||||
<label class="list-group-item">
|
||||
<input type="checkbox"
|
||||
value="@user.Id"
|
||||
checked="@(newProject.ProjectManagerIds.Contains(user.Id))"
|
||||
@onchange="@(e => ToggleProjectManager(user.Id, e.Value != null && (bool)e.Value))" />
|
||||
@user.FirstName @user.LastName (@user.Username)
|
||||
</label>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Status</label>
|
||||
<InputSelect class="form-select" @bind-Value="newProject.Status">
|
||||
<option value="Geplant">Geplant</option>
|
||||
<option value="In Arbeit">In Arbeit</option>
|
||||
<option value="Abgeschlossen">Abgeschlossen</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="CloseAddModal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (showDeleteModal)
|
||||
{
|
||||
<div class="modal fade show d-block" tabindex="-1"
|
||||
style="background-color: rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered" @onclick:stopPropagation>
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title">Projekt löschen</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseDeleteModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Möchten Sie das Projekt <strong>@projectToDelete?.ProjectName</strong> wirklich löschen?</p>
|
||||
<p class="text-muted small">Dieser Vorgang kann nicht rückgängig gemacht werden.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" @onclick="CloseDeleteModal">Abbrechen</button>
|
||||
<button class="btn btn-danger" @onclick="DeleteProjectAsync">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
private List<ProjectDto>? projects;
|
||||
private string? errorMessage;
|
||||
private bool showAddModal = false;
|
||||
private ProjectCreateDto newProject = new();
|
||||
private List<UserDto> users = new();
|
||||
private string searchText = "";
|
||||
|
||||
private IEnumerable<UserDto> FilteredUsers => string.IsNullOrWhiteSpace(searchText)
|
||||
? users
|
||||
: users.Where(u => $"{u.FirstName} {u.LastName} {u.Username}"
|
||||
.Contains(searchText, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadProjectsAsync();
|
||||
var userResult = await UserService.GetUsersAsync();
|
||||
if (userResult.Success && userResult.Data != null)
|
||||
users = userResult.Data;
|
||||
}
|
||||
|
||||
private async Task LoadProjectsAsync()
|
||||
{
|
||||
var result = await ProjectService.GetProjectsAsync();
|
||||
if (!result.Success)
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
return;
|
||||
}
|
||||
projects = result.Data?
|
||||
.OrderBy(p => p.Status)
|
||||
.ThenByDescending(p => p.StartDate)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private void ShowAddModal()
|
||||
{
|
||||
newProject = new ProjectCreateDto { Status = "Geplant", MandantId = 1 };
|
||||
searchText = "";
|
||||
showAddModal = true;
|
||||
}
|
||||
|
||||
private void CloseAddModal()
|
||||
{
|
||||
showAddModal = false;
|
||||
}
|
||||
|
||||
private void ToggleProjectManager(int userId, bool isChecked)
|
||||
{
|
||||
if (isChecked)
|
||||
{
|
||||
if (!newProject.ProjectManagerIds.Contains(userId))
|
||||
newProject.ProjectManagerIds.Add(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
newProject.ProjectManagerIds.Remove(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateProjectAsync()
|
||||
{
|
||||
var result = await ProjectService.CreateProjectAsync(newProject);
|
||||
if (!result.Success)
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
return;
|
||||
}
|
||||
CloseAddModal();
|
||||
await LoadProjectsAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool showDeleteModal = false;
|
||||
private ProjectDto? projectToDelete;
|
||||
|
||||
private void ConfirmDelete(ProjectDto project)
|
||||
{
|
||||
projectToDelete = project;
|
||||
showDeleteModal = true;
|
||||
}
|
||||
|
||||
private void CloseDeleteModal()
|
||||
{
|
||||
showDeleteModal = false;
|
||||
projectToDelete = null;
|
||||
}
|
||||
|
||||
private async Task DeleteProjectAsync()
|
||||
{
|
||||
if(projectToDelete is null)
|
||||
return;
|
||||
|
||||
var result = await ProjectService.DeleteProjectAsync(projectToDelete.Id);
|
||||
if(!result.Success)
|
||||
{
|
||||
errorMessage = result.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
CloseDeleteModal();
|
||||
await LoadProjectsAsync();
|
||||
|
||||
}
|
||||
|
||||
private void OpenProjectDetails(int projectId)
|
||||
{
|
||||
Nav.NavigateTo($"/projects/{projectId}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: all 0.15s ease-in-out;
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.list-group-item input[type="checkbox"] {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-outline-danger {
|
||||
border: none;
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.btn-outline-danger:hover {
|
||||
color: white;
|
||||
background-color: #dc3545;
|
||||
}
|
||||
</style>
|
||||
@@ -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;
|
||||
|
||||
@@ -7,6 +7,8 @@ var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
builder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
|
||||
builder.Services.AddBlazorBootstrap();
|
||||
|
||||
//Auth + HTTP Config
|
||||
|
||||
builder.Services.AddScoped<AuthService>();
|
||||
@@ -17,6 +19,20 @@ builder.Services.AddHttpClient<UserApiService>(client =>
|
||||
client.BaseAddress = new Uri("https://localhost:7271/");
|
||||
}).AddHttpMessageHandler<AuthorizationMessageHandler>();
|
||||
|
||||
builder.Services.AddHttpClient<ProjectApiService>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri("https://localhost:7271/");
|
||||
}).AddHttpMessageHandler<AuthorizationMessageHandler>();
|
||||
|
||||
builder.Services.AddHttpClient<OrderApiService>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri("https://localhost:7271/");
|
||||
}).AddHttpMessageHandler<AuthorizationMessageHandler>();
|
||||
|
||||
builder.Services.AddHttpClient<BookingApiService>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri("https://localhost:7271/");
|
||||
}).AddHttpMessageHandler<AuthorizationMessageHandler>();
|
||||
|
||||
builder.Services.AddScoped(sp => new HttpClient
|
||||
{
|
||||
@@ -24,6 +40,8 @@ builder.Services.AddScoped(sp => new HttpClient
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,11 @@ namespace OnProfNext.Client.Services
|
||||
public ValueTask<string?> GetTokenAsync() =>
|
||||
_js.InvokeAsync<string?>("localStorage.getItem", TokenKey);
|
||||
|
||||
public ValueTask LogoutAsync() =>
|
||||
_js.InvokeVoidAsync("localStorage.removeItem", TokenKey);
|
||||
public async Task LogoutAsync()
|
||||
{
|
||||
await _js.InvokeVoidAsync("localStorage.removeItem", TokenKey);
|
||||
OnAuthStateChanged?.Invoke();
|
||||
}
|
||||
|
||||
public async Task<string?> GetUsernameAsync()
|
||||
{
|
||||
@@ -43,6 +46,22 @@ namespace OnProfNext.Client.Services
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public event Action? OnAuthStateChanged;
|
||||
|
||||
public async Task NotifyAuthStateChangedAsync()
|
||||
{
|
||||
OnAuthStateChanged?.Invoke();
|
||||
}
|
||||
|
||||
public async Task LoginAsync(string token)
|
||||
{
|
||||
await SaveTokenAsync(token);
|
||||
OnAuthStateChanged?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task<bool> IsLoggedInAsync()
|
||||
{
|
||||
|
||||
104
OnProfNext.Client/Services/BookingApiService.cs
Normal file
104
OnProfNext.Client/Services/BookingApiService.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace OnProfNext.Client.Services
|
||||
{
|
||||
public class BookingApiService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public BookingApiService(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public async Task<(bool Success, List<BookingDto>? Data, string? Error)> GetMyBookingsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var bookings = await _httpClient.GetFromJsonAsync<List<BookingDto>>("api/bookings/mine");
|
||||
Console.WriteLine($"Received bookings: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}");
|
||||
return (true, bookings ?? new(), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, $"Fehler beim Laden der Buchungen: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Success, List<BookingDto>? Data, string? Error)> GetBookingsByOrderAsync(int orderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bookings = await _httpClient.GetFromJsonAsync<List<BookingDto>>($"api/bookings/byorder/{orderId}");
|
||||
Console.WriteLine($"Received bookings for order {orderId}: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}");
|
||||
return (true, bookings ?? new(), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, $"Fehler beim Laden der Buchungen: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Success, string? Error)> CreateBookingAsync(BookingCreateDto dto)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Explizite Serialisierung für Debugging
|
||||
var jsonPayload = JsonSerializer.Serialize(new
|
||||
{
|
||||
dto.OrderId,
|
||||
date = dto.Date.ToString("yyyy-MM-ddTHH:mm:ss"),
|
||||
dto.Hours,
|
||||
dto.MandantId,
|
||||
dto.Description
|
||||
}, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
|
||||
Console.WriteLine($"Sending booking to API: {jsonPayload}");
|
||||
|
||||
var content = new StringContent(jsonPayload, System.Text.Encoding.UTF8, "application/json");
|
||||
var response = await _httpClient.PostAsync("api/bookings", content);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
Console.WriteLine("Booking API call successful.");
|
||||
return (true, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorContent = await response.Content.ReadAsStringAsync();
|
||||
Console.WriteLine($"API error response: {errorContent}");
|
||||
return (false, $"Fehler beim Speichern: {response.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception in CreateBookingAsync: {ex.Message}");
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Success, string? Error)> DeleteBookingAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.DeleteAsync($"api/bookings/{id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
Console.WriteLine("Delete booking API call successful.");
|
||||
return (true, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorContent = await response.Content.ReadAsStringAsync();
|
||||
Console.WriteLine($"API error response: {errorContent}");
|
||||
return (false, $"Fehler beim Löschen: {response.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception in DeleteBookingAsync: {ex.Message}");
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
147
OnProfNext.Client/Services/OrderApiService.cs
Normal file
147
OnProfNext.Client/Services/OrderApiService.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace OnProfNext.Client.Services
|
||||
{
|
||||
public class OrderApiService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
public OrderApiService(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
// Alle Aufträge zu einem Projekt abrufen
|
||||
public async Task<(bool Success, List<OrderDto>? Data, string? Error)> GetOrdersByProjectAsync(int projectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var orders = await _httpClient.GetFromJsonAsync<List<OrderDto>>($"api/orders/byproject/{projectId}");
|
||||
return (true, orders ?? new List<OrderDto>(), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Einzelnen Auftrag abrufen
|
||||
public async Task<(bool Success, OrderDto? Data, string? Error)> GetOrderAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var order = await _httpClient.GetFromJsonAsync<OrderDto>($"api/orders/{id}");
|
||||
if (order == null)
|
||||
return (false, null, "Auftrag nicht gefunden.");
|
||||
|
||||
return (true, order, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
//Auftrag erstellen
|
||||
public async Task<(bool Success, string? Error)> CreateOrderAsync(OrderDto order)
|
||||
{
|
||||
try
|
||||
{
|
||||
var createDto = new OrderCreateDto
|
||||
{
|
||||
ProjectId = order.ProjectId,
|
||||
Auftragsnummer = order.Auftragsnummer,
|
||||
Titel = order.Titel,
|
||||
Status = order.Status,
|
||||
Planstunden = order.Planstunden,
|
||||
MandantId = order.MandantId,
|
||||
UserIds = order.Mitarbeiter.Select(u => u.Id).ToList()
|
||||
};
|
||||
|
||||
var response = await _httpClient.PostAsJsonAsync("api/orders", createDto);
|
||||
return response.IsSuccessStatusCode
|
||||
? (true, null)
|
||||
: (false, $"Fehler beim Anlegen: {response.ReasonPhrase}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
//Auftrag aktualisieren
|
||||
public async Task<(bool Success, string? Error)> UpdateOrderAsync(OrderDto order)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PutAsJsonAsync($"api/orders/{order.Id}", order);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return (false, $"Fehler beim Aktualisieren: {response.ReasonPhrase}");
|
||||
|
||||
return (true, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
//Auftrag löschen
|
||||
public async Task<(bool Success, string? Error)> DeleteOrderAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.DeleteAsync($"api/orders/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return (false, $"Fehler beim Löschen: {response.ReasonPhrase}");
|
||||
|
||||
return (true, null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, "Server nicht erreichbar.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
//Set Order Users Async
|
||||
public async Task<(bool Success, string? Error)> SetOrderUsersAsync(int orderId, List<int> userIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var payload = new { OrderId = orderId, UserIds = userIds };
|
||||
var response = await _httpClient.PostAsJsonAsync("api/orderusers", payload);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return (false, $"Fehler beim Speichern: {response.ReasonPhrase}");
|
||||
return (true, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// In OrderApiService.cs
|
||||
public async Task<(bool Success, List<OrderDto>? Data, string? Error)> GetMyOrdersAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var orders = await _httpClient.GetFromJsonAsync<List<OrderDto>>("api/orders/mine");
|
||||
return (true, orders ?? new List<OrderDto>(), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, $"Fehler beim Laden der Aufträge: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
120
OnProfNext.Client/Services/ProjectApiService.cs
Normal file
120
OnProfNext.Client/Services/ProjectApiService.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace OnProfNext.Client.Services
|
||||
{
|
||||
public class ProjectApiService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public ProjectApiService(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
// GET: Alle Projekte abrufen
|
||||
public async Task<(bool Success, List<ProjectDto>? Data, string? Error)> GetProjectsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var projects = await _httpClient.GetFromJsonAsync<List<ProjectDto>>("api/projects");
|
||||
return (true, projects ?? new(), null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, null, "Keine Verbindung zum Server. Bitte später erneut versuchen.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, $"Unerwarteter Fehler: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
//GET: Ein einzelnes Projekt abrufen
|
||||
public async Task<(bool Success, ProjectDto? Data, string? Error)> GetProjectAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var project = await _httpClient.GetFromJsonAsync<ProjectDto>($"api/projects/{id}");
|
||||
if (project == null)
|
||||
return (false, null, "Projekt nicht gefunden.");
|
||||
|
||||
return (true, project, null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, null, "Keine Verbindung zum Server. Bitte später erneut versuchen.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, null, $"Unerwarteter Fehler: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// POST: Neues Projekt erstellen
|
||||
public async Task<(bool Success, string? Error)> CreateProjectAsync(ProjectCreateDto dto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PostAsJsonAsync("api/projects", dto);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return (false, $"Fehler beim Anlegen: {response.ReasonPhrase}");
|
||||
}
|
||||
return (true, null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, "Server nicht erreichbar.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT: Bestehendes Projekt aktualisieren
|
||||
public async Task<(bool Success, string? Error)> UpdateProjectAsync(int id, ProjectCreateDto dto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PutAsJsonAsync($"api/projects/{id}", dto);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return (false, $"Fehler beim Aktualisieren: {response.ReasonPhrase}");
|
||||
}
|
||||
return (true, null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, "Server nicht erreichbar.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE: Projekt löschen
|
||||
public async Task<(bool Success, string? Error)> DeleteProjectAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.DeleteAsync($"api/projects/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return (false, $"Fehler beim Löschen: {response.ReasonPhrase}");
|
||||
}
|
||||
return (true, null);
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, "Server nicht erreichbar.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using OnProfNext.Shared.Models;
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace OnProfNext.Client.Services
|
||||
@@ -12,20 +13,20 @@ namespace OnProfNext.Client.Services
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public async Task<(bool Success, List<User>? Data, string? Error)> GetUsersAsync()
|
||||
public async Task<(bool Success, List<UserDto>? Data, string? Error)> GetUsersAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var users = await _httpClient.GetFromJsonAsync<List<User>>("api/users");
|
||||
return (true, users ?? new List<User>(), null);
|
||||
var users = await _httpClient.GetFromJsonAsync<List<UserDto>>("api/users");
|
||||
return (true, users ?? new List<UserDto>(), null);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
return (false, null, "Keine Verbindung zum Server. Bitte später erneut versuchen.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return(false, null, $"Unerwarteter Fehler: {ex.Message}");
|
||||
return (false, null, $"Unerwarteter Fehler: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ namespace OnProfNext.Client.Services
|
||||
}
|
||||
|
||||
|
||||
public async Task<(bool Success, string? Error)> UpdateUserAsync(User user)
|
||||
public async Task<(bool Success, string? Error)> UpdateUserAsync(UserDto user)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Http
|
||||
@using Microsoft.JSInterop
|
||||
@using OnProfNext.Client
|
||||
@using OnProfNext.Client.Layout
|
||||
@using OnProfNext.Client.Components.Layout
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"mainAssemblyName": "OnProfNext.Client",
|
||||
"resources": {
|
||||
"hash": "sha256-AhHfMRoXU+sbJ6Rea3YPtJWuZ6wr1DB+/6q/AtghVyY=",
|
||||
"hash": "sha256-urElDnrJHnNHhcoIgh4qPQgw0DvL1p3uD2eDB4Wd3+M=",
|
||||
"fingerprinting": {
|
||||
"BlazorBootstrap.ym6tnrklwx.wasm": "BlazorBootstrap.wasm",
|
||||
"Blazored.Typeahead.5g65vcuhxb.wasm": "Blazored.Typeahead.wasm",
|
||||
"Microsoft.AspNetCore.Authorization.z6jo10m0rd.wasm": "Microsoft.AspNetCore.Authorization.wasm",
|
||||
"Microsoft.AspNetCore.Components.65wbz7t8mt.wasm": "Microsoft.AspNetCore.Components.wasm",
|
||||
"Microsoft.AspNetCore.Components.Forms.ysqd97eroy.wasm": "Microsoft.AspNetCore.Components.Forms.wasm",
|
||||
@@ -22,6 +24,8 @@
|
||||
"Microsoft.Extensions.FileProviders.Physical.fwg0p8qiey.wasm": "Microsoft.Extensions.FileProviders.Physical.wasm",
|
||||
"Microsoft.Extensions.FileSystemGlobbing.wpqn02ct4s.wasm": "Microsoft.Extensions.FileSystemGlobbing.wasm",
|
||||
"Microsoft.Extensions.Http.34jr7x6h7z.wasm": "Microsoft.Extensions.Http.wasm",
|
||||
"Microsoft.Extensions.Localization.bvn14pws96.wasm": "Microsoft.Extensions.Localization.wasm",
|
||||
"Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm": "Microsoft.Extensions.Localization.Abstractions.wasm",
|
||||
"Microsoft.Extensions.Logging.2h3t8m6coa.wasm": "Microsoft.Extensions.Logging.wasm",
|
||||
"Microsoft.Extensions.Logging.Abstractions.ni4towxuts.wasm": "Microsoft.Extensions.Logging.Abstractions.wasm",
|
||||
"Microsoft.Extensions.Options.2nlpwp09nn.wasm": "Microsoft.Extensions.Options.wasm",
|
||||
@@ -33,6 +37,7 @@
|
||||
"Microsoft.IdentityModel.Tokens.zeqz59uvkx.wasm": "Microsoft.IdentityModel.Tokens.wasm",
|
||||
"Microsoft.JSInterop.9ydsnriizw.wasm": "Microsoft.JSInterop.wasm",
|
||||
"Microsoft.JSInterop.WebAssembly.v6rnols3v9.wasm": "Microsoft.JSInterop.WebAssembly.wasm",
|
||||
"MudBlazor.845kbj1w9a.wasm": "MudBlazor.wasm",
|
||||
"System.IdentityModel.Tokens.Jwt.5tt1rwyygx.wasm": "System.IdentityModel.Tokens.Jwt.wasm",
|
||||
"Microsoft.CSharp.j3zkownjjr.wasm": "Microsoft.CSharp.wasm",
|
||||
"Microsoft.VisualBasic.Core.qljjwgjnrn.wasm": "Microsoft.VisualBasic.Core.wasm",
|
||||
@@ -210,10 +215,10 @@
|
||||
"icudt_CJK.tjcz0u77k5.dat": "icudt_CJK.dat",
|
||||
"icudt_EFIGS.tptq2av103.dat": "icudt_EFIGS.dat",
|
||||
"icudt_no_CJK.lfu7j35m59.dat": "icudt_no_CJK.dat",
|
||||
"OnProfNext.Shared.ihokpa64w4.wasm": "OnProfNext.Shared.wasm",
|
||||
"OnProfNext.Shared.iu0eh4ivxb.pdb": "OnProfNext.Shared.pdb",
|
||||
"OnProfNext.Client.4hwkikhk8q.wasm": "OnProfNext.Client.wasm",
|
||||
"OnProfNext.Client.a2cfufv20d.pdb": "OnProfNext.Client.pdb"
|
||||
"OnProfNext.Shared.lyqfg82b63.wasm": "OnProfNext.Shared.wasm",
|
||||
"OnProfNext.Shared.r9uf34g1jf.pdb": "OnProfNext.Shared.pdb",
|
||||
"OnProfNext.Client.0dluezm643.wasm": "OnProfNext.Client.wasm",
|
||||
"OnProfNext.Client.ape4q24e07.pdb": "OnProfNext.Client.pdb"
|
||||
},
|
||||
"jsModuleNative": {
|
||||
"dotnet.native.9ih887ebfz.js": "sha256-oS7IRiQoVt9ThQ7Y2UM3XoeY0JqPD02cg9IvRdufn2w="
|
||||
@@ -234,6 +239,8 @@
|
||||
"System.Private.CoreLib.uqnhzdwypx.wasm": "sha256-dmlLyil2xqdBc+0yMfmACcDeIGVefS4QHjRT/9mLdNs="
|
||||
},
|
||||
"assembly": {
|
||||
"BlazorBootstrap.ym6tnrklwx.wasm": "sha256-JvZh7RjGQpT7CC6gfoLZbKPPkhcor/rhKKpkCt/2lfU=",
|
||||
"Blazored.Typeahead.5g65vcuhxb.wasm": "sha256-GwHvrw5VqXbXdYF+BX0dOWgR9mMoIh0SLjRrafirlyY=",
|
||||
"Microsoft.AspNetCore.Authorization.z6jo10m0rd.wasm": "sha256-K3j153B4Qx57/sHT4gOICXyadidNa4qEUflLPz/OgCU=",
|
||||
"Microsoft.AspNetCore.Components.65wbz7t8mt.wasm": "sha256-esbkeXi/0iIJjs+MdmPU6nulNqIzqOw5a4hLgs2f6+U=",
|
||||
"Microsoft.AspNetCore.Components.Forms.ysqd97eroy.wasm": "sha256-8o1e7d2phwhchCrOcBV5r/UklI0sSixpCl8wQkEHNfE=",
|
||||
@@ -253,6 +260,8 @@
|
||||
"Microsoft.Extensions.FileProviders.Physical.fwg0p8qiey.wasm": "sha256-j06UStE6FBwEz3CJbgLfbKKSePh0FaT4PK7wtDoUXs0=",
|
||||
"Microsoft.Extensions.FileSystemGlobbing.wpqn02ct4s.wasm": "sha256-BC/MCU6S9BBMqOrRwZh0plnIpsYyZKyENCmb6p3Acsk=",
|
||||
"Microsoft.Extensions.Http.34jr7x6h7z.wasm": "sha256-fTu6J/dJP8yyhw48HS3g8ZOvSNcIA7ConcInauGbohA=",
|
||||
"Microsoft.Extensions.Localization.bvn14pws96.wasm": "sha256-6UgMJoVZBfDdfzYR0aKVK6BWArxpXC1qiQDDjiXw/L4=",
|
||||
"Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm": "sha256-GJNjpp2mlMIYboBhzukWw5r2Z24PsB0E9Gj9VoTGKEI=",
|
||||
"Microsoft.Extensions.Logging.2h3t8m6coa.wasm": "sha256-1jYRjcDI2/MnB5Htgj4yUaHr8gA/poI4oLgWUMZYnV0=",
|
||||
"Microsoft.Extensions.Logging.Abstractions.ni4towxuts.wasm": "sha256-H+TpHvK/z4RGb8EfLe1cGb1TwnCKZAmNxt8e3s3CUSM=",
|
||||
"Microsoft.Extensions.Options.2nlpwp09nn.wasm": "sha256-zp3zuBmKVlE6HjY0Br1uj3fY9sU7ET4ITzgpnpmj9V0=",
|
||||
@@ -264,6 +273,7 @@
|
||||
"Microsoft.IdentityModel.Tokens.zeqz59uvkx.wasm": "sha256-hQbBReIl6OvRCOLal9JHAiyQa9Zejqvl/Q03oc0DvyE=",
|
||||
"Microsoft.JSInterop.9ydsnriizw.wasm": "sha256-oZgTa/to3sE2tSzwcZQ0GIX1meeIGAYVE7IoJDL4RkI=",
|
||||
"Microsoft.JSInterop.WebAssembly.v6rnols3v9.wasm": "sha256-Z/XKvzIKcHVmnvT7y1f4/N5zSNqzNAfjsLaBDIyCkYs=",
|
||||
"MudBlazor.845kbj1w9a.wasm": "sha256-6H3anvXkkN9V1Gxb+Ul/S1lH5SsXdXFbL0IXDHFkVlY=",
|
||||
"System.IdentityModel.Tokens.Jwt.5tt1rwyygx.wasm": "sha256-15e9xXAMloW+NXhmC4dPppM4zlorit69Q+n8h3ToBSI=",
|
||||
"Microsoft.CSharp.j3zkownjjr.wasm": "sha256-r7YS8Hp01zUR3LoH5JsS7IrucOta+FnV199bCLii7Pk=",
|
||||
"Microsoft.VisualBasic.Core.qljjwgjnrn.wasm": "sha256-/jlp74GLHWhrCfjAmWlVClO68H3wIk+kVx9A/gjByls=",
|
||||
@@ -432,12 +442,12 @@
|
||||
"WindowsBase.vy2l5u79y6.wasm": "sha256-ufB9Mo5joMyUs3DzXWWBFFIZNEVrt6h9N5stYB6Oln4=",
|
||||
"mscorlib.xd6mv31d55.wasm": "sha256-1YSLR2eZt3ceALFV//vZUF2AloxVil3VlrW1zZYPSEI=",
|
||||
"netstandard.kaml52uspo.wasm": "sha256-HLEwBpLfzKw2/zGSVzHzFJxznCkt/WIjahrziiMrOpA=",
|
||||
"OnProfNext.Shared.ihokpa64w4.wasm": "sha256-9jmdZcR2jSUk95bksqs7xpGrEf4rB5xQhmsoBKS65Wg=",
|
||||
"OnProfNext.Client.4hwkikhk8q.wasm": "sha256-mOwRgG56/276TVQlsTTlr3yGVAcOed54r2GKKYiDzD8="
|
||||
"OnProfNext.Shared.lyqfg82b63.wasm": "sha256-w7kYJP/DLlO8NXzgUXym1hiG2ch5+jRuO/UZ6krRm6w=",
|
||||
"OnProfNext.Client.0dluezm643.wasm": "sha256-pOEBoGoioxlzoi9tDgJmWxFEJw9FAZpIlohDGRMcHvw="
|
||||
},
|
||||
"pdb": {
|
||||
"OnProfNext.Shared.iu0eh4ivxb.pdb": "sha256-yhx+tHTfofR2P3NL+7DCQla+3z5jDECL3xhAcxOaHl8=",
|
||||
"OnProfNext.Client.a2cfufv20d.pdb": "sha256-LitRcN0GHAOQWBGqsyqjAsm22TSf9ICv+CfY2/9ulAI="
|
||||
"OnProfNext.Shared.r9uf34g1jf.pdb": "sha256-AQbfy8ggW02znMrieOv1c4vomUo5cXk/ptky3fB99YI=",
|
||||
"OnProfNext.Client.ape4q24e07.pdb": "sha256-knq9IhCJxfvepTeExvxDRJhO5nGuddjspkNtCOcBkIY="
|
||||
}
|
||||
},
|
||||
"cacheBootResources": true,
|
||||
|
||||
Binary file not shown.
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("OnProfNext.Client")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6bcf3e881b1402add0ceb5d438103536834114dd")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+de2c3693508bfb15c93127034ea928d860f4ac56")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("OnProfNext.Client")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("OnProfNext.Client")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
e67ff63085959433c842d067aefd0c971e1ee11324b8f7a22c16f51c41b07239
|
||||
08aa3947a1274dbcd1ed8260838c173be7b9ae8231ae4f43fbcf8b894f4cc2ea
|
||||
|
||||
@@ -3,6 +3,9 @@ build_property.EnableAotAnalyzer =
|
||||
build_property.EnableSingleFileAnalyzer =
|
||||
build_property.EnableTrimAnalyzer = false
|
||||
build_property.IncludeAllContentForSelfExtract =
|
||||
build_property.MudDebugAnalyzer =
|
||||
build_property.MudAllowedAttributePattern =
|
||||
build_property.MudAllowedAttributeList =
|
||||
build_property.TargetFramework = net9.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
@@ -28,6 +31,30 @@ build_property.EnableCodeStyleSeverity =
|
||||
build_metadata.AdditionalFiles.TargetPath = QXBwLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Components/Modals/ProjectModal.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xNb2RhbHNcUHJvamVjdE1vZGFsLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Components/Shared/RedirectToLogin.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xTaGFyZWRcUmVkaXJlY3RUb0xvZ2luLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Bookings/BookingEntry.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQm9va2luZ3NcQm9va2luZ0VudHJ5LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Bookings/ClassicView.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQm9va2luZ3NcQ2xhc3NpY1ZpZXcucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Bookings/FancyView.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQm9va2luZ3NcRmFuY3lWaWV3LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Component.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQ29tcG9uZW50LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/CreateUser.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQ3JlYXRlVXNlci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
@@ -40,22 +67,26 @@ build_metadata.AdditionalFiles.CssScope =
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcTG9naW4ucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Users.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcVXNlcnMucmF6b3I=
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Projects/ProjectDetails.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcUHJvamVjdHNcUHJvamVjdERldGFpbHMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Shared/RedirectToLogin.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFJlZGlyZWN0VG9Mb2dpbi5yYXpvcg==
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Projects/Projects.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcUHJvamVjdHNcUHJvamVjdHMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Pages/Users.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcVXNlcnMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/_Imports.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = X0ltcG9ydHMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Layout/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = TGF5b3V0XE1haW5MYXlvdXQucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-se1kx51m2b
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Components/Layout/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xMYXlvdXRcTWFpbkxheW91dC5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope = b-4ckihtz3s1
|
||||
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Layout/NavMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = TGF5b3V0XE5hdk1lbnUucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-z0fmt146ub
|
||||
[C:/DEVQPDC/Proj2/OnProfNext/OnProfNext.Client/Components/Layout/NavMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xMYXlvdXRcTmF2TWVudS5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope = b-c1psfyttma
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
6ea2ac6c7f9e979ce26a9538bb98c0bd6b6ecb3771454fa3d410910ae571aaee
|
||||
50f06df8b13f05293ac10043b87476aa4a048151949bf50c4255adb1c0e403ae
|
||||
|
||||
@@ -42,8 +42,6 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framewor
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Win32.Registry.nbxzikm6ra.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\mscorlib.xd6mv31d55.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\netstandard.kaml52uspo.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.iu0eh4ivxb.pdb
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.ihokpa64w4.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.AppContext.s2mli7k045.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Buffers.d8ayacj23s.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Collections.Concurrent.feo024siyp.wasm
|
||||
@@ -324,7 +322,6 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framewor
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Security.Cryptography.Algorithms.974cvdn89t.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Linq.Parallel.f7fejzp6g2.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Threading.Tasks.3vxtmtq8z2.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.ihokpa64w4.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Linq.Expressions.9qursg64iq.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Diagnostics.StackTrace.klgx6zaqgg.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Threading.Thread.ela0zpa4cu.wasm.gz
|
||||
@@ -353,7 +350,6 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framewor
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Runtime.Extensions.te5ibe9mop.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Extensions.Logging.Abstractions.ni4towxuts.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.IO.Compression.FileSystem.oapcnmb898.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.iu0eh4ivxb.pdb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Web.HttpUtility.kz1rdswtnm.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\System.Security.AccessControl.15bbw5su7q.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\icudt_no_CJK.lfu7j35m59.dat.gz
|
||||
@@ -831,14 +827,11 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\OnProfNext
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\rjimswa.dswa.cache.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\rjsmrazor.dswa.cache.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\rjsmcshtml.dswa.cache.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\Layout\MainLayout.razor.rz.scp.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\Layout\NavMenu.razor.rz.scp.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\bundle\OnProfNext.Client.styles.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\projectbundle\OnProfNext.Client.bundle.scp.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\blazor.build.boot-extension.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\blazor.boot.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\nx0myr140c-8rbvw3on5j.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\9988w5h4ds-939jwpm0ay.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\sl446u4pu9-bqjiyaj88i.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\tmv2wclpmg-c2jlpeoesf.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\6gct860rig-erw9l3u2r3.gz
|
||||
@@ -885,8 +878,6 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\kq26va
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\gjrhunsew4-76mbc4pefm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\mn3dn5oro4-iag0ou56lh.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\vbwtfewq79-md9yvkcqlf.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\cmx4u86mij-lndxon4b9l.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\b3tztoi1cm-lndxon4b9l.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\qj52mxliu6-z6jo10m0rd.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\19sycpf3d4-65wbz7t8mt.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\f9hzge3k1m-ysqd97eroy.gz
|
||||
@@ -1091,8 +1082,6 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\8f2w23
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\bei5z5w6ky-tjcz0u77k5.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\baolonsbs3-tptq2av103.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\q9hm4ir8wi-lfu7j35m59.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\kzp5jtqdfd-ihokpa64w4.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\po7udqtwl2-iu0eh4ivxb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\staticwebassets.build.json
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\staticwebassets.build.json.cache
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\staticwebassets.development.json
|
||||
@@ -1127,10 +1116,61 @@ C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\yxyyot
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\66hyae12zs-lzotatrep2.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\ebg5gkjd7d-zeqz59uvkx.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\7voc7hmlzb-5tt1rwyygx.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.a2cfufv20d.pdb
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.4hwkikhk8q.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.a2cfufv20d.pdb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.4hwkikhk8q.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\cez1jk5yrk-4hwkikhk8q.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\b9lx0cbjbg-a2cfufv20d.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\xzgxwa2yd7-5hhzlxul06.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\m58axigd6e-cu8qyyjvx6.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\BlazorBootstrap.ym6tnrklwx.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\BlazorBootstrap.ym6tnrklwx.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\BlazorBootstrap.dll
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\BlazorBootstrap.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\yxfdm33bor-63oqyoiiv4.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\refgsao5tb-5vmds449nb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\d5o4a4wkq9-ct0ej5e0q0.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\sismm8xg1l-ezlxc6gzv3.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\q8v6i1uv3e-pisakkcwob.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\36w3eu0hkb-j8zp7bt7w3.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\mfzx4sb2rv-79hai7knhw.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\eojifsclv0-7t9tbfaemk.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\m2wv0pszba-ym6tnrklwx.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Blazored.Typeahead.5g65vcuhxb.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Extensions.Localization.bvn14pws96.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\MudBlazor.845kbj1w9a.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Microsoft.Extensions.Localization.bvn14pws96.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\Blazored.Typeahead.5g65vcuhxb.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\MudBlazor.845kbj1w9a.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\Blazored.Typeahead.dll
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\Microsoft.Extensions.Localization.dll
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\Microsoft.Extensions.Localization.Abstractions.dll
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\MudBlazor.dll
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\Blazored.Typeahead.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\Microsoft.Extensions.Localization.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\Microsoft.Extensions.Localization.Abstractions.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\webcil\MudBlazor.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\tzxjg6is5z-jk5eo7zo4m.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\0wz98yz2xy-tjzqk7tnel.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\9a5c0hw7xq-vy4gn6vj78.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\4x50nu10m9-uv12w7whvw.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\rzn0fbfgqs-5g65vcuhxb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\mn4vfgvxyw-bvn14pws96.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\lmz1wn3azf-o4jp2hcm79.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\stzox4d6il-845kbj1w9a.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\Components\Layout\MainLayout.razor.rz.scp.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\scopedcss\Components\Layout\NavMenu.razor.rz.scp.css
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\cmx4u86mij-jq0bgzcoc4.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\b3tztoi1cm-ob0l47m3ye.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\eb56ryutr6-wfgcz1v7r2.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\9988w5h4ds-804ig5h2xb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\yyex9setpd-oxan0pzjgj.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.r9uf34g1jf.pdb
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.lyqfg82b63.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.lyqfg82b63.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Shared.r9uf34g1jf.pdb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\kzp5jtqdfd-lyqfg82b63.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\po7udqtwl2-r9uf34g1jf.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.ape4q24e07.pdb
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.0dluezm643.wasm
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.ape4q24e07.pdb.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\bin\Debug\net9.0\wwwroot\_framework\OnProfNext.Client.0dluezm643.wasm.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\cez1jk5yrk-0dluezm643.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\b9lx0cbjbg-ape4q24e07.gz
|
||||
C:\DEVQPDC\Proj2\OnProfNext\OnProfNext.Client\obj\Debug\net9.0\compressed\xzgxwa2yd7-n8izp0ydfq.gz
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"mainAssemblyName": "OnProfNext.Client",
|
||||
"resources": {
|
||||
"hash": "sha256-AhHfMRoXU+sbJ6Rea3YPtJWuZ6wr1DB+/6q/AtghVyY=",
|
||||
"hash": "sha256-urElDnrJHnNHhcoIgh4qPQgw0DvL1p3uD2eDB4Wd3+M=",
|
||||
"fingerprinting": {
|
||||
"BlazorBootstrap.ym6tnrklwx.wasm": "BlazorBootstrap.wasm",
|
||||
"Blazored.Typeahead.5g65vcuhxb.wasm": "Blazored.Typeahead.wasm",
|
||||
"Microsoft.AspNetCore.Authorization.z6jo10m0rd.wasm": "Microsoft.AspNetCore.Authorization.wasm",
|
||||
"Microsoft.AspNetCore.Components.65wbz7t8mt.wasm": "Microsoft.AspNetCore.Components.wasm",
|
||||
"Microsoft.AspNetCore.Components.Forms.ysqd97eroy.wasm": "Microsoft.AspNetCore.Components.Forms.wasm",
|
||||
@@ -22,6 +24,8 @@
|
||||
"Microsoft.Extensions.FileProviders.Physical.fwg0p8qiey.wasm": "Microsoft.Extensions.FileProviders.Physical.wasm",
|
||||
"Microsoft.Extensions.FileSystemGlobbing.wpqn02ct4s.wasm": "Microsoft.Extensions.FileSystemGlobbing.wasm",
|
||||
"Microsoft.Extensions.Http.34jr7x6h7z.wasm": "Microsoft.Extensions.Http.wasm",
|
||||
"Microsoft.Extensions.Localization.bvn14pws96.wasm": "Microsoft.Extensions.Localization.wasm",
|
||||
"Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm": "Microsoft.Extensions.Localization.Abstractions.wasm",
|
||||
"Microsoft.Extensions.Logging.2h3t8m6coa.wasm": "Microsoft.Extensions.Logging.wasm",
|
||||
"Microsoft.Extensions.Logging.Abstractions.ni4towxuts.wasm": "Microsoft.Extensions.Logging.Abstractions.wasm",
|
||||
"Microsoft.Extensions.Options.2nlpwp09nn.wasm": "Microsoft.Extensions.Options.wasm",
|
||||
@@ -33,6 +37,7 @@
|
||||
"Microsoft.IdentityModel.Tokens.zeqz59uvkx.wasm": "Microsoft.IdentityModel.Tokens.wasm",
|
||||
"Microsoft.JSInterop.9ydsnriizw.wasm": "Microsoft.JSInterop.wasm",
|
||||
"Microsoft.JSInterop.WebAssembly.v6rnols3v9.wasm": "Microsoft.JSInterop.WebAssembly.wasm",
|
||||
"MudBlazor.845kbj1w9a.wasm": "MudBlazor.wasm",
|
||||
"System.IdentityModel.Tokens.Jwt.5tt1rwyygx.wasm": "System.IdentityModel.Tokens.Jwt.wasm",
|
||||
"Microsoft.CSharp.j3zkownjjr.wasm": "Microsoft.CSharp.wasm",
|
||||
"Microsoft.VisualBasic.Core.qljjwgjnrn.wasm": "Microsoft.VisualBasic.Core.wasm",
|
||||
@@ -210,10 +215,10 @@
|
||||
"icudt_CJK.tjcz0u77k5.dat": "icudt_CJK.dat",
|
||||
"icudt_EFIGS.tptq2av103.dat": "icudt_EFIGS.dat",
|
||||
"icudt_no_CJK.lfu7j35m59.dat": "icudt_no_CJK.dat",
|
||||
"OnProfNext.Shared.ihokpa64w4.wasm": "OnProfNext.Shared.wasm",
|
||||
"OnProfNext.Shared.iu0eh4ivxb.pdb": "OnProfNext.Shared.pdb",
|
||||
"OnProfNext.Client.4hwkikhk8q.wasm": "OnProfNext.Client.wasm",
|
||||
"OnProfNext.Client.a2cfufv20d.pdb": "OnProfNext.Client.pdb"
|
||||
"OnProfNext.Shared.lyqfg82b63.wasm": "OnProfNext.Shared.wasm",
|
||||
"OnProfNext.Shared.r9uf34g1jf.pdb": "OnProfNext.Shared.pdb",
|
||||
"OnProfNext.Client.0dluezm643.wasm": "OnProfNext.Client.wasm",
|
||||
"OnProfNext.Client.ape4q24e07.pdb": "OnProfNext.Client.pdb"
|
||||
},
|
||||
"jsModuleNative": {
|
||||
"dotnet.native.9ih887ebfz.js": "sha256-oS7IRiQoVt9ThQ7Y2UM3XoeY0JqPD02cg9IvRdufn2w="
|
||||
@@ -234,6 +239,8 @@
|
||||
"System.Private.CoreLib.uqnhzdwypx.wasm": "sha256-dmlLyil2xqdBc+0yMfmACcDeIGVefS4QHjRT/9mLdNs="
|
||||
},
|
||||
"assembly": {
|
||||
"BlazorBootstrap.ym6tnrklwx.wasm": "sha256-JvZh7RjGQpT7CC6gfoLZbKPPkhcor/rhKKpkCt/2lfU=",
|
||||
"Blazored.Typeahead.5g65vcuhxb.wasm": "sha256-GwHvrw5VqXbXdYF+BX0dOWgR9mMoIh0SLjRrafirlyY=",
|
||||
"Microsoft.AspNetCore.Authorization.z6jo10m0rd.wasm": "sha256-K3j153B4Qx57/sHT4gOICXyadidNa4qEUflLPz/OgCU=",
|
||||
"Microsoft.AspNetCore.Components.65wbz7t8mt.wasm": "sha256-esbkeXi/0iIJjs+MdmPU6nulNqIzqOw5a4hLgs2f6+U=",
|
||||
"Microsoft.AspNetCore.Components.Forms.ysqd97eroy.wasm": "sha256-8o1e7d2phwhchCrOcBV5r/UklI0sSixpCl8wQkEHNfE=",
|
||||
@@ -253,6 +260,8 @@
|
||||
"Microsoft.Extensions.FileProviders.Physical.fwg0p8qiey.wasm": "sha256-j06UStE6FBwEz3CJbgLfbKKSePh0FaT4PK7wtDoUXs0=",
|
||||
"Microsoft.Extensions.FileSystemGlobbing.wpqn02ct4s.wasm": "sha256-BC/MCU6S9BBMqOrRwZh0plnIpsYyZKyENCmb6p3Acsk=",
|
||||
"Microsoft.Extensions.Http.34jr7x6h7z.wasm": "sha256-fTu6J/dJP8yyhw48HS3g8ZOvSNcIA7ConcInauGbohA=",
|
||||
"Microsoft.Extensions.Localization.bvn14pws96.wasm": "sha256-6UgMJoVZBfDdfzYR0aKVK6BWArxpXC1qiQDDjiXw/L4=",
|
||||
"Microsoft.Extensions.Localization.Abstractions.o4jp2hcm79.wasm": "sha256-GJNjpp2mlMIYboBhzukWw5r2Z24PsB0E9Gj9VoTGKEI=",
|
||||
"Microsoft.Extensions.Logging.2h3t8m6coa.wasm": "sha256-1jYRjcDI2/MnB5Htgj4yUaHr8gA/poI4oLgWUMZYnV0=",
|
||||
"Microsoft.Extensions.Logging.Abstractions.ni4towxuts.wasm": "sha256-H+TpHvK/z4RGb8EfLe1cGb1TwnCKZAmNxt8e3s3CUSM=",
|
||||
"Microsoft.Extensions.Options.2nlpwp09nn.wasm": "sha256-zp3zuBmKVlE6HjY0Br1uj3fY9sU7ET4ITzgpnpmj9V0=",
|
||||
@@ -264,6 +273,7 @@
|
||||
"Microsoft.IdentityModel.Tokens.zeqz59uvkx.wasm": "sha256-hQbBReIl6OvRCOLal9JHAiyQa9Zejqvl/Q03oc0DvyE=",
|
||||
"Microsoft.JSInterop.9ydsnriizw.wasm": "sha256-oZgTa/to3sE2tSzwcZQ0GIX1meeIGAYVE7IoJDL4RkI=",
|
||||
"Microsoft.JSInterop.WebAssembly.v6rnols3v9.wasm": "sha256-Z/XKvzIKcHVmnvT7y1f4/N5zSNqzNAfjsLaBDIyCkYs=",
|
||||
"MudBlazor.845kbj1w9a.wasm": "sha256-6H3anvXkkN9V1Gxb+Ul/S1lH5SsXdXFbL0IXDHFkVlY=",
|
||||
"System.IdentityModel.Tokens.Jwt.5tt1rwyygx.wasm": "sha256-15e9xXAMloW+NXhmC4dPppM4zlorit69Q+n8h3ToBSI=",
|
||||
"Microsoft.CSharp.j3zkownjjr.wasm": "sha256-r7YS8Hp01zUR3LoH5JsS7IrucOta+FnV199bCLii7Pk=",
|
||||
"Microsoft.VisualBasic.Core.qljjwgjnrn.wasm": "sha256-/jlp74GLHWhrCfjAmWlVClO68H3wIk+kVx9A/gjByls=",
|
||||
@@ -432,12 +442,12 @@
|
||||
"WindowsBase.vy2l5u79y6.wasm": "sha256-ufB9Mo5joMyUs3DzXWWBFFIZNEVrt6h9N5stYB6Oln4=",
|
||||
"mscorlib.xd6mv31d55.wasm": "sha256-1YSLR2eZt3ceALFV//vZUF2AloxVil3VlrW1zZYPSEI=",
|
||||
"netstandard.kaml52uspo.wasm": "sha256-HLEwBpLfzKw2/zGSVzHzFJxznCkt/WIjahrziiMrOpA=",
|
||||
"OnProfNext.Shared.ihokpa64w4.wasm": "sha256-9jmdZcR2jSUk95bksqs7xpGrEf4rB5xQhmsoBKS65Wg=",
|
||||
"OnProfNext.Client.4hwkikhk8q.wasm": "sha256-mOwRgG56/276TVQlsTTlr3yGVAcOed54r2GKKYiDzD8="
|
||||
"OnProfNext.Shared.lyqfg82b63.wasm": "sha256-w7kYJP/DLlO8NXzgUXym1hiG2ch5+jRuO/UZ6krRm6w=",
|
||||
"OnProfNext.Client.0dluezm643.wasm": "sha256-pOEBoGoioxlzoi9tDgJmWxFEJw9FAZpIlohDGRMcHvw="
|
||||
},
|
||||
"pdb": {
|
||||
"OnProfNext.Shared.iu0eh4ivxb.pdb": "sha256-yhx+tHTfofR2P3NL+7DCQla+3z5jDECL3xhAcxOaHl8=",
|
||||
"OnProfNext.Client.a2cfufv20d.pdb": "sha256-LitRcN0GHAOQWBGqsyqjAsm22TSf9ICv+CfY2/9ulAI="
|
||||
"OnProfNext.Shared.r9uf34g1jf.pdb": "sha256-AQbfy8ggW02znMrieOv1c4vomUo5cXk/ptky3fB99YI=",
|
||||
"OnProfNext.Client.ape4q24e07.pdb": "sha256-knq9IhCJxfvepTeExvxDRJhO5nGuddjspkNtCOcBkIY="
|
||||
}
|
||||
},
|
||||
"cacheBootResources": true,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
{"GlobalPropertiesHash":"mM8eeq7khgiV1Ho7QUmOpk+VtYcA7aET/3LQ1YVdmDk=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["C0eOV9gOfsDqwL4SXmPo6JNLJCydTRLhkcoGopWE9zQ=","vH/H9umpzRku3bgc\u002BiW4S4uDtfRsbDxcDhLs2PsS30Q=","7WZ82wMbbKcJw5Bzbb6647eKVFT/bZswI1Tk5t/ft5c=","gs5UlNXRGgbBy\u002BFuOsUP\u002Bb5dhLSdZmWvGquuF5Vx0Sk=","DZJCRz9YgqDdyZ\u002B/alouUKBy2KmMsXUiWCxebbKZcLY=","vWEBwblz5Jyt6V3p5EhyGwNxk3wMO63rfUkzfFOe3Co=","C9OcPNxT/zZbgwoL1WFZpq/GpBvLVPp8hPakIqiapo4=","Kx8ACKSK3MtMAbYi7KCFurKiYppxi7vo\u002BEhh02NZdzQ=","yxPUUzlxTy4BFltCWE3KIA\u002BWyQYUg/IIzcE3ijpMcYA=","ImICJyEJwrMtMlwpdR3TUm1zynu8xRKgqQt/SKRWgb0=","TjgCDOh\u002B6hXrsF/SShk3ow5T50/kMKkKCND23t3bb\u002BE=","e9PcF/sfWnqLkh3xeQ7K0Y4jCrIxSFd3uA1X1PFIM5I=","Btp7jyWETg/2eqdAkcMf9vwDjYzaNjWz3CqRvFY2M/Y=","ceaaFJWn2DLR\u002BtltiUns0zSUqZdF95jtCiE8BsA8jCk=","HcuvE7OIR66cL63FjKUiVO27/7jyrWAkalbBFAty5\u002BY=","DLbhHN0wNZ5TZTU/daLOgA6HIQdIppdZ\u002B3ix\u002Bs0q00A=","h/xl0jd8/ccKraqSbuHrqHDKWlgX6yEhialHDeLi9Iw=","IWYbnI783m87kixei3nIgUzSgOSdvDKjZB7TBy1gZnw=","s580H7QKmm/8JfqJ1qQutyar6VmBZ2AS0yK3JBkUhEU=","cjzijXWkKx5xmzo7UM2\u002B\u002BlKHuiTCUBC6DbZKzZzvXRc=","y/HHWIq4FmFCjw1i5XGnkQFK9XF2josRhuQY2UApulw=","JsDoy0qI9Uyk0tJTn0NDNkmt4UmamBvAatx4XlfUC7o=","CvbWU7Giprnv46eIMwfS2bczbDe733bXEYIdjr9jRnc=","Q2XlrbHGFatJOngyPfc6Zcrv1B67MTXKJ\u002BIDqO25R00=","c814YcgxmsuSE3XnK1Nq1Hpb/DSHdHv707R8\u002BsMQUbw=","Tx7xdcxtqfZTa7P9vSMOGgAjrEUDs6YGz/BCDc9zoGs=","qhVXZuy2nCiZw2Uis/Ugu\u002BiclH4afrFxFZCNa2yxE74=","OSAu0TIFhkdeb0xVLS6et8a4aUHkzeUWk3v3s\u002BUn/Y8=","gQojZbGh9zdA6sHRPQKxtDLqvqsJtMNWSvtPxM60tlk=","ue76wb7ZOtUAF2M1UT3LzQtfATbywtmhro/\u002BDVQFo2E=","ujshobx1Okba2\u002BKCptByJRdUhAjHCnL7OEilWHSxvSE=","IMLMtCoq94G/iom6Kc9QnMjl26QBzo9A\u002BUpe\u002Bir5hSk=","cKIyhiSlhxBTpm0tfQp0N73HmTJ0PSk6OasdMHHU6hg=","5/pQTkPDIDKVOIdLIr8K2pqUMYjedXEDzrx/8i2FyMc=","ie4elz0/Yt0Jor8ZOASn7uqtUMQVIIi7iyxpmc\u002BP/3A=","/eDlK\u002BJ5ECzHYnnwNfs1ll7OzscxHc/T9AXptg3xTII=","iZtB7IwVOScbKME8XNDUHe8/LADtOuBuD5iUzZ\u002BTBHA=","VI7hpNtzA0lQFbtSBh2M5HmTFjxD4uLPevcNJtBDECY=","vpPBvnXuysK0e8FBbSO7k6I35HOVZLmZfMhVxlKPzck=","hdgfzdMO3XxPwCGNKDabyl/9YRagIr9KXozaMve1DE4=","4UP6pofGTsyh1E5XO2QVGfORoUAttdjUWvf1A4Mgngw=","AuV7BOj9roSnoQn4CCZRgJiQ9aP\u002Buuc3FxUaAtL4FUk=","3KIGpeODnLLCBrAStJV1hHEo7FwY/hgl7zW1wNeg/Wc=","a2NEK0jnyneLb7plUPbXxhY8oQ9LD9Lc35UnzZUXwJI=","2DvTDD9FORsb164IPm6/PKUGfxUsYAOheM6lMXeQcuQ=","B2ua8h4cGI1Vv8qhyD7sFVXpbxEgmYZbecw9dY4/rFA=","sp9HgH8YqRbHdraJhNz5JJIDCLSscO457uul374ES4I=","wMHpeMWv1hOAkS9kqsiqEALVMDdWAsC3p85glRB/FqI=","/KUhUbxyo/3Nrk2MhF57PAEu8wbud9Cg8Bp1MbxsxoA="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
{"GlobalPropertiesHash":"mM8eeq7khgiV1Ho7QUmOpk+VtYcA7aET/3LQ1YVdmDk=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["C0eOV9gOfsDqwL4SXmPo6JNLJCydTRLhkcoGopWE9zQ=","vH/H9umpzRku3bgc\u002BiW4S4uDtfRsbDxcDhLs2PsS30Q=","7WZ82wMbbKcJw5Bzbb6647eKVFT/bZswI1Tk5t/ft5c=","STdNBMOgbym9plIqVfeTQ5bMv4lCD2PqmCxFkhEIveY=","1e6daLPfiNZ0xKyqXPZvlwnXNr5eNjSY9c8Z3RnpvOs=","usnoV0rd/ueHPT6Pi8sOt97KMDrhrYfd19DwaKRbZLY=","DZJCRz9YgqDdyZ\u002B/alouUKBy2KmMsXUiWCxebbKZcLY=","vWEBwblz5Jyt6V3p5EhyGwNxk3wMO63rfUkzfFOe3Co=","C9OcPNxT/zZbgwoL1WFZpq/GpBvLVPp8hPakIqiapo4=","Kx8ACKSK3MtMAbYi7KCFurKiYppxi7vo\u002BEhh02NZdzQ=","yxPUUzlxTy4BFltCWE3KIA\u002BWyQYUg/IIzcE3ijpMcYA=","ImICJyEJwrMtMlwpdR3TUm1zynu8xRKgqQt/SKRWgb0=","TjgCDOh\u002B6hXrsF/SShk3ow5T50/kMKkKCND23t3bb\u002BE=","e9PcF/sfWnqLkh3xeQ7K0Y4jCrIxSFd3uA1X1PFIM5I=","Btp7jyWETg/2eqdAkcMf9vwDjYzaNjWz3CqRvFY2M/Y=","ceaaFJWn2DLR\u002BtltiUns0zSUqZdF95jtCiE8BsA8jCk=","HcuvE7OIR66cL63FjKUiVO27/7jyrWAkalbBFAty5\u002BY=","DLbhHN0wNZ5TZTU/daLOgA6HIQdIppdZ\u002B3ix\u002Bs0q00A=","h/xl0jd8/ccKraqSbuHrqHDKWlgX6yEhialHDeLi9Iw=","IWYbnI783m87kixei3nIgUzSgOSdvDKjZB7TBy1gZnw=","s580H7QKmm/8JfqJ1qQutyar6VmBZ2AS0yK3JBkUhEU=","cjzijXWkKx5xmzo7UM2\u002B\u002BlKHuiTCUBC6DbZKzZzvXRc=","y/HHWIq4FmFCjw1i5XGnkQFK9XF2josRhuQY2UApulw=","JsDoy0qI9Uyk0tJTn0NDNkmt4UmamBvAatx4XlfUC7o=","CvbWU7Giprnv46eIMwfS2bczbDe733bXEYIdjr9jRnc=","Q2XlrbHGFatJOngyPfc6Zcrv1B67MTXKJ\u002BIDqO25R00=","c814YcgxmsuSE3XnK1Nq1Hpb/DSHdHv707R8\u002BsMQUbw=","Tx7xdcxtqfZTa7P9vSMOGgAjrEUDs6YGz/BCDc9zoGs=","qhVXZuy2nCiZw2Uis/Ugu\u002BiclH4afrFxFZCNa2yxE74=","OSAu0TIFhkdeb0xVLS6et8a4aUHkzeUWk3v3s\u002BUn/Y8=","gQojZbGh9zdA6sHRPQKxtDLqvqsJtMNWSvtPxM60tlk=","ue76wb7ZOtUAF2M1UT3LzQtfATbywtmhro/\u002BDVQFo2E=","ujshobx1Okba2\u002BKCptByJRdUhAjHCnL7OEilWHSxvSE=","IMLMtCoq94G/iom6Kc9QnMjl26QBzo9A\u002BUpe\u002Bir5hSk=","cKIyhiSlhxBTpm0tfQp0N73HmTJ0PSk6OasdMHHU6hg=","5/pQTkPDIDKVOIdLIr8K2pqUMYjedXEDzrx/8i2FyMc=","ie4elz0/Yt0Jor8ZOASn7uqtUMQVIIi7iyxpmc\u002BP/3A=","/eDlK\u002BJ5ECzHYnnwNfs1ll7OzscxHc/T9AXptg3xTII=","iZtB7IwVOScbKME8XNDUHe8/LADtOuBuD5iUzZ\u002BTBHA=","VI7hpNtzA0lQFbtSBh2M5HmTFjxD4uLPevcNJtBDECY=","vpPBvnXuysK0e8FBbSO7k6I35HOVZLmZfMhVxlKPzck=","hdgfzdMO3XxPwCGNKDabyl/9YRagIr9KXozaMve1DE4=","4UP6pofGTsyh1E5XO2QVGfORoUAttdjUWvf1A4Mgngw=","AuV7BOj9roSnoQn4CCZRgJiQ9aP\u002Buuc3FxUaAtL4FUk=","3KIGpeODnLLCBrAStJV1hHEo7FwY/hgl7zW1wNeg/Wc=","a2NEK0jnyneLb7plUPbXxhY8oQ9LD9Lc35UnzZUXwJI=","2DvTDD9FORsb164IPm6/PKUGfxUsYAOheM6lMXeQcuQ=","B2ua8h4cGI1Vv8qhyD7sFVXpbxEgmYZbecw9dY4/rFA=","sp9HgH8YqRbHdraJhNz5JJIDCLSscO457uul374ES4I=","wMHpeMWv1hOAkS9kqsiqEALVMDdWAsC3p85glRB/FqI=","/KUhUbxyo/3Nrk2MhF57PAEu8wbud9Cg8Bp1MbxsxoA=","Xz7qwBV8mKNupyCnNDp6b\u002BbbCDqQIuiz/hLvV6WeHmw="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
@@ -1 +1 @@
|
||||
{"GlobalPropertiesHash":"HQrK/c2YdUjsysKaYGSoybSEyDguxRws1HNGGkzNr68=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["wMWPZGfJtGeKkPw89r\u002BuOnYPKqx9sEcbqVKHPoYpTbg=","puDy0dzI5QvIsFKrWO6hrkZZcZnbTNSWaBqIyd5vS9E=","bNNyXhlBr3jQbNMkCOe8xcZdSkB7XoUpSNnehjUQlxA=","37z8gtWOcvhLoatyOEC4xT9L\u002B\u002BcYD9aFwnhyNPk\u002BY50=","HwFAFTSvCp26cdo1kx5ecfdA/\u002BXAkxgIq5fu6m8nIA0=","SHr5eqYzJxZNE5/PlzkQfEBMjakT5PcfDexn2iCZjyI=","rovhGZeu5lwGm9t06s1govZ9ZDUAyhGquT/zYxV9EMA=","n90/VXHLh5f/b\u002BenXJx5LvC2wVhxMsmGXsKTtLP1rGE=","M2F\u002BdirWJXRBR8xTEBUsBQq5ZBlMsGLrQuDu2Xoflo8=","QQfqB2d2lyRaoRCXHlFI1qDyAV8sb3YBC6sabNep4T8=","sCLTILGPMYZmM4Cq6VeXFDRKEU4zUeqi0zh34Zyl1\u002Bg=","KPtl\u002BIcYzJanv3TdGEjfu/58zjjSte7onQyK1z2UpSs=","UOD2algC0YxakRPAo\u002BdHBxw2nz\u002Bf3inCW8K/2sYv4hk=","2a4AqN7uSgiGGPijKrbGYp3zTiFaYviYMC4je9251Gg=","S1JDFpdG6oeT7HQg1q6p3OLFEq6MSuMk9DrbZZf85U0=","FcAp\u002BB\u002BMdtU4Jqt1qd8ZU0XGQCyIO1UaSwwwKyFcuRI=","KicT\u002BJLs/7POfopY2e6knubWrx25hvaxJ1zNKezbz9Y=","xL7/ma/CChAYqsGMi59uK6yIstcESmcirrh1RzpvMEw=","dnRdnpQc61NJ56ASQrUFLZkDTGNM0KNu\u002BtR3NDDE34A=","Grv4g6vNrL73s12N910v2w8Bfa5b3fgn3knYM4SPbTo=","biFvXP\u002Bh3VCB//g0WfQTKnZXpYAq5NNK8FOtNrSlluc=","JbXwwQIUN/GSNZKsNiMjv4ebWU2SviyhnVdlqdpCpmg=","nz\u002BZycBj/r0qxn/lLFHWJ8J6wFGlMsV/1mlRmZUo/4I=","aQycidQhGUbn4VCw/EJfF5iFRrN1xIgwHoIJjbOVZps=","qgUM6A/uKHiUkWc1/Ln9WXX1SAX8JoRvV74Ma6ZFmng=","iKkyE9MQsJaeQ\u002BwNmzP/yqlnE0DgDcGv\u002BmjdLoDxrRo=","uTVPNnHOvOCd/yTop9dVCWOMKn4tFTh\u002B\u002BvDB36ISZPs=","mfZpFq\u002BvCmodLP7zO9b0YsEWC/OcDyBoxhYqFD56fFk=","YWOs7JAKIsqIOVQG0w8okz7vUzx0CLjYsgFSeEvd8dY=","mhyeOUDBL5xq9Rlm12fZKRW\u002BewVdAloH3HpGO\u002B7GqeM=","dwYRUoBX6sjNOpgOukCSK6FYozMx5nQPuanV9jF0pug=","ozbr8RdoOPcWGZFTphPnXiPHqUXsUX48rNHT9DPxQQQ=","zNy/\u002Beenwd4rP3KmszLj/P9L4RfeJcIG51tiUMGKZUI=","JqnKg76tBTEDi4ygNmSbT8906THHzJuCJTZbK0K6Oe8=","JcACn0ymzW4JpJ5CgWCxT1NdaSHZxnxp\u002BAiJJM/kC6k=","k71DltJbtRqVXA3rGahMZgUq0B9sodbz2R43hsUcD1I=","aouiJcQV84ezpO9Cwpg\u002BId9XaiZVlGhgxGvxD6PaAGM=","b/Jk0Mr/B4BWzcJa6nZHbXC\u002BzU0I1a30M2AcH5fdjKY=","aK2OxKAVYxUxIEDqZnknDAW9qelpdYKLvlGPA3\u002B5OIE=","E4QT\u002B435PZZ\u002BRTzgvECRD1bOtElnkqeWREaoDzYrMdc=","FBxckgU98gb7vgTEM5V4Q\u002BEWV1Ztcp3Bssbx92n1keA=","gv3iSaKsj0CmcWFWMhUhYcA7l4\u002BnVTp1Jj85xAmbA8E=","mRQfJZfYrp6FVuPsI1970i6\u002Bg1zC7cMX1qaaf5X\u002BoCQ=","5BtfX2AAiOmDTGL34icHscY4eUpH3nbfHN/rb4e62rY=","6rueZEktdPrxLkoO8WfJXCckClsIUsg6sBnN1LTessM=","SZJz\u002B71xnWFevxgzVgPPCqih4KkGwhQhHvoh6BgiWFc=","u2aOXUOrTOrwIgVam12G9HzaU7QEbOQG66Q7IDjlMYY=","8DlE0XjBA/lhOGHaXiPZ5cQswwpo6NEUaebI9my2F4s=","1ldijbG/u6m3Wwq0OUgI3unhWdjWhqvOD\u002BI1PauI9GI=","ZONDes5iC8ZsJjdvuMpkRHPDt02QpRfhanA4J/V0CjM=","cgYmjPinNC2bwmQ3uQMAx1qsvVMzZaE99BFHgUlYV\u002Bs=","htYyraM18aOUKQ1Tqg2LWYBgfZen3TdcXku9aKv7q0M=","9hC0wthPXB9k40lIbDKdWYtaw2axqBb91\u002BojeVYtTEY=","TqYSD0yZOIvmoqS7yqGoF3gOa8r34ClAk7\u002BtPdl9Xw0=","7NztDGxnb1Cz0opIKXfkgSzz2h0LyUFOT7wQNrMageQ=","kEPWaTEgcSvuVRYmq9OKVA\u002BlpOmTKkV3fpY5ByqOqFk=","4Z6NbZCHvoNJmFB0UDo9VAbGMti5FbYlOZgrz6CDFPY=","Ncs4XlqbjiOXHFOWs\u002BlDFNyDIeXvLTQrBH/4oQGZuIc=","P1JuwJ4/BytYPLxV\u002BhrJ5\u002BvbS8NeGlaBLiincn/y6m0=","2At\u002BRo2tqG3Zuc8oFrmuJ2h4FtOISqCbue1\u002B\u002B1jDpYw=","A5FwpPfGidgr2NgPt1ofZxg2nxXAcuozNEFd9BE7nsk="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
{"GlobalPropertiesHash":"HQrK/c2YdUjsysKaYGSoybSEyDguxRws1HNGGkzNr68=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["wMWPZGfJtGeKkPw89r\u002BuOnYPKqx9sEcbqVKHPoYpTbg=","puDy0dzI5QvIsFKrWO6hrkZZcZnbTNSWaBqIyd5vS9E=","bNNyXhlBr3jQbNMkCOe8xcZdSkB7XoUpSNnehjUQlxA=","e00HwqbAs5\u002BQP/isIc/1wdQEkEVLrYL4mZkRFgflGxc=","/pGZ5Ne8ls0AltJgWOhL5Yc9\u002BzFbkQwUFLLaEuzhySM=","TDAOXjznXPMZY6da8pxBF7r\u002BgikX9nuv6RoxA3r\u002BE1M=","PAgoRnO8hSCWHTmmLUrKojqhvOGsbhB9PUCqEOnuYrg=","HwFAFTSvCp26cdo1kx5ecfdA/\u002BXAkxgIq5fu6m8nIA0=","SHr5eqYzJxZNE5/PlzkQfEBMjakT5PcfDexn2iCZjyI=","rovhGZeu5lwGm9t06s1govZ9ZDUAyhGquT/zYxV9EMA=","n90/VXHLh5f/b\u002BenXJx5LvC2wVhxMsmGXsKTtLP1rGE=","M2F\u002BdirWJXRBR8xTEBUsBQq5ZBlMsGLrQuDu2Xoflo8=","QQfqB2d2lyRaoRCXHlFI1qDyAV8sb3YBC6sabNep4T8=","sCLTILGPMYZmM4Cq6VeXFDRKEU4zUeqi0zh34Zyl1\u002Bg=","KPtl\u002BIcYzJanv3TdGEjfu/58zjjSte7onQyK1z2UpSs=","UOD2algC0YxakRPAo\u002BdHBxw2nz\u002Bf3inCW8K/2sYv4hk=","2a4AqN7uSgiGGPijKrbGYp3zTiFaYviYMC4je9251Gg=","S1JDFpdG6oeT7HQg1q6p3OLFEq6MSuMk9DrbZZf85U0=","FcAp\u002BB\u002BMdtU4Jqt1qd8ZU0XGQCyIO1UaSwwwKyFcuRI=","KicT\u002BJLs/7POfopY2e6knubWrx25hvaxJ1zNKezbz9Y=","xL7/ma/CChAYqsGMi59uK6yIstcESmcirrh1RzpvMEw=","dnRdnpQc61NJ56ASQrUFLZkDTGNM0KNu\u002BtR3NDDE34A=","Grv4g6vNrL73s12N910v2w8Bfa5b3fgn3knYM4SPbTo=","biFvXP\u002Bh3VCB//g0WfQTKnZXpYAq5NNK8FOtNrSlluc=","JbXwwQIUN/GSNZKsNiMjv4ebWU2SviyhnVdlqdpCpmg=","nz\u002BZycBj/r0qxn/lLFHWJ8J6wFGlMsV/1mlRmZUo/4I=","aQycidQhGUbn4VCw/EJfF5iFRrN1xIgwHoIJjbOVZps=","qgUM6A/uKHiUkWc1/Ln9WXX1SAX8JoRvV74Ma6ZFmng=","iKkyE9MQsJaeQ\u002BwNmzP/yqlnE0DgDcGv\u002BmjdLoDxrRo=","uTVPNnHOvOCd/yTop9dVCWOMKn4tFTh\u002B\u002BvDB36ISZPs=","mfZpFq\u002BvCmodLP7zO9b0YsEWC/OcDyBoxhYqFD56fFk=","YWOs7JAKIsqIOVQG0w8okz7vUzx0CLjYsgFSeEvd8dY=","mhyeOUDBL5xq9Rlm12fZKRW\u002BewVdAloH3HpGO\u002B7GqeM=","dwYRUoBX6sjNOpgOukCSK6FYozMx5nQPuanV9jF0pug=","ozbr8RdoOPcWGZFTphPnXiPHqUXsUX48rNHT9DPxQQQ=","zNy/\u002Beenwd4rP3KmszLj/P9L4RfeJcIG51tiUMGKZUI=","JqnKg76tBTEDi4ygNmSbT8906THHzJuCJTZbK0K6Oe8=","JcACn0ymzW4JpJ5CgWCxT1NdaSHZxnxp\u002BAiJJM/kC6k=","k71DltJbtRqVXA3rGahMZgUq0B9sodbz2R43hsUcD1I=","aouiJcQV84ezpO9Cwpg\u002BId9XaiZVlGhgxGvxD6PaAGM=","b/Jk0Mr/B4BWzcJa6nZHbXC\u002BzU0I1a30M2AcH5fdjKY=","aK2OxKAVYxUxIEDqZnknDAW9qelpdYKLvlGPA3\u002B5OIE=","E4QT\u002B435PZZ\u002BRTzgvECRD1bOtElnkqeWREaoDzYrMdc=","FBxckgU98gb7vgTEM5V4Q\u002BEWV1Ztcp3Bssbx92n1keA=","gv3iSaKsj0CmcWFWMhUhYcA7l4\u002BnVTp1Jj85xAmbA8E=","mRQfJZfYrp6FVuPsI1970i6\u002Bg1zC7cMX1qaaf5X\u002BoCQ=","5BtfX2AAiOmDTGL34icHscY4eUpH3nbfHN/rb4e62rY=","6rueZEktdPrxLkoO8WfJXCckClsIUsg6sBnN1LTessM=","SZJz\u002B71xnWFevxgzVgPPCqih4KkGwhQhHvoh6BgiWFc=","u2aOXUOrTOrwIgVam12G9HzaU7QEbOQG66Q7IDjlMYY=","8DlE0XjBA/lhOGHaXiPZ5cQswwpo6NEUaebI9my2F4s=","1ldijbG/u6m3Wwq0OUgI3unhWdjWhqvOD\u002BI1PauI9GI=","WtqR0aLtM7t6m3NDyJiTfyz81jhBwyuQkg/iDou5f/k=","aNqGJzJ5xa0dNxSytzanVzqK6xNl85ZkIZfdb\u002BKhxHY=","TpcHV4OB3FaN8hILgTJGBWj6cGx2APNuu6cH90cA2Yw=","y2O\u002BMtvYW\u002BJsiXwnsSGokrtLoPU1BZKq/Rs6jBLWkBA=","XfkTfnoOOODr5Ke\u002BIvlGksb7y1tdjO9D3cio6nfgb6o=","wcROe0zOlvSplfU1neaBc6O9UQx0shY6TJh9t2ZSBYs=","10qLnXFiRep12dfNyKPtD4BUjDi86nt7iUeaDRzdFFg=","Aq6Wb82cwzIR34t\u002BKjNx2Bsbl4xPKot/OiCPUr8NcaA=","sbScjs7uLbfBbWbJKERtvGeL8se13w0V5s0ufS/zDaQ=","9hC0wthPXB9k40lIbDKdWYtaw2axqBb91\u002BojeVYtTEY=","oHrJ\u002Blbd6RhXKDeATc8FabZLEDUjbHWnd18rZBRbNBE=","qOlED1ak4sYSTrFn1g6Y7mnsz3UFQEQ/RV3qKJGx0DQ=","bkU1JrXkWH3R/7pZTq912KiH0qHTMuWrKp6\u002B3V8nWE0=","HCsDlEON4uTuZHQ/mLhoZSnOhDE/0YmD0\u002BPzbGk55jk=","DIlQgc8O3Rampq4\u002BuAU34qvAhOQ76ih6rEWZRuXbpGs=","87pLnLY3BRAM5qVJkJZ6NFQjQse85QaOsaRqbVei3f8=","gb5K/PglhYNjQ6udVditV5mmWe8pBL0bkbfqmDZJR3Q=","c//884XNSMx2fHCDDouqzztU4ZLBdyPK5IazFjEu3xg=","A5FwpPfGidgr2NgPt1ofZxg2nxXAcuozNEFd9BE7nsk="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
@@ -1 +1 @@
|
||||
{"GlobalPropertiesHash":"Q5kcht8XOSaXwErDHawVS9gd2nNuRy7EEG55Mop5u7E=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["wMWPZGfJtGeKkPw89r\u002BuOnYPKqx9sEcbqVKHPoYpTbg=","puDy0dzI5QvIsFKrWO6hrkZZcZnbTNSWaBqIyd5vS9E=","bNNyXhlBr3jQbNMkCOe8xcZdSkB7XoUpSNnehjUQlxA=","37z8gtWOcvhLoatyOEC4xT9L\u002B\u002BcYD9aFwnhyNPk\u002BY50=","HwFAFTSvCp26cdo1kx5ecfdA/\u002BXAkxgIq5fu6m8nIA0=","SHr5eqYzJxZNE5/PlzkQfEBMjakT5PcfDexn2iCZjyI=","rovhGZeu5lwGm9t06s1govZ9ZDUAyhGquT/zYxV9EMA=","n90/VXHLh5f/b\u002BenXJx5LvC2wVhxMsmGXsKTtLP1rGE=","M2F\u002BdirWJXRBR8xTEBUsBQq5ZBlMsGLrQuDu2Xoflo8=","QQfqB2d2lyRaoRCXHlFI1qDyAV8sb3YBC6sabNep4T8=","sCLTILGPMYZmM4Cq6VeXFDRKEU4zUeqi0zh34Zyl1\u002Bg=","KPtl\u002BIcYzJanv3TdGEjfu/58zjjSte7onQyK1z2UpSs=","UOD2algC0YxakRPAo\u002BdHBxw2nz\u002Bf3inCW8K/2sYv4hk=","2a4AqN7uSgiGGPijKrbGYp3zTiFaYviYMC4je9251Gg=","S1JDFpdG6oeT7HQg1q6p3OLFEq6MSuMk9DrbZZf85U0=","FcAp\u002BB\u002BMdtU4Jqt1qd8ZU0XGQCyIO1UaSwwwKyFcuRI=","KicT\u002BJLs/7POfopY2e6knubWrx25hvaxJ1zNKezbz9Y=","xL7/ma/CChAYqsGMi59uK6yIstcESmcirrh1RzpvMEw=","dnRdnpQc61NJ56ASQrUFLZkDTGNM0KNu\u002BtR3NDDE34A=","Grv4g6vNrL73s12N910v2w8Bfa5b3fgn3knYM4SPbTo=","biFvXP\u002Bh3VCB//g0WfQTKnZXpYAq5NNK8FOtNrSlluc=","JbXwwQIUN/GSNZKsNiMjv4ebWU2SviyhnVdlqdpCpmg=","nz\u002BZycBj/r0qxn/lLFHWJ8J6wFGlMsV/1mlRmZUo/4I=","aQycidQhGUbn4VCw/EJfF5iFRrN1xIgwHoIJjbOVZps=","qgUM6A/uKHiUkWc1/Ln9WXX1SAX8JoRvV74Ma6ZFmng=","iKkyE9MQsJaeQ\u002BwNmzP/yqlnE0DgDcGv\u002BmjdLoDxrRo=","uTVPNnHOvOCd/yTop9dVCWOMKn4tFTh\u002B\u002BvDB36ISZPs=","mfZpFq\u002BvCmodLP7zO9b0YsEWC/OcDyBoxhYqFD56fFk=","YWOs7JAKIsqIOVQG0w8okz7vUzx0CLjYsgFSeEvd8dY=","mhyeOUDBL5xq9Rlm12fZKRW\u002BewVdAloH3HpGO\u002B7GqeM=","dwYRUoBX6sjNOpgOukCSK6FYozMx5nQPuanV9jF0pug=","ozbr8RdoOPcWGZFTphPnXiPHqUXsUX48rNHT9DPxQQQ=","zNy/\u002Beenwd4rP3KmszLj/P9L4RfeJcIG51tiUMGKZUI=","JqnKg76tBTEDi4ygNmSbT8906THHzJuCJTZbK0K6Oe8=","JcACn0ymzW4JpJ5CgWCxT1NdaSHZxnxp\u002BAiJJM/kC6k=","k71DltJbtRqVXA3rGahMZgUq0B9sodbz2R43hsUcD1I=","aouiJcQV84ezpO9Cwpg\u002BId9XaiZVlGhgxGvxD6PaAGM=","b/Jk0Mr/B4BWzcJa6nZHbXC\u002BzU0I1a30M2AcH5fdjKY=","aK2OxKAVYxUxIEDqZnknDAW9qelpdYKLvlGPA3\u002B5OIE=","E4QT\u002B435PZZ\u002BRTzgvECRD1bOtElnkqeWREaoDzYrMdc=","FBxckgU98gb7vgTEM5V4Q\u002BEWV1Ztcp3Bssbx92n1keA=","gv3iSaKsj0CmcWFWMhUhYcA7l4\u002BnVTp1Jj85xAmbA8E=","mRQfJZfYrp6FVuPsI1970i6\u002Bg1zC7cMX1qaaf5X\u002BoCQ=","5BtfX2AAiOmDTGL34icHscY4eUpH3nbfHN/rb4e62rY=","6rueZEktdPrxLkoO8WfJXCckClsIUsg6sBnN1LTessM=","SZJz\u002B71xnWFevxgzVgPPCqih4KkGwhQhHvoh6BgiWFc=","u2aOXUOrTOrwIgVam12G9HzaU7QEbOQG66Q7IDjlMYY=","8DlE0XjBA/lhOGHaXiPZ5cQswwpo6NEUaebI9my2F4s=","1ldijbG/u6m3Wwq0OUgI3unhWdjWhqvOD\u002BI1PauI9GI=","ZONDes5iC8ZsJjdvuMpkRHPDt02QpRfhanA4J/V0CjM=","cgYmjPinNC2bwmQ3uQMAx1qsvVMzZaE99BFHgUlYV\u002Bs=","htYyraM18aOUKQ1Tqg2LWYBgfZen3TdcXku9aKv7q0M=","9hC0wthPXB9k40lIbDKdWYtaw2axqBb91\u002BojeVYtTEY=","TqYSD0yZOIvmoqS7yqGoF3gOa8r34ClAk7\u002BtPdl9Xw0=","7NztDGxnb1Cz0opIKXfkgSzz2h0LyUFOT7wQNrMageQ=","kEPWaTEgcSvuVRYmq9OKVA\u002BlpOmTKkV3fpY5ByqOqFk=","4Z6NbZCHvoNJmFB0UDo9VAbGMti5FbYlOZgrz6CDFPY=","Ncs4XlqbjiOXHFOWs\u002BlDFNyDIeXvLTQrBH/4oQGZuIc=","P1JuwJ4/BytYPLxV\u002BhrJ5\u002BvbS8NeGlaBLiincn/y6m0=","2At\u002BRo2tqG3Zuc8oFrmuJ2h4FtOISqCbue1\u002B\u002B1jDpYw=","A5FwpPfGidgr2NgPt1ofZxg2nxXAcuozNEFd9BE7nsk="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
{"GlobalPropertiesHash":"Q5kcht8XOSaXwErDHawVS9gd2nNuRy7EEG55Mop5u7E=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["wMWPZGfJtGeKkPw89r\u002BuOnYPKqx9sEcbqVKHPoYpTbg=","puDy0dzI5QvIsFKrWO6hrkZZcZnbTNSWaBqIyd5vS9E=","bNNyXhlBr3jQbNMkCOe8xcZdSkB7XoUpSNnehjUQlxA=","e00HwqbAs5\u002BQP/isIc/1wdQEkEVLrYL4mZkRFgflGxc=","/pGZ5Ne8ls0AltJgWOhL5Yc9\u002BzFbkQwUFLLaEuzhySM=","TDAOXjznXPMZY6da8pxBF7r\u002BgikX9nuv6RoxA3r\u002BE1M=","PAgoRnO8hSCWHTmmLUrKojqhvOGsbhB9PUCqEOnuYrg=","HwFAFTSvCp26cdo1kx5ecfdA/\u002BXAkxgIq5fu6m8nIA0=","SHr5eqYzJxZNE5/PlzkQfEBMjakT5PcfDexn2iCZjyI=","rovhGZeu5lwGm9t06s1govZ9ZDUAyhGquT/zYxV9EMA=","n90/VXHLh5f/b\u002BenXJx5LvC2wVhxMsmGXsKTtLP1rGE=","M2F\u002BdirWJXRBR8xTEBUsBQq5ZBlMsGLrQuDu2Xoflo8=","QQfqB2d2lyRaoRCXHlFI1qDyAV8sb3YBC6sabNep4T8=","sCLTILGPMYZmM4Cq6VeXFDRKEU4zUeqi0zh34Zyl1\u002Bg=","KPtl\u002BIcYzJanv3TdGEjfu/58zjjSte7onQyK1z2UpSs=","UOD2algC0YxakRPAo\u002BdHBxw2nz\u002Bf3inCW8K/2sYv4hk=","2a4AqN7uSgiGGPijKrbGYp3zTiFaYviYMC4je9251Gg=","S1JDFpdG6oeT7HQg1q6p3OLFEq6MSuMk9DrbZZf85U0=","FcAp\u002BB\u002BMdtU4Jqt1qd8ZU0XGQCyIO1UaSwwwKyFcuRI=","KicT\u002BJLs/7POfopY2e6knubWrx25hvaxJ1zNKezbz9Y=","xL7/ma/CChAYqsGMi59uK6yIstcESmcirrh1RzpvMEw=","dnRdnpQc61NJ56ASQrUFLZkDTGNM0KNu\u002BtR3NDDE34A=","Grv4g6vNrL73s12N910v2w8Bfa5b3fgn3knYM4SPbTo=","biFvXP\u002Bh3VCB//g0WfQTKnZXpYAq5NNK8FOtNrSlluc=","JbXwwQIUN/GSNZKsNiMjv4ebWU2SviyhnVdlqdpCpmg=","nz\u002BZycBj/r0qxn/lLFHWJ8J6wFGlMsV/1mlRmZUo/4I=","aQycidQhGUbn4VCw/EJfF5iFRrN1xIgwHoIJjbOVZps=","qgUM6A/uKHiUkWc1/Ln9WXX1SAX8JoRvV74Ma6ZFmng=","iKkyE9MQsJaeQ\u002BwNmzP/yqlnE0DgDcGv\u002BmjdLoDxrRo=","uTVPNnHOvOCd/yTop9dVCWOMKn4tFTh\u002B\u002BvDB36ISZPs=","mfZpFq\u002BvCmodLP7zO9b0YsEWC/OcDyBoxhYqFD56fFk=","YWOs7JAKIsqIOVQG0w8okz7vUzx0CLjYsgFSeEvd8dY=","mhyeOUDBL5xq9Rlm12fZKRW\u002BewVdAloH3HpGO\u002B7GqeM=","dwYRUoBX6sjNOpgOukCSK6FYozMx5nQPuanV9jF0pug=","ozbr8RdoOPcWGZFTphPnXiPHqUXsUX48rNHT9DPxQQQ=","zNy/\u002Beenwd4rP3KmszLj/P9L4RfeJcIG51tiUMGKZUI=","JqnKg76tBTEDi4ygNmSbT8906THHzJuCJTZbK0K6Oe8=","JcACn0ymzW4JpJ5CgWCxT1NdaSHZxnxp\u002BAiJJM/kC6k=","k71DltJbtRqVXA3rGahMZgUq0B9sodbz2R43hsUcD1I=","aouiJcQV84ezpO9Cwpg\u002BId9XaiZVlGhgxGvxD6PaAGM=","b/Jk0Mr/B4BWzcJa6nZHbXC\u002BzU0I1a30M2AcH5fdjKY=","aK2OxKAVYxUxIEDqZnknDAW9qelpdYKLvlGPA3\u002B5OIE=","E4QT\u002B435PZZ\u002BRTzgvECRD1bOtElnkqeWREaoDzYrMdc=","FBxckgU98gb7vgTEM5V4Q\u002BEWV1Ztcp3Bssbx92n1keA=","gv3iSaKsj0CmcWFWMhUhYcA7l4\u002BnVTp1Jj85xAmbA8E=","mRQfJZfYrp6FVuPsI1970i6\u002Bg1zC7cMX1qaaf5X\u002BoCQ=","5BtfX2AAiOmDTGL34icHscY4eUpH3nbfHN/rb4e62rY=","6rueZEktdPrxLkoO8WfJXCckClsIUsg6sBnN1LTessM=","SZJz\u002B71xnWFevxgzVgPPCqih4KkGwhQhHvoh6BgiWFc=","u2aOXUOrTOrwIgVam12G9HzaU7QEbOQG66Q7IDjlMYY=","8DlE0XjBA/lhOGHaXiPZ5cQswwpo6NEUaebI9my2F4s=","1ldijbG/u6m3Wwq0OUgI3unhWdjWhqvOD\u002BI1PauI9GI=","WtqR0aLtM7t6m3NDyJiTfyz81jhBwyuQkg/iDou5f/k=","aNqGJzJ5xa0dNxSytzanVzqK6xNl85ZkIZfdb\u002BKhxHY=","TpcHV4OB3FaN8hILgTJGBWj6cGx2APNuu6cH90cA2Yw=","y2O\u002BMtvYW\u002BJsiXwnsSGokrtLoPU1BZKq/Rs6jBLWkBA=","XfkTfnoOOODr5Ke\u002BIvlGksb7y1tdjO9D3cio6nfgb6o=","wcROe0zOlvSplfU1neaBc6O9UQx0shY6TJh9t2ZSBYs=","10qLnXFiRep12dfNyKPtD4BUjDi86nt7iUeaDRzdFFg=","Aq6Wb82cwzIR34t\u002BKjNx2Bsbl4xPKot/OiCPUr8NcaA=","sbScjs7uLbfBbWbJKERtvGeL8se13w0V5s0ufS/zDaQ=","9hC0wthPXB9k40lIbDKdWYtaw2axqBb91\u002BojeVYtTEY=","oHrJ\u002Blbd6RhXKDeATc8FabZLEDUjbHWnd18rZBRbNBE=","qOlED1ak4sYSTrFn1g6Y7mnsz3UFQEQ/RV3qKJGx0DQ=","bkU1JrXkWH3R/7pZTq912KiH0qHTMuWrKp6\u002B3V8nWE0=","HCsDlEON4uTuZHQ/mLhoZSnOhDE/0YmD0\u002BPzbGk55jk=","DIlQgc8O3Rampq4\u002BuAU34qvAhOQ76ih6rEWZRuXbpGs=","87pLnLY3BRAM5qVJkJZ6NFQjQse85QaOsaRqbVei3f8=","gb5K/PglhYNjQ6udVditV5mmWe8pBL0bkbfqmDZJR3Q=","c//884XNSMx2fHCDDouqzztU4ZLBdyPK5IazFjEu3xg=","A5FwpPfGidgr2NgPt1ofZxg2nxXAcuozNEFd9BE7nsk="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,77 +0,0 @@
|
||||
.page[b-se1kx51m2b] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main[b-se1kx51m2b] {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:hover, .top-row[b-se1kx51m2b] .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row[b-se1kx51m2b] {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page[b-se1kx51m2b] {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth[b-se1kx51m2b] a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b], article[b-se1kx51m2b] {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row[b-z0fmt146ub] {
|
||||
min-height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand[b-z0fmt146ub] {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi[b-z0fmt146ub] {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.75rem;
|
||||
top: -1px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu[b-z0fmt146ub] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu[b-z0fmt146ub] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu[b-z0fmt146ub] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type[b-z0fmt146ub] {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type[b-z0fmt146ub] {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse[b-z0fmt146ub] {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-scrollable[b-z0fmt146ub] {
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
/* /Layout/MainLayout.razor.rz.scp.css */
|
||||
.page[b-se1kx51m2b] {
|
||||
@import '_content/Blazor.Bootstrap/Blazor.Bootstrap.7t9tbfaemk.bundle.scp.css';
|
||||
|
||||
/* /Components/Layout/MainLayout.razor.rz.scp.css */
|
||||
.page[b-4ckihtz3s1] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main[b-se1kx51m2b] {
|
||||
main[b-4ckihtz3s1] {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
.sidebar[b-4ckihtz3s1] {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
@@ -22,75 +24,75 @@ main[b-se1kx51m2b] {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
.top-row[b-4ckihtz3s1] a, .top-row[b-4ckihtz3s1] .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:hover, .top-row[b-se1kx51m2b] .btn-link:hover {
|
||||
.top-row[b-4ckihtz3s1] a:hover, .top-row[b-4ckihtz3s1] .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:first-child {
|
||||
.top-row[b-4ckihtz3s1] a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
.top-row[b-4ckihtz3s1] a, .top-row[b-4ckihtz3s1] .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page[b-se1kx51m2b] {
|
||||
.page[b-4ckihtz3s1] {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
.sidebar[b-4ckihtz3s1] {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth[b-se1kx51m2b] a:first-child {
|
||||
.top-row.auth[b-4ckihtz3s1] a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b], article[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1], article[b-4ckihtz3s1] {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
/* /Layout/NavMenu.razor.rz.scp.css */
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
/* /Components/Layout/NavMenu.razor.rz.scp.css */
|
||||
.navbar-toggler[b-c1psfyttma] {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row[b-z0fmt146ub] {
|
||||
.top-row[b-c1psfyttma] {
|
||||
min-height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand[b-z0fmt146ub] {
|
||||
.navbar-brand[b-c1psfyttma] {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi[b-z0fmt146ub] {
|
||||
.bi[b-c1psfyttma] {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
@@ -100,32 +102,32 @@ main[b-se1kx51m2b] {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu[b-z0fmt146ub] {
|
||||
.bi-house-door-fill-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu[b-z0fmt146ub] {
|
||||
.bi-plus-square-fill-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu[b-z0fmt146ub] {
|
||||
.bi-list-nested-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] {
|
||||
.nav-item[b-c1psfyttma] {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type[b-z0fmt146ub] {
|
||||
.nav-item:first-of-type[b-c1psfyttma] {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type[b-z0fmt146ub] {
|
||||
.nav-item:last-of-type[b-c1psfyttma] {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a {
|
||||
.nav-item[b-c1psfyttma] a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
@@ -134,27 +136,27 @@ main[b-se1kx51m2b] {
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a.active {
|
||||
.nav-item[b-c1psfyttma] a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a:hover {
|
||||
.nav-item[b-c1psfyttma] a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
.navbar-toggler[b-c1psfyttma] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse[b-z0fmt146ub] {
|
||||
.collapse[b-c1psfyttma] {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-scrollable[b-z0fmt146ub] {
|
||||
.nav-scrollable[b-c1psfyttma] {
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/* /Layout/MainLayout.razor.rz.scp.css */
|
||||
.page[b-se1kx51m2b] {
|
||||
/* /Components/Layout/MainLayout.razor.rz.scp.css */
|
||||
.page[b-4ckihtz3s1] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main[b-se1kx51m2b] {
|
||||
main[b-4ckihtz3s1] {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
.sidebar[b-4ckihtz3s1] {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
@@ -22,75 +22,75 @@ main[b-se1kx51m2b] {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
.top-row[b-4ckihtz3s1] a, .top-row[b-4ckihtz3s1] .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:hover, .top-row[b-se1kx51m2b] .btn-link:hover {
|
||||
.top-row[b-4ckihtz3s1] a:hover, .top-row[b-4ckihtz3s1] .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a:first-child {
|
||||
.top-row[b-4ckihtz3s1] a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] a, .top-row[b-se1kx51m2b] .btn-link {
|
||||
.top-row[b-4ckihtz3s1] a, .top-row[b-4ckihtz3s1] .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page[b-se1kx51m2b] {
|
||||
.page[b-4ckihtz3s1] {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar[b-se1kx51m2b] {
|
||||
.sidebar[b-4ckihtz3s1] {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth[b-se1kx51m2b] a:first-child {
|
||||
.top-row.auth[b-4ckihtz3s1] a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row[b-se1kx51m2b], article[b-se1kx51m2b] {
|
||||
.top-row[b-4ckihtz3s1], article[b-4ckihtz3s1] {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
/* /Layout/NavMenu.razor.rz.scp.css */
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
/* /Components/Layout/NavMenu.razor.rz.scp.css */
|
||||
.navbar-toggler[b-c1psfyttma] {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row[b-z0fmt146ub] {
|
||||
.top-row[b-c1psfyttma] {
|
||||
min-height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand[b-z0fmt146ub] {
|
||||
.navbar-brand[b-c1psfyttma] {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi[b-z0fmt146ub] {
|
||||
.bi[b-c1psfyttma] {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
@@ -100,32 +100,32 @@ main[b-se1kx51m2b] {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu[b-z0fmt146ub] {
|
||||
.bi-house-door-fill-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu[b-z0fmt146ub] {
|
||||
.bi-plus-square-fill-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu[b-z0fmt146ub] {
|
||||
.bi-list-nested-nav-menu[b-c1psfyttma] {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] {
|
||||
.nav-item[b-c1psfyttma] {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type[b-z0fmt146ub] {
|
||||
.nav-item:first-of-type[b-c1psfyttma] {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type[b-z0fmt146ub] {
|
||||
.nav-item:last-of-type[b-c1psfyttma] {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a {
|
||||
.nav-item[b-c1psfyttma] a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
@@ -134,27 +134,27 @@ main[b-se1kx51m2b] {
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a.active {
|
||||
.nav-item[b-c1psfyttma] a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item[b-z0fmt146ub] a:hover {
|
||||
.nav-item[b-c1psfyttma] a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler[b-z0fmt146ub] {
|
||||
.navbar-toggler[b-c1psfyttma] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse[b-z0fmt146ub] {
|
||||
.collapse[b-c1psfyttma] {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-scrollable[b-z0fmt146ub] {
|
||||
.nav-scrollable[b-c1psfyttma] {
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
LLDFCtTeJjqY5H3lO0eDuYGdqu5tbNevpkUMhKX8TTA=
|
||||
+3s8TTPcc657CtZZeHB/FwXsD8EuOVIHrdrZEjeJb9A=
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -55,6 +55,14 @@
|
||||
"net9.0": {
|
||||
"targetAlias": "net9.0",
|
||||
"dependencies": {
|
||||
"Blazor.Bootstrap": {
|
||||
"target": "Package",
|
||||
"version": "[3.4.0, )"
|
||||
},
|
||||
"Blazored.Typeahead": {
|
||||
"target": "Package",
|
||||
"version": "[4.7.0, )"
|
||||
},
|
||||
"Microsoft.AspNetCore.Components.WebAssembly": {
|
||||
"target": "Package",
|
||||
"version": "[9.0.9, )"
|
||||
@@ -80,6 +88,10 @@
|
||||
"version": "[9.0.9, )",
|
||||
"autoReferenced": true
|
||||
},
|
||||
"MudBlazor": {
|
||||
"target": "Package",
|
||||
"version": "[8.13.0, )"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt": {
|
||||
"target": "Package",
|
||||
"version": "[8.14.0, )"
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)mudblazor\8.13.0\buildTransitive\MudBlazor.props" Condition="Exists('$(NuGetPackageRoot)mudblazor\8.13.0\buildTransitive\MudBlazor.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.illink.tasks\9.0.9\build\Microsoft.NET.ILLink.Tasks.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.illink.tasks\9.0.9\build\Microsoft.NET.ILLink.Tasks.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.webassembly\9.0.9\build\net9.0\Microsoft.AspNetCore.Components.WebAssembly.props" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.webassembly\9.0.9\build\net9.0\Microsoft.AspNetCore.Components.WebAssembly.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazored.typeahead\4.7.0\buildTransitive\Blazored.Typeahead.props" Condition="Exists('$(NuGetPackageRoot)blazored.typeahead\4.7.0\buildTransitive\Blazored.Typeahead.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazor.bootstrap\3.4.0\buildTransitive\Blazor.Bootstrap.props" Condition="Exists('$(NuGetPackageRoot)blazor.bootstrap\3.4.0\buildTransitive\Blazor.Bootstrap.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgMicrosoft_NET_Sdk_WebAssembly_Pack Condition=" '$(PkgMicrosoft_NET_Sdk_WebAssembly_Pack)' == '' ">C:\Users\MarcWieland\.nuget\packages\microsoft.net.sdk.webassembly.pack\9.0.9</PkgMicrosoft_NET_Sdk_WebAssembly_Pack>
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.9\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.9\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.9\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.9\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\9.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\9.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)mudblazor\8.13.0\build\MudBlazor.targets" Condition="Exists('$(NuGetPackageRoot)mudblazor\8.13.0\build\MudBlazor.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.sdk.webassembly.pack\9.0.9\build\Microsoft.NET.Sdk.WebAssembly.Pack.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.9\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.9\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.webassembly.devserver\9.0.9\build\Microsoft.AspNetCore.Components.WebAssembly.DevServer.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.webassembly.devserver\9.0.9\build\Microsoft.AspNetCore.Components.WebAssembly.DevServer.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\9.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\9.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -2,6 +2,43 @@
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net9.0": {
|
||||
"Blazor.Bootstrap/3.4.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components.Web": "9.0.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/BlazorBootstrap.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/BlazorBootstrap.dll": {}
|
||||
},
|
||||
"build": {
|
||||
"buildTransitive/Blazor.Bootstrap.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/Blazor.Bootstrap.props": {}
|
||||
}
|
||||
},
|
||||
"Blazored.Typeahead/4.7.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "6.0.3",
|
||||
"Microsoft.AspNetCore.Components.Web": "6.0.3"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net6.0/Blazored.Typeahead.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Blazored.Typeahead.dll": {}
|
||||
},
|
||||
"build": {
|
||||
"buildTransitive/Blazored.Typeahead.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/Blazored.Typeahead.props": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Authorization/9.0.9": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -380,6 +417,38 @@
|
||||
"buildTransitive/net8.0/_._": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization/9.0.1": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Options": "9.0.1"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions/9.0.1": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging/9.0.9": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -583,6 +652,31 @@
|
||||
"build/Microsoft.NET.Sdk.WebAssembly.Pack.targets": {}
|
||||
}
|
||||
},
|
||||
"MudBlazor/8.13.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "9.0.1",
|
||||
"Microsoft.AspNetCore.Components.Web": "9.0.1",
|
||||
"Microsoft.Extensions.Localization": "9.0.1"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/MudBlazor.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/MudBlazor.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"build/MudBlazor.targets": {},
|
||||
"buildTransitive/MudBlazor.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/MudBlazor.props": {}
|
||||
}
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/8.14.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -612,6 +706,43 @@
|
||||
}
|
||||
},
|
||||
"net9.0/browser-wasm": {
|
||||
"Blazor.Bootstrap/3.4.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components.Web": "9.0.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/BlazorBootstrap.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/BlazorBootstrap.dll": {}
|
||||
},
|
||||
"build": {
|
||||
"buildTransitive/Blazor.Bootstrap.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/Blazor.Bootstrap.props": {}
|
||||
}
|
||||
},
|
||||
"Blazored.Typeahead/4.7.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "6.0.3",
|
||||
"Microsoft.AspNetCore.Components.Web": "6.0.3"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net6.0/Blazored.Typeahead.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Blazored.Typeahead.dll": {}
|
||||
},
|
||||
"build": {
|
||||
"buildTransitive/Blazored.Typeahead.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/Blazored.Typeahead.props": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Authorization/9.0.9": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -990,6 +1121,38 @@
|
||||
"buildTransitive/net8.0/_._": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization/9.0.1": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Options": "9.0.1"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions/9.0.1": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging/9.0.9": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -1193,6 +1356,31 @@
|
||||
"build/Microsoft.NET.Sdk.WebAssembly.Pack.targets": {}
|
||||
}
|
||||
},
|
||||
"MudBlazor/8.13.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "9.0.1",
|
||||
"Microsoft.AspNetCore.Components.Web": "9.0.1",
|
||||
"Microsoft.Extensions.Localization": "9.0.1"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net9.0/MudBlazor.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/MudBlazor.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"build/MudBlazor.targets": {},
|
||||
"buildTransitive/MudBlazor.props": {}
|
||||
},
|
||||
"buildMultiTargeting": {
|
||||
"buildMultiTargeting/MudBlazor.props": {}
|
||||
}
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/8.14.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -1223,6 +1411,55 @@
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"Blazor.Bootstrap/3.4.0": {
|
||||
"sha512": "RlK531tJCXGEoESwjDIARttoRPtOCXXQqrNwfaai7sIWir2pqsBop0gySBqN742m+K2vY9p9J7Mwwl6XcNXm6g==",
|
||||
"type": "package",
|
||||
"path": "blazor.bootstrap/3.4.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"128X128.png",
|
||||
"README.md",
|
||||
"blazor.bootstrap.3.4.0.nupkg.sha512",
|
||||
"blazor.bootstrap.nuspec",
|
||||
"build/Blazor.Bootstrap.props",
|
||||
"build/Microsoft.AspNetCore.StaticWebAssetEndpoints.props",
|
||||
"build/Microsoft.AspNetCore.StaticWebAssets.props",
|
||||
"buildMultiTargeting/Blazor.Bootstrap.props",
|
||||
"buildTransitive/Blazor.Bootstrap.props",
|
||||
"lib/net6.0/BlazorBootstrap.dll",
|
||||
"lib/net8.0/BlazorBootstrap.dll",
|
||||
"lib/net9.0/BlazorBootstrap.dll",
|
||||
"staticwebassets/Blazor.Bootstrap.7t9tbfaemk.bundle.scp.css",
|
||||
"staticwebassets/blazor.bootstrap.css",
|
||||
"staticwebassets/blazor.bootstrap.js",
|
||||
"staticwebassets/blazor.bootstrap.pdf.js",
|
||||
"staticwebassets/blazor.bootstrap.sortable-list.js",
|
||||
"staticwebassets/blazor.bootstrap.theme-switcher.js",
|
||||
"staticwebassets/icon/128X128.png",
|
||||
"staticwebassets/pdfjs-4.0.379.min.js",
|
||||
"staticwebassets/pdfjs-4.0.379.worker.min.js"
|
||||
]
|
||||
},
|
||||
"Blazored.Typeahead/4.7.0": {
|
||||
"sha512": "fTN4Bt9rwEE/d33FXFd+h/DBjVtsFJLRf9B8mu0zJWMWG5Mk2tU2il3aK0+laUxNgBNBgEL0jW/831I+oapd6A==",
|
||||
"type": "package",
|
||||
"path": "blazored.typeahead/4.7.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"blazored.typeahead.4.7.0.nupkg.sha512",
|
||||
"blazored.typeahead.nuspec",
|
||||
"build/Blazored.Typeahead.props",
|
||||
"build/Microsoft.AspNetCore.StaticWebAssets.props",
|
||||
"buildMultiTargeting/Blazored.Typeahead.props",
|
||||
"buildTransitive/Blazored.Typeahead.props",
|
||||
"icon.png",
|
||||
"lib/net6.0/Blazored.Typeahead.dll",
|
||||
"staticwebassets/blazored-typeahead.css",
|
||||
"staticwebassets/blazored-typeahead.js"
|
||||
]
|
||||
},
|
||||
"Microsoft.AspNetCore.Authorization/9.0.9": {
|
||||
"sha512": "OVUDsnJDBhCuyJtjkQXObWbBGjh4kyxL/pl/5RqtZHnSJcpEr1eD6l4vbFIdRHg4bFI59vTTrfHKQ3zwfR4KCw==",
|
||||
"type": "package",
|
||||
@@ -1886,6 +2123,44 @@
|
||||
"useSharedDesignerContext.txt"
|
||||
]
|
||||
},
|
||||
"Microsoft.Extensions.Localization/9.0.1": {
|
||||
"sha512": "UgvX4Yb2T3tEsKT30ktZr0H7kTRPapCgEH0bdTwxiEGSdA39/hAQMvvb+vgHpqmevDU5+puyI9ujRkmmbF946w==",
|
||||
"type": "package",
|
||||
"path": "microsoft.extensions.localization/9.0.1",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"Icon.png",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"lib/net462/Microsoft.Extensions.Localization.dll",
|
||||
"lib/net462/Microsoft.Extensions.Localization.xml",
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.dll",
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.xml",
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Localization.dll",
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Localization.xml",
|
||||
"microsoft.extensions.localization.9.0.1.nupkg.sha512",
|
||||
"microsoft.extensions.localization.nuspec"
|
||||
]
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions/9.0.1": {
|
||||
"sha512": "CABog43lyaZQMjmlktuImCy6zmAzRBaXqN81uPaMQjlp//ISDVYItZPh6KWpWRF4MY/B67X5oDc3JTUpfdocZw==",
|
||||
"type": "package",
|
||||
"path": "microsoft.extensions.localization.abstractions/9.0.1",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"Icon.png",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"lib/net462/Microsoft.Extensions.Localization.Abstractions.dll",
|
||||
"lib/net462/Microsoft.Extensions.Localization.Abstractions.xml",
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.dll",
|
||||
"lib/net9.0/Microsoft.Extensions.Localization.Abstractions.xml",
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Localization.Abstractions.dll",
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Localization.Abstractions.xml",
|
||||
"microsoft.extensions.localization.abstractions.9.0.1.nupkg.sha512",
|
||||
"microsoft.extensions.localization.abstractions.nuspec"
|
||||
]
|
||||
},
|
||||
"Microsoft.Extensions.Logging/9.0.9": {
|
||||
"sha512": "MaCB0Y9hNDs4YLu3HCJbo199WnJT8xSgajG1JYGANz9FkseQ5f3v/llu3HxLI6mjDlu7pa7ps9BLPWjKzsAAzQ==",
|
||||
"type": "package",
|
||||
@@ -2307,6 +2582,33 @@
|
||||
"tools/net9.0/Microsoft.NET.WebAssembly.Webcil.dll"
|
||||
]
|
||||
},
|
||||
"MudBlazor/8.13.0": {
|
||||
"sha512": "Y6JW93zf8tiVhMSkkL0mZ3ruqjOTNftvVoX3sik6NEnIye+Gs0FXI8rhXfrH2LU79Mw/fOtT5ms3L/Q4TKx2kA==",
|
||||
"type": "package",
|
||||
"path": "mudblazor/8.13.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE",
|
||||
"Nuget.png",
|
||||
"README.md",
|
||||
"analyzers/dotnet/cs/MudBlazor.Analyzers.dll",
|
||||
"build/Microsoft.AspNetCore.StaticWebAssetEndpoints.props",
|
||||
"build/Microsoft.AspNetCore.StaticWebAssets.props",
|
||||
"build/MudBlazor.props",
|
||||
"build/MudBlazor.targets",
|
||||
"buildMultiTargeting/MudBlazor.props",
|
||||
"buildTransitive/MudBlazor.props",
|
||||
"lib/net8.0/MudBlazor.dll",
|
||||
"lib/net8.0/MudBlazor.xml",
|
||||
"lib/net9.0/MudBlazor.dll",
|
||||
"lib/net9.0/MudBlazor.xml",
|
||||
"mudblazor.8.13.0.nupkg.sha512",
|
||||
"mudblazor.nuspec",
|
||||
"staticwebassets/MudBlazor.min.css",
|
||||
"staticwebassets/MudBlazor.min.js"
|
||||
]
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/8.14.0": {
|
||||
"sha512": "EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==",
|
||||
"type": "package",
|
||||
@@ -2339,11 +2641,14 @@
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net9.0": [
|
||||
"Blazor.Bootstrap >= 3.4.0",
|
||||
"Blazored.Typeahead >= 4.7.0",
|
||||
"Microsoft.AspNetCore.Components.WebAssembly >= 9.0.9",
|
||||
"Microsoft.AspNetCore.Components.WebAssembly.DevServer >= 9.0.9",
|
||||
"Microsoft.Extensions.Http >= 9.0.9",
|
||||
"Microsoft.NET.ILLink.Tasks >= 9.0.9",
|
||||
"Microsoft.NET.Sdk.WebAssembly.Pack >= 9.0.9",
|
||||
"MudBlazor >= 8.13.0",
|
||||
"OnProfNext.Shared >= 1.0.0",
|
||||
"System.IdentityModel.Tokens.Jwt >= 8.14.0"
|
||||
]
|
||||
@@ -2403,6 +2708,14 @@
|
||||
"net9.0": {
|
||||
"targetAlias": "net9.0",
|
||||
"dependencies": {
|
||||
"Blazor.Bootstrap": {
|
||||
"target": "Package",
|
||||
"version": "[3.4.0, )"
|
||||
},
|
||||
"Blazored.Typeahead": {
|
||||
"target": "Package",
|
||||
"version": "[4.7.0, )"
|
||||
},
|
||||
"Microsoft.AspNetCore.Components.WebAssembly": {
|
||||
"target": "Package",
|
||||
"version": "[9.0.9, )"
|
||||
@@ -2428,6 +2741,10 @@
|
||||
"version": "[9.0.9, )",
|
||||
"autoReferenced": true
|
||||
},
|
||||
"MudBlazor": {
|
||||
"target": "Package",
|
||||
"version": "[8.13.0, )"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt": {
|
||||
"target": "Package",
|
||||
"version": "[8.14.0, )"
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "J3t2sm//lQ8=",
|
||||
"dgSpecHash": "NE5DfiP76Cc=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\DEVQPDC\\Proj2\\OnProfNext\\OnProfNext.Client\\OnProfNext.Client.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\blazor.bootstrap\\3.4.0\\blazor.bootstrap.3.4.0.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\blazored.typeahead\\4.7.0\\blazored.typeahead.4.7.0.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.aspnetcore.authorization\\9.0.9\\microsoft.aspnetcore.authorization.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.aspnetcore.components\\9.0.9\\microsoft.aspnetcore.components.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.aspnetcore.components.analyzers\\9.0.9\\microsoft.aspnetcore.components.analyzers.9.0.9.nupkg.sha512",
|
||||
@@ -25,6 +27,8 @@
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.fileproviders.physical\\9.0.9\\microsoft.extensions.fileproviders.physical.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.filesystemglobbing\\9.0.9\\microsoft.extensions.filesystemglobbing.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.http\\9.0.9\\microsoft.extensions.http.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.localization\\9.0.1\\microsoft.extensions.localization.9.0.1.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.localization.abstractions\\9.0.1\\microsoft.extensions.localization.abstractions.9.0.1.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.logging\\9.0.9\\microsoft.extensions.logging.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\9.0.9\\microsoft.extensions.logging.abstractions.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.extensions.options\\9.0.9\\microsoft.extensions.options.9.0.9.nupkg.sha512",
|
||||
@@ -38,6 +42,7 @@
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.jsinterop.webassembly\\9.0.9\\microsoft.jsinterop.webassembly.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.net.illink.tasks\\9.0.9\\microsoft.net.illink.tasks.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.net.sdk.webassembly.pack\\9.0.9\\microsoft.net.sdk.webassembly.pack.9.0.9.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\mudblazor\\8.13.0\\mudblazor.8.13.0.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.14.0\\system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512",
|
||||
"C:\\Users\\MarcWieland\\.nuget\\packages\\microsoft.netcore.app.runtime.mono.browser-wasm\\9.0.9\\microsoft.netcore.app.runtime.mono.browser-wasm.9.0.9.nupkg.sha512"
|
||||
],
|
||||
|
||||
@@ -10,14 +10,17 @@
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link href="OnProfNext.Client.styles.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
|
||||
<link href="_content/Blazor.Bootstrap/blazor.bootstrap.css" rel="stylesheet" />
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="d-flex flex-column justify-content-center align-items-center vh-100">
|
||||
<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status"></div>
|
||||
<div class="mt-3 text-secondary fw-semibold">OnProf Next lädt...</div>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
|
||||
<div id="loader-overlay" class="d-flex flex-column justify-content-center align-items-center">
|
||||
<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status"></div>
|
||||
<div class="mt-3 text-secondary fw-semibold">OnProf Next lädt...</div>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
@@ -26,7 +29,22 @@
|
||||
<span class="dismiss">🗙</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#loader-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: #ffffff;
|
||||
z-index: 9999;
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="js/init.js"></script>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/Blazor.Bootstrap/blazor.bootstrap.js"></script>
|
||||
<script src="js/onProfNext.js"></script>
|
||||
<script src="js/dragDrop.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
||||
37
OnProfNext.Client/wwwroot/js/dragDrop.js
Normal file
37
OnProfNext.Client/wwwroot/js/dragDrop.js
Normal file
@@ -0,0 +1,37 @@
|
||||
window.onProfNext = {
|
||||
preventDefault: function (event) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
startResize: function (event, bookingId, onResizeCallback) {
|
||||
event.preventDefault();
|
||||
const element = event.target.closest('.booking-item');
|
||||
if (!element) return;
|
||||
|
||||
let startY = event.clientY;
|
||||
let startHeight = parseInt(element.style.height) || 50; // Default 50px (1 hour)
|
||||
const minHeight = 25; // Minimum 0.5 hours
|
||||
const maxHeight = 400; // Maximum 8 hours
|
||||
|
||||
function onMouseMove(e) {
|
||||
const deltaY = e.clientY - startY;
|
||||
let newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY));
|
||||
newHeight = Math.round(newHeight / 25) * 25; // Round to nearest 0.5 hours
|
||||
element.style.height = `${newHeight}px`;
|
||||
|
||||
const hours = newHeight / 50; // 50px = 1 hour
|
||||
window.onProfNext.currentHours = hours;
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
DotNet.invokeMethodAsync('OnProfNext.Client', 'UpdateBookingHours', bookingId, window.onProfNext.currentHours);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
}
|
||||
};
|
||||
7
OnProfNext.Client/wwwroot/js/init.js
Normal file
7
OnProfNext.Client/wwwroot/js/init.js
Normal file
@@ -0,0 +1,7 @@
|
||||
window.hideLoader = () => {
|
||||
const loader = document.getElementById("loader-overlay");
|
||||
if (loader) {
|
||||
loader.style.opacity = "0";
|
||||
setTimeout(() => loader.remove(), 400);
|
||||
}
|
||||
};
|
||||
15
OnProfNext.Client/wwwroot/js/onProfNext.js
Normal file
15
OnProfNext.Client/wwwroot/js/onProfNext.js
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
window.onProfNext = {
|
||||
preventDefault: function () {
|
||||
// Diese Funktion wird von Blazor aufgerufen, um preventDefault zu setzen
|
||||
// Sie muss an einem Ort aufgerufen werden, wo das Event verfügbar ist
|
||||
// In Blazor wird sie über @ondragover aufgerufen
|
||||
return true; // Signalisiert, dass der Aufruf erfolgreich war
|
||||
}
|
||||
};
|
||||
|
||||
// Event-Listener für dragover, um preventDefault zu setzen
|
||||
document.addEventListener('dragover', (event) => {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
});
|
||||
46
OnProfNext.Server/Configurations/BookingConfiguration.cs
Normal file
46
OnProfNext.Server/Configurations/BookingConfiguration.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Data.Configurations
|
||||
{
|
||||
public class BookingConfiguration : IEntityTypeConfiguration<Booking>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Booking> builder)
|
||||
{
|
||||
builder.ToTable("Bookings");
|
||||
|
||||
builder.HasKey(b => b.Id);
|
||||
|
||||
builder.Property(b => b.Hours)
|
||||
.HasColumnType("decimal(5,2)")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(b => b.Date)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(b => b.Description)
|
||||
.HasMaxLength(500);
|
||||
|
||||
builder.Property(b => b.MandantId)
|
||||
.IsRequired();
|
||||
|
||||
|
||||
builder.HasOne(b => b.Order)
|
||||
.WithMany()
|
||||
.HasForeignKey(b => b.OrderId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(b => b.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(b => b.UserId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.Property(b => b.CreatedAt)
|
||||
.HasDefaultValueSql("GETUTCDATE()");
|
||||
|
||||
builder.Property(b => b.UpdatedAt)
|
||||
.HasDefaultValueSql("GETUTCDATE()");
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OnProfNext.Server/Configurations/OrderConfiguration.cs
Normal file
59
OnProfNext.Server/Configurations/OrderConfiguration.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Configurations
|
||||
{
|
||||
public class OrderConfiguration : IEntityTypeConfiguration<Order>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Order> entity)
|
||||
{
|
||||
entity.ToTable("Orders");
|
||||
|
||||
entity.HasKey(o => o.Id);
|
||||
|
||||
entity.Property(o => o.Auftragsnummer)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(o => o.Titel)
|
||||
.IsRequired()
|
||||
.HasMaxLength(255);
|
||||
|
||||
entity.Property(o => o.Status)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasDefaultValue("Geplant");
|
||||
|
||||
entity.Property(o => o.Planstunden)
|
||||
.HasPrecision(10, 2)
|
||||
.HasDefaultValue(0);
|
||||
|
||||
entity.Property(o => o.Iststunden)
|
||||
.HasPrecision(10, 2)
|
||||
.HasDefaultValue(0);
|
||||
|
||||
entity.Property(o => o.MandantId)
|
||||
.IsRequired();
|
||||
|
||||
entity.Property(o => o.CreatedAt)
|
||||
.HasDefaultValueSql("GETUTCDATE()");
|
||||
|
||||
entity.Property(o => o.UpdatedAt)
|
||||
.HasDefaultValueSql("GETUTCDATE()");
|
||||
|
||||
|
||||
entity.HasOne(o => o.Project)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(o => o.ProjectId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
entity.HasMany(o => o.OrderUsers)
|
||||
.WithOne(ou => ou.Order)
|
||||
.HasForeignKey(ou => ou.OrderId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
OnProfNext.Server/Configurations/OrderUserConfiguration.cs
Normal file
25
OnProfNext.Server/Configurations/OrderUserConfiguration.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Configurations
|
||||
{
|
||||
public class OrderUserConfiguration : IEntityTypeConfiguration<OrderUser>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<OrderUser> entity)
|
||||
{
|
||||
entity.ToTable("OrderUsers");
|
||||
entity.HasKey(ou => new { ou.OrderId, ou.UserId });
|
||||
|
||||
entity.HasOne(ou => ou.Order)
|
||||
.WithMany(o => o.OrderUsers)
|
||||
.HasForeignKey(ou => ou.OrderId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasOne(ou => ou.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(ou => ou.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
OnProfNext.Server/Configurations/ProjectConfiguration.cs
Normal file
47
OnProfNext.Server/Configurations/ProjectConfiguration.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Configurations
|
||||
{
|
||||
public class ProjectConfiguration : IEntityTypeConfiguration<Project>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Project> entity)
|
||||
{
|
||||
entity.ToTable("Projects");
|
||||
// Primary Key
|
||||
entity.HasKey(p => p.Id);
|
||||
// Project Name
|
||||
entity.Property(p => p.ProjectName)
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
// Description
|
||||
entity.Property(p => p.Description)
|
||||
.HasMaxLength(1000);
|
||||
// Project Manager
|
||||
entity.Property(p => p.ProjectManager)
|
||||
.HasMaxLength(100);
|
||||
// Status
|
||||
entity.Property(p => p.Status)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasDefaultValue("Geplant");
|
||||
// Start Date
|
||||
entity.Property(p => p.StartDate)
|
||||
.IsRequired()
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
// End Date
|
||||
entity.Property(p => p.EndDate);
|
||||
// Mandant
|
||||
entity.Property(p => p.MandantId)
|
||||
.HasDefaultValue(1);
|
||||
// Timestamps
|
||||
entity.Property(p => p.CreatedAt)
|
||||
.HasDefaultValueSql("SYSDATETIME()")
|
||||
.ValueGeneratedOnAdd();
|
||||
entity.Property(p => p.UpdatedAt)
|
||||
.HasDefaultValueSql("SYSDATETIME()")
|
||||
.ValueGeneratedOnAddOrUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
OnProfNext.Server/Configurations/ProjectUserConfiguration.cs
Normal file
28
OnProfNext.Server/Configurations/ProjectUserConfiguration.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Configurations
|
||||
{
|
||||
public class ProjectUserConfiguration : IEntityTypeConfiguration<ProjectUser>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ProjectUser> entity)
|
||||
{
|
||||
entity.ToTable("ProjectUsers");
|
||||
|
||||
// Composite Primary Key
|
||||
entity.HasKey(pu => new { pu.ProjectId, pu.UserId });
|
||||
|
||||
entity.HasOne(pu => pu.Project)
|
||||
.WithMany(p => p.ProjectUsers)
|
||||
.HasForeignKey(pu => pu.ProjectId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasOne(pu => pu.User)
|
||||
.WithMany(u => u.ProjectUsers)
|
||||
.HasForeignKey(pu => pu.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
163
OnProfNext.Server/Controllers/BookingsController.cs
Normal file
163
OnProfNext.Server/Controllers/BookingsController.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Data;
|
||||
using OnProfNext.Shared.Models;
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace OnProfNext.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
public class BookingsController : ControllerBase
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public BookingsController(AppDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private int GetCurrentUserId()
|
||||
{
|
||||
var userIdClaim = User.FindFirst("UserId")?.Value;
|
||||
if (string.IsNullOrEmpty(userIdClaim))
|
||||
throw new UnauthorizedAccessException("Kein User-Claim im Token gefunden.");
|
||||
|
||||
return int.Parse(userIdClaim);
|
||||
}
|
||||
|
||||
[HttpGet("mine")]
|
||||
public async Task<ActionResult<IEnumerable<BookingDto>>> GetMyBookings()
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
|
||||
var bookings = await _context.Bookings
|
||||
.Include(b => b.Order)
|
||||
.Where(b => b.UserId == userId)
|
||||
.OrderByDescending(b => b.Date)
|
||||
.Select(b => new BookingDto
|
||||
{
|
||||
Id = b.Id,
|
||||
OrderId = b.OrderId,
|
||||
OrderTitle = b.Order != null ? b.Order.Titel : "",
|
||||
UserId = b.UserId,
|
||||
Date = b.Date,
|
||||
Hours = b.Hours,
|
||||
Description = b.Description,
|
||||
MandantId = b.MandantId,
|
||||
IsPending = false
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
Console.WriteLine($"Returning bookings: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}");
|
||||
return Ok(bookings);
|
||||
}
|
||||
|
||||
[HttpGet("byproject/{projectId}")]
|
||||
public async Task<ActionResult<IEnumerable<BookingDto>>> GetBookingsByProject(int projectId)
|
||||
{
|
||||
var bookings = await _context.Bookings
|
||||
.Include(b => b.Order)
|
||||
.ThenInclude(o => o.Project)
|
||||
.Include(b => b.User)
|
||||
.Where(b => b.Order!.ProjectId == projectId)
|
||||
.Select(b => new BookingDto
|
||||
{
|
||||
Id = b.Id,
|
||||
OrderId = b.OrderId,
|
||||
OrderTitle = b.Order!.Titel,
|
||||
UserId = b.UserId,
|
||||
Username = $"{b.User!.FirstName} {b.User.LastName}",
|
||||
Date = b.Date,
|
||||
Hours = b.Hours,
|
||||
Description = b.Description,
|
||||
MandantId = b.MandantId,
|
||||
IsPending = false
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
Console.WriteLine($"Returning bookings for project {projectId}: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}");
|
||||
return Ok(bookings);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<BookingDto>> CreateBooking([FromBody] BookingCreateDto dto)
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
|
||||
// Logge die rohe HTTP-Payload
|
||||
var rawRequest = await new StreamReader(Request.BodyReader.AsStream()).ReadToEndAsync();
|
||||
Console.WriteLine($"Raw HTTP request body: {rawRequest}");
|
||||
Console.WriteLine($"Received booking DTO: {JsonSerializer.Serialize(dto, new JsonSerializerOptions { WriteIndented = true })}");
|
||||
Console.WriteLine($"Received booking: Date={dto.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {dto.Date.Kind})");
|
||||
|
||||
var booking = new Booking
|
||||
{
|
||||
OrderId = dto.OrderId,
|
||||
UserId = userId,
|
||||
Date = dto.Date,
|
||||
Hours = dto.Hours,
|
||||
Description = dto.Description,
|
||||
MandantId = dto.MandantId,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.Bookings.Add(booking);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var createdDto = new BookingDto
|
||||
{
|
||||
Id = booking.Id,
|
||||
OrderId = booking.OrderId,
|
||||
UserId = booking.UserId,
|
||||
Date = booking.Date,
|
||||
Hours = booking.Hours,
|
||||
Description = booking.Description,
|
||||
MandantId = booking.MandantId,
|
||||
IsPending = false
|
||||
};
|
||||
|
||||
Console.WriteLine($"Created booking: ID={booking.Id}, Date={booking.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {booking.Date.Kind})");
|
||||
return CreatedAtAction(nameof(GetMyBookings), new { id = booking.Id }, createdDto);
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateBooking(int id, BookingCreateDto dto)
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
Console.WriteLine($"Updating booking ID={id}: Date={dto.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {dto.Date.Kind})");
|
||||
|
||||
var booking = await _context.Bookings.FirstOrDefaultAsync(b => b.Id == id && b.UserId == userId);
|
||||
if (booking == null) return NotFound();
|
||||
|
||||
booking.OrderId = dto.OrderId;
|
||||
booking.Date = dto.Date;
|
||||
booking.Hours = dto.Hours;
|
||||
booking.Description = dto.Description;
|
||||
booking.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
Console.WriteLine($"Updated booking ID={id}: Date={booking.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {booking.Date.Kind})");
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteBooking(int id)
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
var booking = await _context.Bookings.FirstOrDefaultAsync(b => b.Id == id && b.UserId == userId);
|
||||
if (booking == null)
|
||||
return NotFound();
|
||||
|
||||
Console.WriteLine($"Deleting booking ID={id}");
|
||||
_context.Bookings.Remove(booking);
|
||||
await _context.SaveChangesAsync();
|
||||
Console.WriteLine($"Deleted booking ID={id}");
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
56
OnProfNext.Server/Controllers/OrderUsersController.cs
Normal file
56
OnProfNext.Server/Controllers/OrderUsersController.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Data;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class OrderUsersController : ControllerBase
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public OrderUsersController(AppDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
//GET: api/orderusers/{orderId}
|
||||
[HttpGet("{orderId}")]
|
||||
public async Task<ActionResult<IEnumerable<int>>> GetUsersForOrder(int orderId)
|
||||
{
|
||||
var userIds = await _context.OrderUsers.Where(ou => ou.OrderId == orderId).Select(ou => ou.UserId).ToListAsync();
|
||||
|
||||
return Ok(userIds);
|
||||
}
|
||||
|
||||
//POST: api/orderusers
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SetUsersForOrder([FromBody] OrderUserAssignmentDto dto)
|
||||
{
|
||||
var existing = await _context.OrderUsers
|
||||
.Where(ou => ou.OrderId == dto.OrderId)
|
||||
.ToListAsync();
|
||||
|
||||
_context.OrderUsers.RemoveRange(existing);
|
||||
|
||||
var newRelations = dto.UserIds.Select(uid => new OrderUser
|
||||
{
|
||||
OrderId = dto.OrderId,
|
||||
UserId = uid
|
||||
});
|
||||
|
||||
_context.OrderUsers.AddRange(newRelations);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
public class OrderUserAssignmentDto
|
||||
{
|
||||
public int OrderId { get; set; }
|
||||
public List<int> UserIds { get; set; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
229
OnProfNext.Server/Controllers/OrdersController.cs
Normal file
229
OnProfNext.Server/Controllers/OrdersController.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Data;
|
||||
using OnProfNext.Shared.Models;
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
|
||||
namespace OnProfNext.Server.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class OrdersController : ControllerBase
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public OrdersController(AppDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
[HttpGet("byproject/{projectId}")]
|
||||
public async Task<ActionResult<IEnumerable<OrderDto>>> GetOrdersByProject(int projectId)
|
||||
{
|
||||
var orders = await _context.Orders
|
||||
.Include(o => o.OrderUsers)
|
||||
.ThenInclude(ou => ou.User)
|
||||
.Where(o => o.ProjectId == projectId)
|
||||
.AsNoTracking()
|
||||
.Select(o => new OrderDto
|
||||
{
|
||||
Id = o.Id,
|
||||
ProjectId = o.ProjectId,
|
||||
Auftragsnummer = o.Auftragsnummer,
|
||||
Titel = o.Titel,
|
||||
Status = o.Status,
|
||||
Planstunden = o.Planstunden,
|
||||
Iststunden = o.Iststunden,
|
||||
MandantId = o.MandantId,
|
||||
Mitarbeiter = o.OrderUsers
|
||||
.Select(ou => new UserDto
|
||||
{
|
||||
Id = ou.User!.Id,
|
||||
Username = ou.User.Username,
|
||||
FirstName = ou.User.FirstName,
|
||||
LastName = ou.User.LastName,
|
||||
Email = ou.User.Email
|
||||
}).ToList()
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(orders);
|
||||
}
|
||||
|
||||
// GET: api/orders/5
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<OrderDto>> GetOrder(int id)
|
||||
{
|
||||
var order = await _context.Orders
|
||||
.Include(o => o.OrderUsers)
|
||||
.ThenInclude(ou => ou.User)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(o => o.Id == id);
|
||||
|
||||
if (order == null)
|
||||
return NotFound();
|
||||
|
||||
var dto = new OrderDto
|
||||
{
|
||||
Id = order.Id,
|
||||
ProjectId = order.ProjectId,
|
||||
Auftragsnummer = order.Auftragsnummer,
|
||||
Titel = order.Titel,
|
||||
Status = order.Status,
|
||||
Planstunden = order.Planstunden,
|
||||
Iststunden = order.Iststunden,
|
||||
Projektcode = order.Projektcode,
|
||||
MandantId = order.MandantId,
|
||||
CreatedAt = order.CreatedAt,
|
||||
UpdatedAt = order.UpdatedAt,
|
||||
Mitarbeiter = order.OrderUsers
|
||||
.Select(ou => new UserDto
|
||||
{
|
||||
Id = ou.User!.Id,
|
||||
Username = ou.User.Username,
|
||||
FirstName = ou.User.FirstName,
|
||||
LastName = ou.User.LastName,
|
||||
Email = ou.User.Email
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
// POST: api/orders
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<OrderDto>> CreateOrder(OrderCreateDto dto)
|
||||
{
|
||||
var order = new Order
|
||||
{
|
||||
ProjectId = dto.ProjectId,
|
||||
Auftragsnummer = dto.Auftragsnummer,
|
||||
Titel = dto.Titel,
|
||||
Status = dto.Status,
|
||||
Planstunden = dto.Planstunden,
|
||||
Iststunden = 0,
|
||||
MandantId = dto.MandantId,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.Orders.Add(order);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Mitarbeiter zuordnen
|
||||
if (dto.UserIds != null && dto.UserIds.Any())
|
||||
{
|
||||
var relations = dto.UserIds.Select(uid => new OrderUser
|
||||
{
|
||||
OrderId = order.Id,
|
||||
UserId = uid
|
||||
});
|
||||
|
||||
_context.OrderUsers.AddRange(relations);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Antwort zusammenbauen
|
||||
var createdDto = new OrderDto
|
||||
{
|
||||
Id = order.Id,
|
||||
ProjectId = order.ProjectId,
|
||||
Auftragsnummer = order.Auftragsnummer,
|
||||
Titel = order.Titel,
|
||||
Status = order.Status,
|
||||
Planstunden = order.Planstunden,
|
||||
Iststunden = order.Iststunden,
|
||||
MandantId = order.MandantId,
|
||||
CreatedAt = order.CreatedAt,
|
||||
UpdatedAt = order.UpdatedAt
|
||||
};
|
||||
|
||||
return CreatedAtAction(nameof(GetOrder), new { id = order.Id }, createdDto);
|
||||
}
|
||||
|
||||
//PUT: api/orders/5
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateOrder(int id, OrderDto dto)
|
||||
{
|
||||
var order = await _context.Orders.FindAsync(id);
|
||||
if (order == null) return NotFound();
|
||||
|
||||
order.Titel = dto.Titel;
|
||||
order.Status = dto.Status;
|
||||
order.Planstunden = dto.Planstunden;
|
||||
order.Iststunden = dto.Iststunden;
|
||||
order.Projektcode = dto.Projektcode;
|
||||
order.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// DELETE: api/orders/5
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteOrder(int id)
|
||||
{
|
||||
var order = await _context.Orders
|
||||
.Include(o => o.OrderUsers)
|
||||
.FirstOrDefaultAsync(o => o.Id == id);
|
||||
|
||||
if (order == null)
|
||||
return NotFound();
|
||||
|
||||
_context.OrderUsers.RemoveRange(order.OrderUsers);
|
||||
_context.Orders.Remove(order);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private int GetCurrentUserId()
|
||||
{
|
||||
var userIdClaim = User.FindFirst("UserId")?.Value;
|
||||
if (string.IsNullOrEmpty(userIdClaim))
|
||||
throw new UnauthorizedAccessException("Kein User-Claim im Token gefunden.");
|
||||
|
||||
return int.Parse(userIdClaim);
|
||||
}
|
||||
|
||||
[HttpGet("mine")]
|
||||
public async Task<ActionResult<IEnumerable<OrderDto>>> GetMyOrders()
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
|
||||
var orders = await _context.Orders
|
||||
.Include(o => o.OrderUsers)
|
||||
.ThenInclude(ou => ou.User)
|
||||
.Where(o => o.OrderUsers.Any(ou => ou.UserId == userId))
|
||||
.AsNoTracking()
|
||||
.Select(o => new OrderDto
|
||||
{
|
||||
Id = o.Id,
|
||||
ProjectId = o.ProjectId,
|
||||
Auftragsnummer = o.Auftragsnummer,
|
||||
Titel = o.Titel,
|
||||
Status = o.Status,
|
||||
Planstunden = o.Planstunden,
|
||||
Iststunden = o.Iststunden,
|
||||
Projektcode = o.Projektcode,
|
||||
MandantId = o.MandantId,
|
||||
CreatedAt = o.CreatedAt,
|
||||
UpdatedAt = o.UpdatedAt,
|
||||
Mitarbeiter = o.OrderUsers
|
||||
.Select(ou => new UserDto
|
||||
{
|
||||
Id = ou.User!.Id,
|
||||
Username = ou.User.Username,
|
||||
FirstName = ou.User.FirstName,
|
||||
LastName = ou.User.LastName,
|
||||
Email = ou.User.Email
|
||||
}).ToList()
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(orders);
|
||||
}
|
||||
}
|
||||
}
|
||||
147
OnProfNext.Server/Controllers/ProjectsController.cs
Normal file
147
OnProfNext.Server/Controllers/ProjectsController.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Data;
|
||||
using OnProfNext.Shared.Models;
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
|
||||
namespace OnProfNext.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ProjectsController : ControllerBase
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public ProjectsController(AppDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
//GET api/project
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<ProjectDto>>> GetProjects()
|
||||
{
|
||||
var projects = await _context.Set<Project>().Include(p => p.ProjectUsers).ThenInclude(pu => pu.User).ToListAsync();
|
||||
|
||||
var result = projects.Select(p => new ProjectDto
|
||||
{
|
||||
Id = p.Id,
|
||||
ProjectName = p.ProjectName,
|
||||
Description = p.Description,
|
||||
Status = p.Status,
|
||||
StartDate = p.StartDate,
|
||||
EndDate = p.EndDate,
|
||||
MandantId = p.MandantId,
|
||||
CreatedAt = p.CreatedAt,
|
||||
UpdatedAt = p.UpdatedAt,
|
||||
ProjectManagers = p.ProjectUsers
|
||||
.Select(pu => new UserShortDto
|
||||
{
|
||||
Id = pu.User.Id,
|
||||
Username = pu.User.Username,
|
||||
FirstName = pu.User.FirstName,
|
||||
LastName = pu.User.LastName
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
//GET: api/project/5
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<Project>> GetProject(int id)
|
||||
{
|
||||
var project = await _context.Set<Project>().FindAsync(id);
|
||||
if (project == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
//POST : api/project
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ProjectDto>> CreateProject(ProjectCreateDto dto)
|
||||
{
|
||||
var project = new Project
|
||||
{
|
||||
ProjectName = dto.ProjectName,
|
||||
Description = dto.Description,
|
||||
Status = dto.Status,
|
||||
StartDate = dto.StartDate,
|
||||
EndDate = dto.EndDate,
|
||||
MandantId = dto.MandantId,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.Projects.Add(project);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Relationseinträge hinzufügen
|
||||
foreach (var userId in dto.ProjectManagerIds)
|
||||
{
|
||||
_context.ProjectUsers.Add(new ProjectUser
|
||||
{
|
||||
ProjectId = project.Id,
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return CreatedAtAction(nameof(GetProjects), new { id = project.Id }, dto);
|
||||
}
|
||||
|
||||
//PUT: api/project/5
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateProject(int id, ProjectCreateDto dto)
|
||||
{
|
||||
var project = await _context.Projects
|
||||
.Include(p => p.ProjectUsers)
|
||||
.FirstOrDefaultAsync(p => p.Id == id);
|
||||
|
||||
if (project == null)
|
||||
return NotFound();
|
||||
|
||||
// Grunddaten aktualisieren
|
||||
project.ProjectName = dto.ProjectName;
|
||||
project.Description = dto.Description;
|
||||
project.Status = dto.Status;
|
||||
project.StartDate = dto.StartDate;
|
||||
project.EndDate = dto.EndDate;
|
||||
project.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
// Projektleiter aktualisieren
|
||||
project.ProjectUsers.Clear();
|
||||
foreach (var userId in dto.ProjectManagerIds)
|
||||
{
|
||||
project.ProjectUsers.Add(new ProjectUser
|
||||
{
|
||||
ProjectId = project.Id,
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
//DELETE: api/project/5
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteProject(int id)
|
||||
{
|
||||
var project = await _context.Projects.FindAsync(id);
|
||||
if (project == null)
|
||||
return NotFound();
|
||||
|
||||
_context.Projects.Remove(project);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Data;
|
||||
using OnProfNext.Server.Services;
|
||||
using OnProfNext.Shared.Models;
|
||||
using OnProfNext.Shared.Models.DTOs;
|
||||
|
||||
namespace OnProfNext.Server.Controllers
|
||||
{
|
||||
@@ -21,24 +23,49 @@ namespace OnProfNext.Server.Controllers
|
||||
//GET: api/users
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
|
||||
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers()
|
||||
{
|
||||
return await _context.Users.AsNoTracking().ToListAsync();
|
||||
var users = await _context.Users.AsNoTracking().Select(u => new UserDto
|
||||
{
|
||||
Id = u.Id,
|
||||
Username = u.Username,
|
||||
Email = u.Email,
|
||||
FirstName = u.FirstName,
|
||||
LastName = u.LastName,
|
||||
MandantId = u.MandantId,
|
||||
IsActive = u.IsActive
|
||||
}).ToListAsync();
|
||||
|
||||
return Ok(users);
|
||||
}
|
||||
|
||||
//GET: api/users/5
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<User>> GetUser(int id)
|
||||
public async Task<ActionResult<UserDto>> GetUser(int id)
|
||||
{
|
||||
var user = await _context.Users.FindAsync(id);
|
||||
var user = await _context.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Id == id)
|
||||
.Select(u => new UserDto
|
||||
{
|
||||
Id = u.Id,
|
||||
Username = u.Username,
|
||||
Email = u.Email,
|
||||
FirstName = u.FirstName,
|
||||
LastName = u.LastName,
|
||||
MandantId = u.MandantId,
|
||||
IsActive = u.IsActive
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return user;
|
||||
|
||||
return Ok(user);
|
||||
}
|
||||
|
||||
//POST: api/users
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<User>> CreateUser(User user)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OnProfNext.Server.Configurations;
|
||||
using OnProfNext.Server.Data.Configurations;
|
||||
using OnProfNext.Shared.Models;
|
||||
|
||||
namespace OnProfNext.Server.Data
|
||||
@@ -11,6 +12,11 @@ namespace OnProfNext.Server.Data
|
||||
}
|
||||
|
||||
public DbSet<User> Users => Set<User>();
|
||||
public DbSet<Project> Projects => Set<Project>();
|
||||
public DbSet<ProjectUser> ProjectUsers => Set<ProjectUser>();
|
||||
public DbSet<OrderUser> OrderUsers => Set<OrderUser>();
|
||||
public DbSet<Order> Orders => Set<Order>();
|
||||
public DbSet<Booking> Bookings => Set<Booking>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -18,6 +24,11 @@ namespace OnProfNext.Server.Data
|
||||
|
||||
//Leitet aus UserConfiguration die Konfiguration der User-Entität ab
|
||||
modelBuilder.ApplyConfiguration(new UserConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new ProjectConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new ProjectUserConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new OrderUserConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new OrderConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new BookingConfiguration());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
144
OnProfNext.Server/Migrations/20251014114821_AddProjectsTable.Designer.cs
generated
Normal file
144
OnProfNext.Server/Migrations/20251014114821_AddProjectsTable.Designer.cs
generated
Normal file
@@ -0,0 +1,144 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using OnProfNext.Server.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace OnProfNext.Server.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20251014114821_AddProjectsTable")]
|
||||
partial class AddProjectsTable
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("OnProfNext.Shared.Models.Project", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime2")
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<DateTime?>("EndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("MandantId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("ProjectManager")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<string>("ProjectName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)");
|
||||
|
||||
b.Property<DateTime>("StartDate")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime2")
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasDefaultValue("Geplant");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("datetime2")
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Projects", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OnProfNext.Shared.Models.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime2")
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bit")
|
||||
.HasDefaultValue(true);
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<int>("MandantId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("nvarchar(512)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("datetime2")
|
||||
.HasDefaultValueSql("SYSDATETIME()");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace OnProfNext.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddProjectsTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Projects",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ProjectName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: true),
|
||||
ProjectManager = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
|
||||
Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false, defaultValue: "Geplant"),
|
||||
StartDate = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "SYSDATETIME()"),
|
||||
EndDate = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||
MandantId = table.Column<int>(type: "int", nullable: false, defaultValue: 1),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "SYSDATETIME()"),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "SYSDATETIME()")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Projects", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Projects");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user