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>
150 lines
5.5 KiB
Plaintext
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> |