Compare commits

...

5 Commits

Author SHA1 Message Date
khwezi 73145fd360 Merge pull request 'Upgraded backend services' (#28) from ui-design into main
Reviewed-on: #28
2026-05-30 00:32:23 +02:00
Khwezi Mngoma 0a3dd61ce0 Upgraded backend services
continuous-integration/drone/pr Build is passing
2026-05-30 00:31:54 +02:00
khwezi 7f29680993 Merge pull request 'ui-design' (#18) from ui-design into main
Reviewed-on: #18
2026-05-24 11:30:13 +02:00
Khwezi Mngoma 2f8afc380e Light refactor
continuous-integration/drone/pr Build is passing
2026-05-24 11:29:49 +02:00
Khwezi Mngoma cda1d225bc Final design touches 2026-05-24 11:27:59 +02:00
7 changed files with 114 additions and 78 deletions
@@ -165,12 +165,21 @@
}
</button>
<a href="/profile" class="btn btn-dark rounded-pill px-3 py-1 d-inline-flex align-items-center gap-2 btn-sm fw-medium shadow-sm">
<a href="/profile" class="btn btn-dark rounded-pill px-3 py-1 d-none d-md-inline-flex align-items-center gap-2 btn-sm fw-medium shadow-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
<circle cx="12" cy="7" r="4" />
</svg>
Log In
LogIn
</a>
<a href="/profile" class="btn btn-sm btn-dark rounded-circle d-inline-flex d-md-none align-items-center justify-content-center border-0 p-0 shadow-sm"
style="width: 32px; height: 32px;"
aria-label="Log In">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
<circle cx="12" cy="7" r="4" />
</svg>
</a>
</div>
</div>
+59 -57
View File
@@ -21,64 +21,66 @@
<h5 class="fw-bold m-0">Order History</h5>
</div>
<div class="table-container-fixed">
<table class="table align-middle profile-table m-0">
<thead>
<tr>
<th class="text-uppercase text-muted col-order-id">Order ID</th>
<th class="text-uppercase text-muted col-title">Title</th>
<th class="text-uppercase text-muted col-date">Date</th>
<th class="text-uppercase text-muted col-address">Address</th>
<th class="text-uppercase text-muted col-status">Status</th>
<th class="text-uppercase text-muted text-end col-total">Total</th>
<th class="text-uppercase text-muted text-center col-invoice">Invoice</th>
</tr>
</thead>
<tbody>
@if (orderHistory != null)
{
@foreach (var order in orderHistory)
{
<tr>
<td class="fw-medium text-nowrap">@order.OrderId</td>
<td>
<a href="/products/@order.ProductId" class="product-link fw-medium text-nowrap" title="@order.ProductTitle">
@order.DisplayTitle
<div class="d-flex flex-column gap-3">
@if (orderHistory != null)
{
@foreach (var order in orderHistory)
{
<div class="card p-4 shadow-sm order-history-card">
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start gap-3">
<div class="flex-grow-1 w-100">
<div class="order-meta-track mb-2">
<div class="meta-item-id">
<span class="fw-bold text-dark">@order.OrderId</span>
</div>
<div class="meta-item-date">
<span class="text-muted small">@order.OrderDate.ToString("MMM dd, yyyy")</span>
</div>
<div class="meta-item-status">
<span class="badge @(order.Status?.ToLower() == "shipped" ? "status-shipped" : "status-delivered") text-uppercase">
@order.Status
</span>
</div>
</div>
<h6 class="mb-2">
<a href="/products/@order.ProductId" class="product-link fw-medium" title="@order.ProductTitle">
@order.ProductTitle
</a>
</td>
<td class="text-muted text-nowrap">@order.OrderDate.ToString("MMM dd, yyyy")</td>
<td>
<span class="text-secondary d-inline-flex align-items-center gap-1 text-nowrap">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="currentColor" class="me-1 text-muted flex-shrink-0">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
</svg>
@order.ShippingAddressName
</span>
</td>
<td>
<span class="badge @(order.Status?.ToLower() == "shipped" ? "status-shipped" : "status-delivered") text-uppercase text-nowrap">
@order.Status
</span>
</td>
<td class="text-end fw-medium text-nowrap">R @order.Total.ToString("N2")</td>
<td class="text-center">
<button class="btn btn-link p-0 text-dark action-btn" title="Download Invoice" @onclick="() => DownloadInvoice(order.OrderId)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="svg-icon">
<path d="M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67l2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2v9.67z" />
</svg>
</button>
</td>
</tr>
}
}
else
{
<tr>
<td colspan="7" class="text-center text-muted py-4">Loading order history...</td>
</tr>
}
</tbody>
</table>
</h6>
<div class="d-flex align-items-center text-secondary small">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="currentColor" class="me-1 text-muted flex-shrink-0">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
</svg>
<span class="text-muted">Shipped to:</span>&nbsp;@order.ShippingAddressName
</div>
</div>
<div class="d-flex flex-row flex-sm-column align-items-center align-items-sm-end justify-content-between w-100 w-sm-auto pt-2 pt-sm-0 border-top border-sm-top-0 border-light">
<div class="text-sm-end mb-sm-2">
<span class="text-muted xx-small d-block text-uppercase font-monospace tracking-wider">Total Paid</span>
<span class="fw-bold text-dark fs-5">R @order.Total.ToString("N2")</span>
</div>
<button class="btn btn-link p-0 text-dark action-btn mt-sm-1" title="Download Invoice" @onclick="() => DownloadInvoice(order.OrderId)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="svg-icon">
<path d="M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67l2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2v9.67z" />
</svg>
</button>
</div>
</div>
</div>
}
}
else
{
<div class="card p-4 text-center text-muted">
Loading order history...
</div>
}
</div>
</div>
@@ -176,3 +176,29 @@
cursor: pointer;
user-select: none;
}
/* Shared Card Styling Unification Rules */
.order-history-card {
transition: border-color 0.2s ease, box-shadow 0.2s ease;
border-radius: 0; /* Matches your address card configuration */
}
.order-history-card:hover {
border-color: rgba(0, 0, 0, 0.16);
}
/* Micro Typography Alignment */
.xx-small {
font-size: 0.65rem;
}
.tracking-wider {
letter-spacing: 0.05rem;
}
/* Responsive adjustments across layout break-points */
@media (max-width: 575.98px) {
.border-sm-top-0 {
border-top: 1px solid rgba(0, 0, 0, 0.06) !important;
}
}
+2 -1
View File
@@ -18,12 +18,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="LiteCharms.Features" Version="1.43.0" />
<PackageReference Include="LiteCharms.Features" Version="1.51.0" />
</ItemGroup>
<!-- UI -->
<ItemGroup>
<PackageReference Include="ANM.Blazored.Toast" Version="0.1.1" />
<PackageReference Include="LiteCharms.Features.MidrandBooks" Version="1.51.0" />
<!-- Global Usings -->
<Using Include="Blazored.Toast.Services" />
+8 -8
View File
@@ -1,5 +1,6 @@
using LiteCharms.Features.Extensions;
using LiteCharms.Features.Mediator;
using LiteCharms.Features.MidrandBooks.Extensions;
using MidrandBookshop.Components;
using static LiteCharms.Features.Extensions.Quartz;
@@ -11,22 +12,21 @@ builder.Services.AddRazorComponents()
builder.AddMonitoring();
builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddMediator();
builder.Services.AddMediator();
//builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(TelemetryPipelineBehavior<,>));
//builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingPipelineBehavior<,>));
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(TelemetryPipelineBehavior<,>));
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingPipelineBehavior<,>));
//builder.Services.AddSalesServiceBus();
//builder.Services.AddGeneralServiceBus();
builder.Services.AddQuartzSchedulerClient(MidrandShopSchedulerName, builder.Configuration);
//builder.Services.AddEmailServices(builder.Configuration);
//builder.Services.AddEmailServiceBus();
builder.Services.AddEmailServices(builder.Configuration);
builder.Services.AddEmailServiceBus();
builder.Services.AddShopServices();
builder.Services.AddMidrandShopDatabase(builder.Configuration);
builder.Services.AddMidrandShopPostgresHealthCheck();
//builder.Services.AddMidrandShopQuartzHealthCheck();
builder.Services.AddMidrandShopQuartzHealthCheck();
builder.Services.AddHealthChecksSupport(builder.Configuration);
var app = builder.Build();
+6 -8
View File
@@ -1,16 +1,14 @@
{
"Email": {
"Credentials": {
"Username": "shop@litecharms.co.za"
},
"Port": 465,
"Host": "mail.litecharms.co.za",
"UseSsl": true
"BookshopS3Settings": {
"ServiceUrl": "http://192.168.1.177:30900",
"Region": "garage",
"BucketName": "bookshop",
"CdnBaseUrl": "https://bookshop.cdn.khongisa.co.za"
},
"Monitoring": {
"ApiKey": "",
"Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889",
"ServiceName": "LiteCharms.Shop"
"ServiceName": "MidrandBooks.DEV"
},
"Logging": {
"LogLevel": {
+2 -2
View File
@@ -44,7 +44,7 @@ metadata:
name: midrandbooks
namespace: midrandbooks-uat
spec:
replicas: 1
replicas: 2
selector:
matchLabels:
app: midrandbooks
@@ -82,7 +82,7 @@ spec:
secretKeyRef:
name: midrandbooks-secrets
key: connection-string-quartz
- name: ConnectionStrings__PostgresMidrandShop
- name: ConnectionStrings__PostgresMidrandBooks
valueFrom:
secretKeyRef:
name: midrandbooks-secrets