## 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>
51 lines
2.0 KiB
C#
51 lines
2.0 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using LittleShop.Services;
|
|
|
|
namespace LittleShop.Areas.Admin.Controllers;
|
|
|
|
[Area("Admin")]
|
|
[Authorize(Policy = "AdminOnly")]
|
|
public class DashboardController : Controller
|
|
{
|
|
private readonly IOrderService _orderService;
|
|
private readonly IProductService _productService;
|
|
private readonly ICategoryService _categoryService;
|
|
|
|
public DashboardController(
|
|
IOrderService orderService,
|
|
IProductService productService,
|
|
ICategoryService categoryService)
|
|
{
|
|
_orderService = orderService;
|
|
_productService = productService;
|
|
_categoryService = categoryService;
|
|
}
|
|
|
|
public async Task<IActionResult> Index()
|
|
{
|
|
var orders = await _orderService.GetAllOrdersAsync();
|
|
var products = await _productService.GetAllProductsAsync();
|
|
var categories = await _categoryService.GetAllCategoriesAsync();
|
|
|
|
// Basic metrics
|
|
ViewData["TotalOrders"] = orders.Count();
|
|
ViewData["TotalProducts"] = products.Count();
|
|
ViewData["TotalCategories"] = categories.Count();
|
|
ViewData["TotalRevenue"] = orders.Where(o => o.PaidAt.HasValue).Sum(o => o.TotalAmount).ToString("F2");
|
|
|
|
// Enhanced metrics
|
|
ViewData["TotalVariations"] = products.Sum(p => p.Variations.Count);
|
|
ViewData["PendingOrders"] = orders.Count(o => o.Status == LittleShop.Enums.OrderStatus.PendingPayment);
|
|
ViewData["ShippedOrders"] = orders.Count(o => o.Status == LittleShop.Enums.OrderStatus.Shipped);
|
|
ViewData["TotalStock"] = products.Sum(p => p.StockQuantity);
|
|
ViewData["LowStockProducts"] = products.Count(p => p.StockQuantity < 10);
|
|
ViewData["OutOfStockProducts"] = products.Count(p => p.StockQuantity == 0);
|
|
|
|
// Recent activity
|
|
ViewData["RecentOrders"] = orders.OrderByDescending(o => o.CreatedAt).Take(5);
|
|
ViewData["TopProducts"] = products.OrderByDescending(p => p.StockQuantity).Take(5);
|
|
|
|
return View();
|
|
}
|
|
} |