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>
71 lines
4.3 KiB
Plaintext
71 lines
4.3 KiB
Plaintext
@page
|
||
@model AsadiTools.Pages.Admin.Products.ProductsIndexModel
|
||
@{ ViewData["Title"] = "محصولات"; Layout = "_AdminLayout"; }
|
||
|
||
<div class="p-6 md:p-8">
|
||
<div class="flex items-center justify-between mb-8">
|
||
<h1 class="text-2xl font-extrabold text-gray-900">محصولات</h1>
|
||
<a href="/Admin/Products/Create" class="flex items-center gap-2 bg-blue-700 text-white px-4 py-2.5 rounded-xl text-sm font-bold hover:bg-blue-800 transition-colors">
|
||
➕ افزودن محصول
|
||
</a>
|
||
</div>
|
||
|
||
<div class="bg-white rounded-2xl border border-gray-100 overflow-hidden">
|
||
<div class="overflow-x-auto">
|
||
<table class="w-full text-sm">
|
||
<thead class="bg-gray-50 border-b">
|
||
<tr>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">نام</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">دسته</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">برند</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">قیمت</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">موجودی</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">وضعیت</th>
|
||
<th class="px-5 py-3.5 text-right font-medium text-gray-500">عملیات</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="divide-y divide-gray-50">
|
||
@foreach (var p in Model.Products)
|
||
{
|
||
var cat = SiteData.Categories.FirstOrDefault(c => c.Id == p.Category);
|
||
var brand = SiteData.Brands.FirstOrDefault(b => b.Id == p.Brand);
|
||
<tr class="hover:bg-gray-50/50">
|
||
<td class="px-5 py-4">
|
||
<div class="font-medium text-gray-900">@p.NameFa</div>
|
||
@if (p.Sku != null) { <div class="text-xs text-gray-400 font-mono">@p.Sku</div> }
|
||
</td>
|
||
<td class="px-5 py-4 text-gray-500">@(cat != null ? cat.Icon + " " + cat.NameFa : p.Category)</td>
|
||
<td class="px-5 py-4">
|
||
@if (brand != null)
|
||
{
|
||
<span class="text-xs font-bold px-2 py-0.5 rounded-full text-white" style="background-color:@brand.Color">@brand.NameFa</span>
|
||
}
|
||
else { <span class="text-gray-400">–</span> }
|
||
</td>
|
||
<td class="px-5 py-4 font-bold text-blue-700">@SiteData.FormatPrice(p.Price)</td>
|
||
<td class="px-5 py-4">
|
||
<span class="font-bold @(p.Stock == 0 ? "text-red-500" : p.Stock < 5 ? "text-yellow-500" : "text-green-600")">@p.Stock</span>
|
||
</td>
|
||
<td class="px-5 py-4">
|
||
<span class="text-xs px-2 py-1 rounded-full font-medium @(p.IsActive ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-500")">
|
||
@(p.IsActive ? "فعال" : "غیرفعال")
|
||
</span>
|
||
</td>
|
||
<td class="px-5 py-4">
|
||
<div class="flex items-center gap-3">
|
||
<a href="/Admin/Products/Edit?id=@p.Id" class="text-blue-600 hover:text-blue-800 text-xs font-medium">ویرایش</a>
|
||
<form method="post" asp-page-handler="Delete" onsubmit="return confirm('حذف شود؟')">
|
||
@Html.AntiForgeryToken()
|
||
<input type="hidden" name="id" value="@p.Id" />
|
||
<button type="submit" class="text-red-400 hover:text-red-600 text-xs font-medium">حذف</button>
|
||
</form>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|