f97f891d67
Full ASP.NET Core 10 Razor Pages app for آساد ابزار tool repair shop in Karaj, Iran (official DeWalt representative). Features: - Homepage, Services, DeWalt page, Shop (pagination + images) - 10 brand SEO pages (/brands/*) with rich Persian content + FAQ schema - Blog engine with admin management (/blog, /Admin/Blog) - Cart, Checkout, Contact (OpenStreetMap embed) - Admin panel: Products CRUD, Orders, Blog, Change Password - Jalali date formatting, product images, SiteData centralised contact - Docker + docker-compose with healthcheck - Gitea CI/CD via .gitea/workflows/ci-cd.yml (NuGet through Nexus mirror) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
4.0 KiB
Plaintext
75 lines
4.0 KiB
Plaintext
@page
|
|
@model AsadiTools.Pages.Shop.DetailModel
|
|
@{ ViewData["Title"] = Model.Product?.NameFa ?? "قطعه"; Layout = "_Layout"; }
|
|
|
|
@if (Model.Product is null)
|
|
{
|
|
<div class="max-w-xl mx-auto text-center py-20"><p class="text-gray-500">محصول یافت نشد.</p><a href="/Shop" class="text-blue-600 hover:underline mt-2 block">بازگشت به فروشگاه</a></div>
|
|
}
|
|
else
|
|
{
|
|
var p = Model.Product;
|
|
var cat = SiteData.Categories.FirstOrDefault(c => c.Id == p.Category);
|
|
var brand = SiteData.Brands.FirstOrDefault(b => b.Id == p.Brand);
|
|
|
|
<div class="max-w-5xl mx-auto px-4 py-8">
|
|
<nav class="flex items-center gap-2 text-sm text-gray-500 mb-8">
|
|
<a href="/" class="hover:text-blue-600">خانه</a><span>/</span>
|
|
<a href="/Shop" class="hover:text-blue-600">فروشگاه</a><span>/</span>
|
|
<span class="text-gray-800">@p.NameFa</span>
|
|
</nav>
|
|
|
|
<div class="grid md:grid-cols-2 gap-10">
|
|
<div class="rounded-3xl overflow-hidden aspect-square @(string.IsNullOrEmpty(p.ImageUrl) ? "bg-gradient-to-br from-blue-50 to-blue-100 flex items-center justify-center text-8xl" : "")">
|
|
@if (!string.IsNullOrEmpty(p.ImageUrl))
|
|
{
|
|
<img src="@p.ImageUrl" alt="@p.NameFa" class="w-full h-full object-cover" />
|
|
}
|
|
else
|
|
{
|
|
@(cat?.Icon ?? "🔧")
|
|
}
|
|
</div>
|
|
<div>
|
|
<div class="flex flex-wrap gap-2 mb-4">
|
|
@if (brand != null) { <span class="text-sm font-bold px-3 py-1 rounded-full text-white" style="background-color:@brand.Color">@brand.NameFa</span> }
|
|
@if (cat != null) { <span class="text-sm px-3 py-1 rounded-full bg-gray-100 text-gray-600">@cat.Icon @cat.NameFa</span> }
|
|
</div>
|
|
<h1 class="text-2xl font-extrabold text-gray-900 mb-2">@p.NameFa</h1>
|
|
@if (p.NameEn != null) { <p class="text-gray-400 text-sm mb-4 font-mono">@p.NameEn</p> }
|
|
@if (p.Sku != null) { <p class="text-xs text-gray-400 mb-6 bg-gray-100 inline-block px-3 py-1 rounded-full">کد محصول: @p.Sku</p> }
|
|
@if (p.Description != null) { <p class="text-gray-600 leading-7 mb-6 text-sm">@p.Description</p> }
|
|
|
|
<div class="mb-6">
|
|
@if (p.HasDiscount) { <p class="text-gray-400 line-through text-lg">@SiteData.FormatPrice(p.Price)</p> }
|
|
<p class="text-3xl font-extrabold text-blue-700">@SiteData.FormatPrice(p.FinalPrice)</p>
|
|
</div>
|
|
|
|
<div class="mb-6">
|
|
@if (p.Stock > 0)
|
|
{
|
|
<span class="text-green-600 text-sm font-medium">🟢 موجود در انبار (@p.Stock عدد)</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="text-red-500 text-sm font-medium">🔴 ناموجود</span>
|
|
}
|
|
</div>
|
|
|
|
<form method="post" class="flex gap-3">
|
|
@Html.AntiForgeryToken()
|
|
<input type="hidden" name="productId" value="@p.Id" />
|
|
<input type="hidden" name="nameFa" value="@p.NameFa" />
|
|
<input type="hidden" name="price" value="@p.FinalPrice" />
|
|
<input type="hidden" name="sku" value="@p.Sku" />
|
|
<button type="submit" @(p.Stock == 0 ? "disabled" : "")
|
|
class="flex-1 flex items-center justify-center gap-2 bg-blue-700 text-white py-3.5 rounded-xl font-bold hover:bg-blue-800 transition-colors disabled:bg-gray-200 disabled:text-gray-400">
|
|
🛒 @(p.Stock == 0 ? "ناموجود" : "افزودن به سبد خرید")
|
|
</button>
|
|
<a href="/Cart" class="flex items-center gap-2 border-2 border-blue-700 text-blue-700 py-3.5 px-4 rounded-xl font-bold hover:bg-blue-50">سبد</a>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|