Added service ordering and implemented basic service creation
This commit is contained in:
@@ -1,34 +1,49 @@
|
||||
@if (loaded)
|
||||
@if (Loaded)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex justify-content-center py-4">
|
||||
<span class="fs-1 spinner-border spinner-border-lg align-middle me-2"></span>
|
||||
<span class="mt-3 fs-5">@(Text)</span>
|
||||
</div>
|
||||
if (ShowAsCard)
|
||||
{
|
||||
<div class="card card-body">
|
||||
<div class="d-flex justify-content-center py-4">
|
||||
<span class="fs-1 spinner-border spinner-border-lg align-middle me-2"></span>
|
||||
<span class="mt-3 fs-5">@(Text)</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex justify-content-center py-4">
|
||||
<span class="fs-1 spinner-border spinner-border-lg align-middle me-2"></span>
|
||||
<span class="mt-3 fs-5">@(Text)</span>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
|
||||
[Parameter]
|
||||
public bool ShowAsCard { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public Func<LazyLoader, Task> Load { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Text { get; set; } = "";
|
||||
|
||||
private bool loaded = false;
|
||||
private bool Loaded = false;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await Load.Invoke(this);
|
||||
loaded = true;
|
||||
Loaded = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -41,10 +56,10 @@ else
|
||||
|
||||
public async Task Reload()
|
||||
{
|
||||
loaded = false;
|
||||
Loaded = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Load.Invoke(this);
|
||||
loaded = true;
|
||||
Loaded = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
101
Moonlight/Shared/Views/Services/Index.razor
Normal file
101
Moonlight/Shared/Views/Services/Index.razor
Normal file
@@ -0,0 +1,101 @@
|
||||
@page "/services"
|
||||
|
||||
@using Moonlight.App.Services.ServiceManage
|
||||
@using Moonlight.App.Database.Entities.Store
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject ServiceService ServiceService
|
||||
@inject IdentityService IdentityService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
<LazyLoader ShowAsCard="true" Load="Load">
|
||||
<div class="row mb-5">
|
||||
@foreach (var service in MyServices)
|
||||
{
|
||||
<div class="col-md-3 col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title align-items-start flex-column">
|
||||
<span class="card-label fw-bold text-dark fs-3">@(service.Nickname ?? $"Service {service.Id}")</span>
|
||||
<span class="text-gray-400 mt-1 fw-semibold fs-6">@(service.Product.Name)</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body fs-6">
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Price</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(ConfigService.Get().Store.Currency) @(service.Product.Price)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Renew at</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(Formatter.FormatDate(service.RenewAt))</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Created at</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(Formatter.FormatDate(service.CreatedAt))</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer p-3">
|
||||
<div class="btn-group w-100 mb-3">
|
||||
<button class="btn btn-primary w-50 me-3">Manage</button>
|
||||
<button class="btn btn-secondary w-50">Manage shares</button>
|
||||
</div>
|
||||
<div class="btn-group w-100">
|
||||
<button class="btn btn-warning w-50 me-3">Renew</button>
|
||||
<button class="btn btn-danger w-50">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@foreach (var service in SharedServices)
|
||||
{
|
||||
<div class="col-md-3 col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title align-items-start flex-column">
|
||||
<span class="card-label fw-bold text-dark fs-3">@(service.Nickname ?? $"Service {service.Id}")</span>
|
||||
<span class="text-gray-400 mt-1 fw-semibold fs-6">@(service.Product.Name)</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body fs-6">
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Shared by</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(service.Owner.Username)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Created at</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(Formatter.FormatDate(service.CreatedAt))</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer p-3 text-center">
|
||||
<button class="btn btn-primary">Manage</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</LazyLoader>
|
||||
|
||||
@code
|
||||
{
|
||||
private Service[] MyServices;
|
||||
private Service[] SharedServices;
|
||||
|
||||
private async Task Load(LazyLoader _)
|
||||
{
|
||||
MyServices = await ServiceService.Get(IdentityService.CurrentUser);
|
||||
SharedServices = await ServiceService.GetShared(IdentityService.CurrentUser);
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,14 @@
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Database.Entities.Store
|
||||
@using Moonlight.App.Repositories
|
||||
@using Moonlight.App.Services.ServiceManage
|
||||
|
||||
@inject ConfigService ConfigService
|
||||
@inject StoreService StoreService
|
||||
@inject IdentityService IdentityService
|
||||
@inject AlertService AlertService
|
||||
@inject NavigationManager Navigation
|
||||
@inject ServiceService ServiceService
|
||||
@inject Repository<Product> ProductRepository
|
||||
@inject Repository<Coupon> CouponRepository
|
||||
|
||||
@@ -73,7 +76,7 @@ TODO: Add 404 here
|
||||
actualPrice = defaultPrice;
|
||||
else
|
||||
actualPrice = Math.Round(defaultPrice * SelectedCoupon.Percent / 100, 2);
|
||||
|
||||
|
||||
var currency = ConfigService.Get().Store.Currency;
|
||||
}
|
||||
|
||||
@@ -81,7 +84,7 @@ TODO: Add 404 here
|
||||
<div class="d-flex flex-stack">
|
||||
<div class="text-gray-700 fw-semibold me-2">Today</div>
|
||||
<div class="d-flex align-items-senter">
|
||||
<span class="fw-bold">@(currency) @(defaultPrice)</span>
|
||||
<span class="fw-bold">@(currency) @(actualPrice)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-stack">
|
||||
@@ -136,7 +139,7 @@ TODO: Add 404 here
|
||||
{
|
||||
if (CanBeOrdered)
|
||||
{
|
||||
<button class="btn btn-primary w-100">Order for @(currency) @(actualPrice)</button>
|
||||
<WButton OnClick="OnSubmit" Text="@($"Order for {currency} {actualPrice}")" CssClasses="btn btn-primary w-100"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -161,7 +164,7 @@ TODO: Add 404 here
|
||||
private int DurationMultiplicator = 1;
|
||||
|
||||
private string CouponCode = "";
|
||||
|
||||
|
||||
private bool CanBeOrdered = false;
|
||||
private bool IsValidating = false;
|
||||
private string ErrorMessage = "";
|
||||
@@ -227,4 +230,22 @@ TODO: Add 404 here
|
||||
|
||||
await Revalidate();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
if (SelectedProduct == null) // Prevent processing null
|
||||
return;
|
||||
|
||||
// Process the order with the selected values
|
||||
var service = await StoreService
|
||||
.Order
|
||||
.Process(
|
||||
IdentityService.CurrentUser,
|
||||
SelectedProduct,
|
||||
DurationMultiplicator,
|
||||
SelectedCoupon
|
||||
);
|
||||
|
||||
Navigation.NavigateTo("/service/" + service.Id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user