fix: manager login and menu management (#38)
Release package / release (push) Failing after 7m21s
Release package / release (push) Failing after 7m21s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Reviewed-on: #38
This commit was merged in pull request #38.
This commit is contained in:
+62
-329
@@ -1,8 +1,6 @@
|
||||
import type {
|
||||
Combo,
|
||||
Department,
|
||||
MenuCategory,
|
||||
Product,
|
||||
MenuItemEntity,
|
||||
ProductSalesStats,
|
||||
RevenueDataPoint,
|
||||
ShiftSlot,
|
||||
@@ -35,250 +33,189 @@ export const SOCIAL_LINKS: SocialLinks = {
|
||||
website: "/",
|
||||
};
|
||||
|
||||
// ===== MENU CATEGORIES =====
|
||||
// Each category has a unique FontAwesome icon representing the item type
|
||||
export const MENU_CATEGORIES: MenuCategory[] = [
|
||||
{ id: "all", name: "All", icon: "fa-solid fa-border-all" },
|
||||
{ id: "cafe", name: "Coffee", icon: "fa-solid fa-mug-hot" },
|
||||
{ id: "tra", name: "Tea", icon: "fa-solid fa-leaf" },
|
||||
{ id: "sua-chua", name: "Yogurt", icon: "fa-solid fa-jar" },
|
||||
{ id: "nuoc-ep", name: "Juice", icon: "fa-solid fa-blender" },
|
||||
{ id: "latte", name: "Latte", icon: "fa-solid fa-mug-saucer" },
|
||||
{
|
||||
id: "giai-khat",
|
||||
name: "Refreshments / Snacks",
|
||||
icon: "fa-solid fa-ice-cream",
|
||||
},
|
||||
{ id: "topping", name: "Topping", icon: "fa-solid fa-layer-group" },
|
||||
];
|
||||
|
||||
// ===== MOCK PRODUCTS =====
|
||||
// Placeholder data – replace with real API calls when backend is ready
|
||||
export const MOCK_PRODUCTS: Product[] = [
|
||||
export const MOCK_PRODUCTS: MenuItemEntity[] = [
|
||||
{
|
||||
id: 1,
|
||||
id: "1",
|
||||
name: "Black Coffee",
|
||||
category: "cafe",
|
||||
price: 25000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Traditional Vietnamese black coffee, rich and bold, brewed by hand with a phin filter.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
id: "2",
|
||||
name: "Milk Coffee",
|
||||
category: "cafe",
|
||||
price: 30000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Aromatic condensed milk coffee, rich and creamy — a perfect blend of strong coffee and sweet condensed milk.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
id: "3",
|
||||
name: "White Coffee",
|
||||
category: "cafe",
|
||||
|
||||
price: 32000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Light and mild, with less coffee and more milk — perfect for those just starting to enjoy coffee.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
id: "4",
|
||||
name: "Egg Coffee",
|
||||
category: "cafe",
|
||||
|
||||
price: 45000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"A Hanoi specialty — smooth, velvety egg cream layered over a bold coffee base.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
id: "5",
|
||||
name: "Peach Orange Lemongrass Tea",
|
||||
category: "tra",
|
||||
|
||||
price: 35000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Fragrant peach tea with fresh orange and lemongrass — refreshing and wonderfully cooling.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
id: "6",
|
||||
name: "Matcha Green Tea",
|
||||
category: "tra",
|
||||
|
||||
price: 40000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Pure Japanese matcha with a signature light bitterness — aromatic, refreshing, and nutritious.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
id: "7",
|
||||
name: "Lychee Jasmine Tea",
|
||||
category: "tra",
|
||||
|
||||
price: 38000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Sweet lychee tea delicately infused with jasmine blossom — a calming and soulful sip.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
id: "8",
|
||||
name: "Yogurt with Tapioca Pearls",
|
||||
category: "sua-chua",
|
||||
|
||||
price: 38000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Smooth, creamy yogurt paired with chewy black tapioca pearls — a perfectly balanced sweet and tangy treat.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
id: "9",
|
||||
name: "Strawberry Yogurt",
|
||||
category: "sua-chua",
|
||||
|
||||
price: 40000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Chilled yogurt with fresh sweet-tart strawberries, packed with vitamins and minerals.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
id: "10",
|
||||
name: "Fresh Orange Juice",
|
||||
category: "nuoc-ep",
|
||||
|
||||
price: 35000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"100% freshly squeezed orange juice, rich in vitamin C and great for your health.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
id: "11",
|
||||
name: "Watermelon Juice",
|
||||
category: "nuoc-ep",
|
||||
|
||||
price: 30000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Ice-cold watermelon juice — instantly refreshing on hot summer days.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
id: "12",
|
||||
name: "Caramel Latte",
|
||||
category: "latte",
|
||||
|
||||
price: 45000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Sweet and indulgent caramel latte with a velvety milk foam topping and a drizzle of caramel sauce.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
id: "13",
|
||||
name: "Vanilla Latte",
|
||||
category: "latte",
|
||||
|
||||
price: 45000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Smooth and gentle vanilla latte with a delicate natural vanilla fragrance.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
id: "14",
|
||||
name: "Toasted Butter Bread",
|
||||
category: "giai-khat",
|
||||
|
||||
price: 20000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Crispy toasted bread spread with fragrant butter and strawberry jam — the perfect coffee companion.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
id: "15",
|
||||
name: "Caramel Flan",
|
||||
category: "giai-khat",
|
||||
|
||||
price: 25000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Silky smooth flan with a golden caramel topping that melts in your mouth.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
id: "16",
|
||||
name: "Black Tapioca Pearls",
|
||||
category: "topping",
|
||||
|
||||
price: 10000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Chewy black tapioca pearls — add them to any drink for extra flavor and texture.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
id: "17",
|
||||
name: "Coffee Jelly",
|
||||
category: "topping",
|
||||
|
||||
price: 10000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Cool coffee jelly that adds a distinctive flavor boost to your drink.",
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
id: "18",
|
||||
name: "White Tapioca Pearls",
|
||||
category: "topping",
|
||||
|
||||
price: 10000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
imageUrl: "/imgs/products/placeholder.jpg",
|
||||
description:
|
||||
"Chewy white tapioca pearls — add them to any drink for extra flavor and texture.",
|
||||
available: true,
|
||||
},
|
||||
];
|
||||
|
||||
// ===== MOCK COMBOS =====
|
||||
export const MOCK_COMBOS: Combo[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Double Coffee Combo",
|
||||
description: "2 black coffees + 2 toasted butter breads, save 15%.",
|
||||
price: 75000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
items: [
|
||||
{ productId: 1, quantity: 2 },
|
||||
{ productId: 14, quantity: 2 },
|
||||
],
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Group Tea Combo",
|
||||
description:
|
||||
"2 peach orange lemongrass teas + 2 matcha green teas, perfect for a group.",
|
||||
price: 130000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
items: [
|
||||
{ productId: 5, quantity: 2 },
|
||||
{ productId: 6, quantity: 2 },
|
||||
],
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Morning Combo",
|
||||
description:
|
||||
"1 milk coffee + 1 caramel flan — start your day on a sweet note.",
|
||||
price: 48000,
|
||||
image: "/imgs/products/placeholder.jpg",
|
||||
items: [
|
||||
{ productId: 2, quantity: 1 },
|
||||
{ productId: 15, quantity: 1 },
|
||||
],
|
||||
available: false,
|
||||
},
|
||||
];
|
||||
|
||||
// ===== MOCK SHOPS (for Feed page) =====
|
||||
export const MOCK_SHOPS: Shop[] = [
|
||||
{
|
||||
@@ -395,217 +332,6 @@ export const MOCK_REVENUE_YEARLY: RevenueDataPoint[] = [
|
||||
{ label: "2026", revenue: 180000000, orders: 6480 },
|
||||
];
|
||||
|
||||
// Product sales statistics (with cost price for profit analysis)
|
||||
export const MOCK_PRODUCT_SALES: ProductSalesStats[] = [
|
||||
{
|
||||
productId: 12,
|
||||
name: "Caramel Latte",
|
||||
category: "latte",
|
||||
unitsSold: 487,
|
||||
revenue: 21915000,
|
||||
costPrice: 18000,
|
||||
sellingPrice: 45000,
|
||||
profit: 13185000,
|
||||
profitMargin: 60.2,
|
||||
},
|
||||
{
|
||||
productId: 6,
|
||||
name: "Matcha Green Tea",
|
||||
category: "tra",
|
||||
unitsSold: 412,
|
||||
revenue: 16480000,
|
||||
costPrice: 15000,
|
||||
sellingPrice: 40000,
|
||||
profit: 10300000,
|
||||
profitMargin: 62.5,
|
||||
},
|
||||
{
|
||||
productId: 5,
|
||||
name: "Peach Orange Lemongrass Tea",
|
||||
category: "tra",
|
||||
unitsSold: 398,
|
||||
revenue: 13930000,
|
||||
costPrice: 12000,
|
||||
sellingPrice: 35000,
|
||||
profit: 9153000,
|
||||
profitMargin: 65.7,
|
||||
},
|
||||
{
|
||||
productId: 13,
|
||||
name: "Vanilla Latte",
|
||||
category: "latte",
|
||||
unitsSold: 356,
|
||||
revenue: 16020000,
|
||||
costPrice: 18000,
|
||||
sellingPrice: 45000,
|
||||
profit: 9612000,
|
||||
profitMargin: 60.0,
|
||||
},
|
||||
{
|
||||
productId: 4,
|
||||
name: "Egg Coffee",
|
||||
category: "cafe",
|
||||
unitsSold: 340,
|
||||
revenue: 15300000,
|
||||
costPrice: 16000,
|
||||
sellingPrice: 45000,
|
||||
profit: 9860000,
|
||||
profitMargin: 64.4,
|
||||
},
|
||||
{
|
||||
productId: 2,
|
||||
name: "Milk Coffee",
|
||||
category: "cafe",
|
||||
unitsSold: 325,
|
||||
revenue: 9750000,
|
||||
costPrice: 10000,
|
||||
sellingPrice: 30000,
|
||||
profit: 6500000,
|
||||
profitMargin: 66.7,
|
||||
},
|
||||
{
|
||||
productId: 3,
|
||||
name: "White Coffee",
|
||||
category: "cafe",
|
||||
unitsSold: 298,
|
||||
revenue: 9536000,
|
||||
costPrice: 11000,
|
||||
sellingPrice: 32000,
|
||||
profit: 6259000,
|
||||
profitMargin: 65.6,
|
||||
},
|
||||
{
|
||||
productId: 1,
|
||||
name: "Black Coffee",
|
||||
category: "cafe",
|
||||
unitsSold: 285,
|
||||
revenue: 7125000,
|
||||
costPrice: 8000,
|
||||
sellingPrice: 25000,
|
||||
profit: 4845000,
|
||||
profitMargin: 68.0,
|
||||
},
|
||||
{
|
||||
productId: 9,
|
||||
name: "Strawberry Yogurt",
|
||||
category: "sua-chua",
|
||||
unitsSold: 267,
|
||||
revenue: 10680000,
|
||||
costPrice: 15000,
|
||||
sellingPrice: 40000,
|
||||
profit: 6675000,
|
||||
profitMargin: 62.5,
|
||||
},
|
||||
{
|
||||
productId: 10,
|
||||
name: "Fresh Orange Juice",
|
||||
category: "nuoc-ep",
|
||||
unitsSold: 241,
|
||||
revenue: 8435000,
|
||||
costPrice: 12000,
|
||||
sellingPrice: 35000,
|
||||
profit: 5543000,
|
||||
profitMargin: 65.7,
|
||||
},
|
||||
{
|
||||
productId: 8,
|
||||
name: "Yogurt with Tapioca Pearls",
|
||||
category: "sua-chua",
|
||||
unitsSold: 228,
|
||||
revenue: 8664000,
|
||||
costPrice: 14000,
|
||||
sellingPrice: 38000,
|
||||
profit: 5472000,
|
||||
profitMargin: 63.2,
|
||||
},
|
||||
{
|
||||
productId: 7,
|
||||
name: "Lychee Jasmine Tea",
|
||||
category: "tra",
|
||||
unitsSold: 215,
|
||||
revenue: 8170000,
|
||||
costPrice: 13000,
|
||||
sellingPrice: 38000,
|
||||
profit: 5375000,
|
||||
profitMargin: 65.8,
|
||||
},
|
||||
{
|
||||
productId: 15,
|
||||
name: "Caramel Flan",
|
||||
category: "giai-khat",
|
||||
unitsSold: 198,
|
||||
revenue: 4950000,
|
||||
costPrice: 8000,
|
||||
sellingPrice: 25000,
|
||||
profit: 3366000,
|
||||
profitMargin: 68.0,
|
||||
},
|
||||
{
|
||||
productId: 11,
|
||||
name: "Watermelon Juice",
|
||||
category: "nuoc-ep",
|
||||
unitsSold: 182,
|
||||
revenue: 5460000,
|
||||
costPrice: 10000,
|
||||
sellingPrice: 30000,
|
||||
profit: 3640000,
|
||||
profitMargin: 66.7,
|
||||
},
|
||||
{
|
||||
productId: 14,
|
||||
name: "Toasted Butter Bread",
|
||||
category: "giai-khat",
|
||||
unitsSold: 175,
|
||||
revenue: 3500000,
|
||||
costPrice: 6000,
|
||||
sellingPrice: 20000,
|
||||
profit: 2450000,
|
||||
profitMargin: 70.0,
|
||||
},
|
||||
{
|
||||
productId: 16,
|
||||
name: "Black Tapioca Pearls",
|
||||
category: "topping",
|
||||
unitsSold: 456,
|
||||
revenue: 4560000,
|
||||
costPrice: 2000,
|
||||
sellingPrice: 10000,
|
||||
profit: 3648000,
|
||||
profitMargin: 80.0,
|
||||
},
|
||||
{
|
||||
productId: 17,
|
||||
name: "Coffee Jelly",
|
||||
category: "topping",
|
||||
unitsSold: 389,
|
||||
revenue: 3890000,
|
||||
costPrice: 2000,
|
||||
sellingPrice: 10000,
|
||||
profit: 3112000,
|
||||
profitMargin: 80.0,
|
||||
},
|
||||
{
|
||||
productId: 18,
|
||||
name: "White Tapioca Pearls",
|
||||
category: "topping",
|
||||
unitsSold: 342,
|
||||
revenue: 3420000,
|
||||
costPrice: 2000,
|
||||
sellingPrice: 10000,
|
||||
profit: 2736000,
|
||||
profitMargin: 80.0,
|
||||
},
|
||||
];
|
||||
|
||||
// ===== SHIFT / SCHEDULE DATA =====
|
||||
|
||||
export const DEPARTMENTS: Department[] = [
|
||||
{ id: "bar", name: "Bar Staff", icon: "fa-solid fa-martini-glass-citrus" },
|
||||
{ id: "kitchen", name: "Kitchen", icon: "fa-solid fa-kitchen-set" },
|
||||
{ id: "cashier", name: "Cashier", icon: "fa-solid fa-cash-register" },
|
||||
{ id: "janitor", name: "Janitor", icon: "fa-solid fa-broom" },
|
||||
];
|
||||
|
||||
/**
|
||||
* Generate mock shift slots for the weeks around today (April 2026).
|
||||
* Covers Mon 6 Apr – Sun 26 Apr 2026.
|
||||
@@ -676,7 +402,7 @@ function generateMockShifts(): ShiftSlot[] {
|
||||
}
|
||||
|
||||
shifts.push({
|
||||
id: shiftId,
|
||||
id: "shiftId",
|
||||
date: dateStr,
|
||||
startTime: slot.start,
|
||||
endTime: slot.end,
|
||||
@@ -695,3 +421,10 @@ function generateMockShifts(): ShiftSlot[] {
|
||||
}
|
||||
|
||||
export const MOCK_SHIFT_SLOTS: ShiftSlot[] = generateMockShifts();
|
||||
|
||||
export const DEPARTMENTS: Department[] = [
|
||||
{ id: "bar", name: "Bar Staff", icon: "fa-solid fa-martini-glass-citrus" },
|
||||
{ id: "kitchen", name: "Kitchen", icon: "fa-solid fa-kitchen-set" },
|
||||
{ id: "cashier", name: "Cashier", icon: "fa-solid fa-cash-register" },
|
||||
{ id: "janitor", name: "Janitor", icon: "fa-solid fa-broom" },
|
||||
];
|
||||
Reference in New Issue
Block a user