257 lines
10 KiB
Plaintext
257 lines
10 KiB
Plaintext
@page "/labs/add"
|
|
@page "/labs/{id:guid}"
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using Microsoft.AspNetCore.Components
|
|
|
|
<PageTitle>@Title</PageTitle>
|
|
|
|
<h1>@Title</h1>
|
|
@if (Lab != null)
|
|
{
|
|
<EditForm Model="@Lab" OnValidSubmit="@HandleValidSubmit" class="row g-3 mb-3">
|
|
<DataAnnotationsValidator/>
|
|
<ValidationSummary/>
|
|
<div class="col-lg-6 row g-lg-3 g-md-2 g-1 h-100">
|
|
<div class="col-12 form-floating">
|
|
<InputText @bind-Value="Lab.Name" id="inputName" class="form-control"/>
|
|
<label for="inputName">Name</label>
|
|
</div>
|
|
<div class="col-md-4 form-floating">
|
|
<InputText @bind-Value="Lab.Website" id="inputWebsite" class="form-control"/>
|
|
<label for="inputWebsite">Website</label>
|
|
</div>
|
|
<div class="col-md-4 form-floating">
|
|
<InputText @bind-Value="Lab.Phone" id="inputPhone" class="form-control"/>
|
|
<label for="inputPhone">Phone</label>
|
|
</div>
|
|
<div class="col-md-4 form-floating">
|
|
<InputText @bind-Value="Lab.Email" id="inputEmail" class="form-control"/>
|
|
<label for="inputEmail">Email</label>
|
|
</div>
|
|
<div class="col-12">
|
|
<label for="inputCountry">
|
|
Country
|
|
</label>
|
|
<InputSelect @bind-Value="SelectedCountryId" id="inputCountry" class="form-select">
|
|
@foreach (var country in Countries)
|
|
{
|
|
<option value="@country.Id.Value">@country.Name (@country.EnglishName)</option>
|
|
}
|
|
</InputSelect>
|
|
</div>
|
|
<div class="col-12 form-floating">
|
|
<InputText @bind-Value="Lab.AddressLine1" id="inputAddressLine1" class="form-control"/>
|
|
<label for="inputAddressLine1">Address line 1</label>
|
|
</div>
|
|
<div class="col-12 form-floating">
|
|
<InputText @bind-Value="Lab.AddressLine2" id="inputAddressLine2" class="form-control"/>
|
|
<label for="inputAddressLine2">Address line 2</label>
|
|
</div>
|
|
<div class="col-md-6 form-floating">
|
|
<InputText @bind-Value="Lab.AddressPostcode" id="inputPostcode" class="form-control"/>
|
|
<label for="inputPostcode">Postcode</label>
|
|
</div>
|
|
<div class="col-md-6 form-floating">
|
|
<InputText @bind-Value="Lab.AddressCity" id="inputCity" class="form-control"/>
|
|
<label for="inputCity">City</label>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
<InputCheckbox @bind-Value="Lab.RequiresAppointment" id="inputRequiresAppointment" class="form-check-input"/>
|
|
<label for="inputRequiresAppointment" class="form-check-label">Requires appointment</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
<InputCheckbox @bind-Value="Lab.SelfDraw" id="inputSelfDraw" class="form-check-input"/>
|
|
<label for="inputSelfDraw" class="form-check-label">Self draw blood</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 form-floating">
|
|
<InputNumber @bind-Value="Lab.BasicFee" id="inputBasicFee" class="form-control"/>
|
|
<label for="inputBasicFee">Basic fee (€)</label>
|
|
</div>
|
|
<div class="col-md-6 form-floating">
|
|
<InputNumber @bind-Value="Lab.DrawFee" id="inputDrawFee" class="form-control"/>
|
|
<label for="inputDrawFee">Blood draw fee (€)</label>
|
|
</div>
|
|
|
|
<div class="col-12 form-floating">
|
|
<InputTextArea @bind-Value="Lab.Notes" id="inputNotes" class="form-control" style="height: 100px"/>
|
|
<label for="inputNotes">Notes</label>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="col-lg-6 row g-lg-3 g-md-2 g-1">
|
|
@foreach (var test in Tests)
|
|
{
|
|
var offer = Lab.TestOffers.FirstOrDefault(x => x.TestId == test.Id);
|
|
<div class="card">
|
|
<div class="card-body">
|
|
@if (offer == null)
|
|
{
|
|
<button class="btn btn-success float-end" type="button" @onclick="() => AddOffer(test)">Add</button>
|
|
}
|
|
else
|
|
{
|
|
<button class="btn btn-danger float-end" type="button" @onclick="() => RemoveOffer(offer)">Remove</button>
|
|
}
|
|
<h5 class="card-title">@test.Abbreviation</h5>
|
|
<h6 class="card-subtitle mb-2 text-muted">@test.Name</h6>
|
|
@if (offer != null)
|
|
{
|
|
<div class="row g-1">
|
|
<div class="col-md-6 form-floating">
|
|
<InputNumber @bind-Value="offer.Price" id="@($"inputPrice-{offer.Id.Value}")" class="form-control"/>
|
|
<label for="@($"inputPrice-{offer.Id.Value}")">Price (€)</label>
|
|
</div>
|
|
<div class="col-md-6 form-floating">
|
|
<InputNumber @bind-Value="offer.BloodVolume" id="@($"inputBloodVolume-{offer.Id.Value}")" class="form-control"/>
|
|
<label for="@($"inputBloodVolume-{offer.Id.Value}")">Blood Volume (mL)</label>
|
|
</div>
|
|
<div class="col-12 form-floating">
|
|
<InputText @bind-Value="offer.ServiceDirectoryLink" id="@($"inputServiceDirectoryLink-{offer.Id.Value}")" class="form-control"/>
|
|
<label for="@($"inputServiceDirectoryLink-{offer.Id.Value}")">Leistungsverzeichnis-Link</label>
|
|
</div>
|
|
<div class="col-12 form-floating">
|
|
<InputText @bind-Value="offer.TestMethod" id="@($"inputTestMethod-{offer.Id.Value}")" class="form-control"/>
|
|
<label for="@($"inputTestMethod-{offer.Id.Value}")">Method</label>
|
|
</div>
|
|
<div class="col-12 form-floating">
|
|
<InputTextArea @bind-Value="offer.Notes" id="@($"inputNotes-{offer.Id.Value}")" class="form-control"/>
|
|
<label for="@($"inputNotes-{offer.Id.Value}")">Notes</label>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="col-12">
|
|
<button type="submit" class="btn btn-primary">Save</button>
|
|
<button type="button" class="btn btn-danger float-end" @onclick="() => ShowDeleteModal = true">Delete</button>
|
|
</div>
|
|
</EditForm>
|
|
}
|
|
else
|
|
{
|
|
<h1>NOT FOUND</h1>
|
|
}
|
|
|
|
@if (ShowDeleteModal)
|
|
{
|
|
<div class="modal show" tabindex="-1" style="display: block;">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Really delete this lab?</h5>
|
|
<button type="button" class="btn-close" @onclick="() => ShowDeleteModal = false" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Deleted labs cannot be recovered.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" @onclick="() => ShowDeleteModal = false">Abort</button>
|
|
<button type="button" class="btn btn-danger" @onclick="DeleteLab">Delete</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-backdrop fade show"></div>
|
|
}
|
|
|
|
|
|
@code {
|
|
|
|
[Inject]
|
|
public NavigationManager NavigationManager { get; set; } = null!;
|
|
|
|
[Inject]
|
|
public IDbContextFactory<AppDbContext> DbContextFactory { get; set; } = null!;
|
|
|
|
|
|
[Parameter]
|
|
public Guid? Id { get; set; }
|
|
|
|
private Lab? Lab { get; set; }
|
|
|
|
private List<Country> Countries { get; set; } = new();
|
|
|
|
private List<Test> Tests { get; set; } = new();
|
|
|
|
private string Title => Id == null ? "Add lab" : "Edit lab";
|
|
|
|
private Guid SelectedCountryId
|
|
{
|
|
get => Lab?.CountryId.Value ?? Guid.Empty;
|
|
set => Lab!.CountryId = CountryId.FromGuid(value);
|
|
}
|
|
|
|
private List<TestOffer> NewOffers { get; set; } = new();
|
|
private List<TestOffer> RemovedOffers { get; set; } = new();
|
|
|
|
private bool ShowDeleteModal { get; set; }
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
base.OnInitialized();
|
|
using var ctx = DbContextFactory.CreateDbContext();
|
|
|
|
Countries = ctx.Set<Country>().ToList();
|
|
Tests = ctx.Set<Test>().ToList();
|
|
|
|
if (Id != null)
|
|
{
|
|
Lab = ctx.Set<Lab>()
|
|
.Include(x => x.TestOffers)
|
|
.First(x => x.Id == LabId.FromGuid(Id.Value));
|
|
Lab.Country = null!; // this seems super hacky, wtf
|
|
}
|
|
else
|
|
{
|
|
Lab = new Lab { CountryId = Countries.First().Id };
|
|
}
|
|
}
|
|
|
|
private void HandleValidSubmit()
|
|
{
|
|
using var ctx = DbContextFactory.CreateDbContext();
|
|
if (Id == null)
|
|
{
|
|
ctx.Add(Lab!);
|
|
}
|
|
else
|
|
{
|
|
ctx.Update(Lab!);
|
|
}
|
|
ctx.AddRange(NewOffers);
|
|
ctx.RemoveRange(RemovedOffers);
|
|
ctx.SaveChanges();
|
|
NavigationManager.NavigateTo("/labs");
|
|
}
|
|
|
|
private void AddOffer(Test test)
|
|
{
|
|
var offer = new TestOffer { TestId = test.Id };
|
|
Lab!.TestOffers.Add(offer);
|
|
NewOffers.Add(offer);
|
|
}
|
|
|
|
private void RemoveOffer(TestOffer offer)
|
|
{
|
|
Lab!.TestOffers.Remove(offer);
|
|
RemovedOffers.Add(offer);
|
|
}
|
|
|
|
private void DeleteLab()
|
|
{
|
|
using var ctx = DbContextFactory.CreateDbContext();
|
|
ctx.RemoveRange(Lab!.TestOffers);
|
|
ctx.Remove(Lab!);
|
|
ctx.SaveChanges();
|
|
NavigationManager.NavigateTo("/labs");
|
|
}
|
|
|
|
} |