littleshop/LittleShop/Views/BotDirectory/Index.cshtml
SysAdmin 034b8facee Implement product multi-buys and variants system
Major restructuring of product variations:
- Renamed ProductVariation to ProductMultiBuy for quantity-based pricing (e.g., "3 for £25")
- Added new ProductVariant model for string-based options (colors, flavors)
- Complete separation of multi-buy pricing from variant selection

Features implemented:
- Multi-buy deals with automatic price-per-unit calculation
- Product variants for colors/flavors/sizes with stock tracking
- TeleBot checkout supports both multi-buys and variant selection
- Shopping cart correctly calculates multi-buy bundle prices
- Order system tracks selected variants and multi-buy choices
- Real-time bot activity monitoring with SignalR
- Public bot directory page with QR codes for Telegram launch
- Admin dashboard shows multi-buy and variant metrics

Technical changes:
- Updated all DTOs, services, and controllers
- Fixed cart total calculation for multi-buy bundles
- Comprehensive test coverage for new functionality
- All existing tests passing with new features

Database changes:
- Migrated ProductVariations to ProductMultiBuys
- Added ProductVariants table
- Updated OrderItems to track variants

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-21 00:30:12 +01:00

150 lines
5.5 KiB
Plaintext

@model List<LittleShop.Controllers.BotDirectoryDto>
@{
ViewData["Title"] = "Bot Directory";
Layout = "_PublicLayout";
}
<div class="container mt-4">
<div class="row">
<div class="col-12">
<h1 class="display-4 text-center mb-4">
<i class="bi bi-robot"></i> Shop Assistant Bots
</h1>
<p class="text-center text-muted mb-5">
Connect with our shopping assistant bots on Telegram. Scan the QR code or click the username to start chatting!
</p>
</div>
</div>
<div class="row g-4">
@foreach (var bot in Model)
{
<div class="col-md-6 col-lg-4">
<div class="card h-100 shadow-sm bot-card">
<div class="card-header bg-gradient text-white" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
<div class="d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="bi bi-robot"></i> @bot.Name
</h5>
<span class="badge bg-@bot.GetBadgeColor()">@bot.Type</span>
</div>
</div>
<div class="card-body">
<div class="text-center mb-3">
@if (!string.IsNullOrEmpty(bot.TelegramUsername))
{
<img src="/bots/qr/@bot.Id" alt="QR Code for @bot.Name" class="img-fluid qr-code" style="max-width: 200px;" />
<div class="mt-3">
<a href="https://t.me/@bot.TelegramUsername" target="_blank" class="btn btn-primary btn-lg">
<i class="bi bi-telegram"></i> @@@bot.TelegramUsername
</a>
</div>
}
else
{
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle"></i> Bot configuration pending
</div>
}
</div>
@if (!string.IsNullOrEmpty(bot.Description))
{
<p class="text-muted">@bot.Description</p>
}
@if (!string.IsNullOrEmpty(bot.PersonalityName))
{
<p class="mb-2">
<small class="text-muted">
<i class="bi bi-person-badge"></i> Personality: <strong>@bot.PersonalityName</strong>
</small>
</p>
}
<div class="d-flex justify-content-between align-items-center mt-3">
<span class="badge bg-@bot.GetStatusColor()">
<i class="bi bi-circle-fill"></i> @bot.GetStatusBadge()
</span>
<small class="text-muted">
Since @bot.CreatedAt.ToString("MMM dd, yyyy")
</small>
</div>
</div>
</div>
</div>
}
@if (!Model.Any())
{
<div class="col-12">
<div class="alert alert-info text-center">
<h4 class="alert-heading">No Bots Available</h4>
<p>There are currently no active bots in the directory. Please check back later!</p>
</div>
</div>
}
</div>
<div class="row mt-5">
<div class="col-12">
<div class="card bg-light">
<div class="card-body text-center">
<h5 class="card-title">How to Connect</h5>
<ol class="text-start" style="max-width: 600px; margin: 0 auto;">
<li>Open Telegram on your mobile device</li>
<li>Scan the QR code with your camera or click the bot username</li>
<li>Press "Start" to begin chatting with the bot</li>
<li>Browse products, add items to cart, and checkout securely</li>
</ol>
<hr>
<p class="text-muted mb-0">
<i class="bi bi-shield-check"></i> All transactions are secure and encrypted
</p>
</div>
</div>
</div>
</div>
</div>
<style>
.bot-card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
border: none;
overflow: hidden;
}
.bot-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.15) !important;
}
.qr-code {
border: 4px solid #f8f9fa;
border-radius: 8px;
padding: 10px;
background: white;
}
.badge {
font-weight: 500;
}
@@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(102, 126, 234, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(102, 126, 234, 0);
}
}
.btn-primary {
animation: pulse 2s infinite;
}
</style>