## Product Variations System - Add ProductVariation model with quantity-based pricing (1 for £10, 2 for £19, 3 for £25) - Complete CRUD operations for product variations - Enhanced ProductService to include variations in all queries - Updated OrderItem to support ProductVariationId for variation-based orders - Graceful error handling for duplicate quantity constraints - Admin interface with variations management (Create/Edit/Delete) - API endpoints for programmatic variation management ## Enhanced Order Workflow Management - Redesigned OrderStatus enum with clear workflow states (Accept → Packing → Dispatched → Delivered) - Added workflow tracking fields (AcceptedAt, PackingStartedAt, DispatchedAt, ExpectedDeliveryDate) - User tracking for accountability (AcceptedByUser, PackedByUser, DispatchedByUser) - Automatic delivery date calculation (dispatch date + working days, skips weekends) - On Hold workflow for problem resolution with reason tracking - Tab-based orders interface focused on workflow stages - One-click workflow actions from list view ## Mobile-Responsive Design - Responsive orders interface: tables on desktop, cards on mobile - Touch-friendly buttons and spacing for mobile users - Horizontal scrolling tabs with condensed labels on mobile - Color-coded status borders for quick visual recognition - Smart text switching based on screen size ## Product Import/Export System - CSV import with product variations support - Template download with examples - Export existing products to CSV - Detailed import results with success/error reporting - Category name resolution (no need for GUIDs) - Photo URLs import support ## Enhanced Dashboard - Product variations count and metrics - Stock alerts (low stock/out of stock warnings) - Order workflow breakdown (pending, accepted, dispatched counts) - Enhanced layout with more detailed information ## Technical Improvements - Fixed form binding issues across all admin forms - Removed external CDN dependencies for isolated deployment - Bot Wizard form with auto-personality assignment - Proper authentication scheme configuration (Cookie + JWT) - Enhanced debug logging for troubleshooting ## Self-Contained Deployment - All external CDN references replaced with local libraries - Ready for air-gapped/isolated network deployment - No external internet dependencies 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
176 lines
6.4 KiB
Plaintext
176 lines
6.4 KiB
Plaintext
@{
|
|
ViewData["Title"] = "Dashboard";
|
|
}
|
|
|
|
<div class="row mb-4">
|
|
<div class="col">
|
|
<h1><i class="fas fa-tachometer-alt"></i> Dashboard</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-primary mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-shopping-cart"></i> Total Orders
|
|
</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title">@ViewData["TotalOrders"]</h4>
|
|
<small>@ViewData["PendingOrders"] pending • @ViewData["ShippedOrders"] shipped</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-success mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-box"></i> Total Products
|
|
</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title">@ViewData["TotalProducts"]</h4>
|
|
<small>@ViewData["TotalVariations"] variations • @ViewData["TotalStock"] in stock</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-info mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-tags"></i> Categories
|
|
</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title">@ViewData["TotalCategories"]</h4>
|
|
<small>Active categories</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-warning mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-pound-sign"></i> Total Revenue
|
|
</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title">£@ViewData["TotalRevenue"]</h4>
|
|
<small>From completed orders</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-danger mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-exclamation-triangle"></i> Stock Alerts
|
|
</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title">@ViewData["LowStockProducts"]</h4>
|
|
<small>@ViewData["OutOfStockProducts"] out of stock</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-9">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5><i class="fas fa-list"></i> Product Variations Summary</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
@if ((int)ViewData["TotalVariations"] > 0)
|
|
{
|
|
<div class="alert alert-success">
|
|
<i class="fas fa-check-circle"></i>
|
|
<strong>@ViewData["TotalVariations"] product variations</strong> have been configured across your catalog.
|
|
Customers can now choose quantity-based pricing options!
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="alert alert-info">
|
|
<i class="fas fa-info-circle"></i>
|
|
No product variations configured yet.
|
|
<a href="@Url.Action("Index", "Products")" class="alert-link">Add variations</a>
|
|
to offer quantity-based pricing (e.g., 1 for £10, 2 for £19, 3 for £25).
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5><i class="fas fa-chart-line"></i> Quick Actions</h5>
|
|
<button id="pwa-install-dashboard" class="btn btn-sm btn-outline-primary" style="float: right;">
|
|
<i class="fas fa-mobile-alt"></i> Install App
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="list-group list-group-flush">
|
|
<a href="@Url.Action("Create", "Products")" class="list-group-item list-group-item-action">
|
|
<i class="fas fa-plus"></i> Add New Product
|
|
</a>
|
|
<a href="@Url.Action("Create", "Categories")" class="list-group-item list-group-item-action">
|
|
<i class="fas fa-plus"></i> Add New Category
|
|
</a>
|
|
<a href="@Url.Action("Index", "Orders")" class="list-group-item list-group-item-action">
|
|
<i class="fas fa-list"></i> View All Orders
|
|
</a>
|
|
<a href="@Url.Action("Create", "Users")" class="list-group-item list-group-item-action">
|
|
<i class="fas fa-user-plus"></i> Add New User
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5><i class="fas fa-info-circle"></i> System Information</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="list-unstyled">
|
|
<li><strong>Framework:</strong> .NET 9.0</li>
|
|
<li><strong>Database:</strong> SQLite</li>
|
|
<li><strong>Authentication:</strong> Cookie-based</li>
|
|
<li><strong>Crypto Support:</strong> 8 currencies via BTCPay Server</li>
|
|
<li><strong>API Endpoints:</strong> Available for client integration</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const installBtn = document.getElementById('pwa-install-dashboard');
|
|
if (installBtn) {
|
|
installBtn.addEventListener('click', function() {
|
|
// Check if app is in standalone mode
|
|
if (window.matchMedia('(display-mode: standalone)').matches) {
|
|
alert('App is already installed!');
|
|
return;
|
|
}
|
|
|
|
// Show manual install instructions
|
|
alert(`To install LittleShop Admin as an app:
|
|
|
|
🌐 Chrome/Edge:
|
|
1. Click the install icon (⊞) in the address bar, OR
|
|
2. Menu (⋮) → "Install LittleShop Admin"
|
|
|
|
🍎 Safari (iOS):
|
|
1. Share button → "Add to Home Screen"
|
|
|
|
📱 Mobile browsers:
|
|
1. Browser menu → "Add to Home Screen"
|
|
|
|
The app will then work offline and appear in your apps list!`);
|
|
});
|
|
}
|
|
});
|
|
</script> |