feat(admin): P6 — Zones, Combo services, Shift management
- R4: Zone management (Restaurant) — 4 zones with table counts, status, actions - S6: Combo services (Spa) — 3 combo cards with pricing, duration, sold count - C5: Shift management (Café) — weekly shift grid (S/C/—) with legend + stats
This commit is contained in:
@@ -1338,6 +1338,133 @@
|
||||
</div>
|
||||
break;
|
||||
|
||||
// ═══ R4: ZONES / KHU VỰC (Nhà hàng) ═══
|
||||
case "zones":
|
||||
<div class="admin-panel">
|
||||
<div class="admin-panel__header" style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<h3 class="admin-panel__title">📍 Quản lý khu vực</h3>
|
||||
<button class="admin-btn-primary" style="font-size:12px;padding:6px 14px;"><i data-lucide="plus" style="width:14px;height:14px;margin-right:4px;"></i>Thêm khu vực</button>
|
||||
</div>
|
||||
<div class="admin-panel__body">
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;">
|
||||
@foreach (var (name, tables, desc, color, icon) in new[] {
|
||||
("Tầng 1 — Sảnh chính", 12, "Khu vực chính tiếp khách, gần quầy bar", "#3B82F6", "building"),
|
||||
("Tầng 2 — VIP", 6, "Phòng VIP riêng tư, cách âm tốt", "#A855F7", "crown"),
|
||||
("Sân vườn", 8, "Khu vực ngoài trời, view đẹp", "#22C55E", "trees"),
|
||||
("Bar & Lounge", 4, "Khu vực bar, phục vụ đồ uống", "#F59E0B", "wine") })
|
||||
{
|
||||
<div style="padding:20px;border-radius:12px;background:var(--admin-bg-elevated);border:1px solid var(--admin-border-subtle);">
|
||||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
|
||||
<div style="width:40px;height:40px;border-radius:10px;background:rgba(@(color == "#3B82F6" ? "59,130,246" : color == "#A855F7" ? "168,85,247" : color == "#22C55E" ? "34,197,94" : "245,158,11"),0.15);display:flex;align-items:center;justify-content:center;">
|
||||
<i data-lucide="@icon" style="width:20px;height:20px;color:@color;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:700;font-size:15px;">@name</div>
|
||||
<div style="font-size:12px;color:var(--admin-text-tertiary);">@tables bàn</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="font-size:13px;color:var(--admin-text-secondary);margin:0 0 14px;">@desc</p>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<span style="font-size:11px;padding:3px 10px;border-radius:6px;background:rgba(34,197,94,0.12);color:#22C55E;">Đang hoạt động</span>
|
||||
</div>
|
||||
<div style="display:flex;gap:12px;margin-top:14px;border-top:1px solid var(--admin-border-subtle);padding-top:12px;">
|
||||
<button style="font-size:12px;color:var(--admin-orange-primary);background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:4px;"><i data-lucide="pencil" style="width:12px;height:12px;"></i>Sửa</button>
|
||||
<button style="font-size:12px;color:var(--admin-text-tertiary);background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:4px;"><i data-lucide="layout-grid" style="width:12px;height:12px;"></i>Sơ đồ bàn</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
break;
|
||||
|
||||
// ═══ S6: COMBO DỊCH VỤ (Spa) ═══
|
||||
case "combos":
|
||||
<div class="admin-panel">
|
||||
<div class="admin-panel__header" style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<h3 class="admin-panel__title">🎁 Combo dịch vụ</h3>
|
||||
<button class="admin-btn-primary" style="font-size:12px;padding:6px 14px;"><i data-lucide="plus" style="width:14px;height:14px;margin-right:4px;"></i>Tạo combo</button>
|
||||
</div>
|
||||
<div class="admin-panel__body">
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:16px;">
|
||||
@foreach (var (name, services, duration, price, orig, sold, color) in new[] {
|
||||
("Combo Thư Giãn Toàn Thân", "Massage body 60' + Xông hơi 30' + Đắp mặt nạ 20'", "110 phút", "800,000₫", "1,050,000₫", 45, "#3B82F6"),
|
||||
("Combo Detox & Làm Đẹp", "Tẩy tế bào chết + Massage mặt + Chăm sóc da 5 bước", "90 phút", "650,000₫", "850,000₫", 32, "#A855F7"),
|
||||
("Combo Cặp Đôi Premium", "2 Massage body 90' + 2 Xông hơi + Trà thảo mộc", "120 phút", "1,500,000₫", "2,100,000₫", 18, "#EC4899") })
|
||||
{
|
||||
<div style="padding:20px;border-radius:12px;background:var(--admin-bg-elevated);border:1px solid var(--admin-border-subtle);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;">
|
||||
<h4 style="font-size:16px;font-weight:700;margin:0;">@name</h4>
|
||||
<span style="font-size:11px;padding:3px 10px;border-radius:6px;background:rgba(34,197,94,0.12);color:#22C55E;">Đang bán</span>
|
||||
</div>
|
||||
<p style="font-size:13px;color:var(--admin-text-secondary);margin:0 0 12px;line-height:1.5;">@services</p>
|
||||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
|
||||
<i data-lucide="clock" style="width:14px;height:14px;color:var(--admin-text-tertiary);"></i>
|
||||
<span style="font-size:13px;color:var(--admin-text-tertiary);">@duration</span>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;padding-top:12px;border-top:1px solid var(--admin-border-subtle);">
|
||||
<div>
|
||||
<span style="font-size:18px;font-weight:800;color:var(--admin-orange-primary);">@price</span>
|
||||
<span style="font-size:12px;color:var(--admin-text-tertiary);text-decoration:line-through;margin-left:8px;">@orig</span>
|
||||
</div>
|
||||
<span style="font-size:12px;color:var(--admin-text-tertiary);">Đã bán: @sold</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
break;
|
||||
|
||||
// ═══ C5: CA LÀM VIỆC / SHIFTS (Café) ═══
|
||||
case "shifts":
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px;margin-bottom:16px;">
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(59,130,246,0.1);"><i data-lucide="clock" style="color:#3B82F6;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">3</span><span class="admin-stat-card__label">Ca hôm nay</span></div></div>
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(34,197,94,0.1);"><i data-lucide="user-check" style="color:#22C55E;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">5</span><span class="admin-stat-card__label">Đang làm việc</span></div></div>
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(245,158,11,0.1);"><i data-lucide="alert-circle" style="color:#F59E0B;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">1</span><span class="admin-stat-card__label">Vắng mặt</span></div></div>
|
||||
</div>
|
||||
<div class="admin-panel">
|
||||
<div class="admin-panel__header" style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<h3 class="admin-panel__title">📋 Lịch ca — Tuần này</h3>
|
||||
<button class="admin-btn-primary" style="font-size:12px;padding:6px 14px;"><i data-lucide="plus" style="width:14px;height:14px;margin-right:4px;"></i>Phân ca</button>
|
||||
</div>
|
||||
<div class="admin-panel__body" style="padding:0;overflow-x:auto;">
|
||||
<table class="admin-table" style="width:100%;min-width:700px;"><thead><tr>
|
||||
<th style="padding:12px 16px;text-align:left;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);white-space:nowrap;">Nhân viên</th>
|
||||
@foreach (var d in new[] { "T2", "T3", "T4", "T5", "T6", "T7", "CN" })
|
||||
{
|
||||
<th style="padding:12px 8px;text-align:center;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);min-width:80px;">@d</th>
|
||||
}
|
||||
</tr></thead><tbody>
|
||||
@foreach (var (name, shifts) in new[] {
|
||||
("Nguyễn A", new[] { "S", "S", "C", "C", "—", "S", "—" }),
|
||||
("Trần B", new[] { "C", "C", "S", "S", "C", "—", "—" }),
|
||||
("Lê C", new[] { "S", "—", "S", "C", "S", "C", "S" }),
|
||||
("Phạm D", new[] { "—", "S", "C", "—", "C", "S", "C" }),
|
||||
("Hoàng E", new[] { "C", "C", "—", "S", "S", "—", "S" }) })
|
||||
{
|
||||
<tr style="border-top:1px solid var(--admin-border-subtle);">
|
||||
<td style="padding:12px 16px;font-weight:600;white-space:nowrap;">@name</td>
|
||||
@foreach (var s in shifts)
|
||||
{
|
||||
var bg = s == "S" ? "rgba(59,130,246,0.12)" : s == "C" ? "rgba(168,85,247,0.12)" : "transparent";
|
||||
var fg = s == "S" ? "#3B82F6" : s == "C" ? "#A855F7" : "var(--admin-text-tertiary)";
|
||||
<td style="padding:8px;text-align:center;">
|
||||
<span style="display:inline-block;width:36px;height:28px;line-height:28px;border-radius:6px;font-size:12px;font-weight:700;background:@bg;color:@fg;">@s</span>
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:16px;margin-top:12px;">
|
||||
<div style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:rgba(59,130,246,0.25);"></span> S = Sáng (7:00-14:00)</div>
|
||||
<div style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:rgba(168,85,247,0.25);"></span> C = Chiều (14:00-22:00)</div>
|
||||
<div style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:transparent;border:1px solid var(--admin-border-subtle);"></span> — = Nghỉ</div>
|
||||
</div>
|
||||
break;
|
||||
|
||||
// ═══ UNKNOWN SECTIONS ═══
|
||||
default:
|
||||
<div class="admin-panel">
|
||||
@@ -1554,6 +1681,9 @@
|
||||
case "consent": _sectionTitle = "Cam kết KH"; _sectionIcon = "file-check"; _sectionDescription = "Biểu mẫu đồng ý khách hàng."; break;
|
||||
case "doctors": _sectionTitle = "Bác sĩ / CK"; _sectionIcon = "stethoscope"; _sectionDescription = "Quản lý bác sĩ và chuyên gia."; break;
|
||||
case "followup": _sectionTitle = "Tái khám"; _sectionIcon = "calendar-heart"; _sectionDescription = "Lịch tái khám sau điều trị."; break;
|
||||
case "zones": _sectionTitle = "Khu vực"; _sectionIcon = "map-pin"; _sectionDescription = "Quản lý khu vực phục vụ."; break;
|
||||
case "combos": _sectionTitle = "Combo dịch vụ"; _sectionIcon = "layers"; _sectionDescription = "Quản lý combo dịch vụ."; break;
|
||||
case "shifts": _sectionTitle = "Ca làm việc"; _sectionIcon = "clock-4"; _sectionDescription = "Lịch ca làm, phân ca."; break;
|
||||
default: _sectionTitle = Section ?? "Trang"; _sectionIcon = "layout-dashboard"; _sectionDescription = "Trang đang phát triển."; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public static class ShopSidebarConfig
|
||||
new("POS Bán hàng", "monitor", "pos"),
|
||||
new("Menu & Đồ uống", "coffee", "menu"),
|
||||
new("Nguyên liệu", "flask-conical", "recipes"),
|
||||
new("Ca làm việc", "clock-4", "shifts"),
|
||||
new("Tồn kho", "warehouse", "inventory"),
|
||||
new("Tài chính", "trending-up", "finance"),
|
||||
new("Nhân sự", "users", "staff"),
|
||||
@@ -49,6 +50,7 @@ public static class ShopSidebarConfig
|
||||
new("Menu & Món ăn", "utensils", "menu"),
|
||||
new("Bàn / Table", "grid-3x3", "tables"),
|
||||
new("Đặt bàn", "calendar-check", "reservations"),
|
||||
new("Khu vực", "map-pin", "zones"),
|
||||
new("Bếp (Kitchen)", "flame", "kitchen"),
|
||||
new("Tồn kho", "warehouse", "inventory"),
|
||||
new("Tài chính", "trending-up", "finance"),
|
||||
@@ -80,6 +82,7 @@ public static class ShopSidebarConfig
|
||||
new("Lịch hẹn", "calendar", "appointments"),
|
||||
new("Dịch vụ", "sparkles", "services"),
|
||||
new("Gói dịch vụ", "gift", "packages"),
|
||||
new("Combo dịch vụ", "layers", "combos"),
|
||||
new("Tài nguyên", "door-open", "resources"),
|
||||
new("Sản phẩm", "package", "products"),
|
||||
new("Tài chính", "trending-up", "finance"),
|
||||
|
||||
Reference in New Issue
Block a user