Files
frontend/lib/constants.ts
T
TakahashiNguyen 9ed4889310
Release package / release (push) Successful in 10m13s
fix: add shift management (#41)
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #41
2026-05-14 03:13:06 +00:00

202 lines
7.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type {
Department,
RevenueDataPoint,
ShiftEntity,
ShopInfo,
SocialLinks,
} from "./types";
// ===== SHOP INFORMATION =====
export const SHOP_INFO: ShopInfo = {
name: "Coffee Shop",
tagline: "Rich Flavors Moments of Relaxation",
logo: "/imgs/logo.png",
address: "123 Nguyen Hue Street, District 1, Ho Chi Minh City",
phone: "0901 234 567",
managerPhone: "0912 345 678",
email: "contact@coffeeshop.vn",
wifi: {
name: "CoffeeShop_Free",
password: "coffee2024",
},
openHours: "07:00 22:00 (Monday Sunday)",
};
// ===== SOCIAL LINKS =====
export const SOCIAL_LINKS: SocialLinks = {
facebook: "https://facebook.com/coffeeshop",
tiktok: "https://tiktok.com/@coffeeshop",
website: "/",
};
// ===== MOCK FINANCIAL DATA =====
// Daily revenue for the last 30 days (current month)
export const MOCK_REVENUE_DAILY: RevenueDataPoint[] = [
{ label: "01/04", revenue: 1250000, orders: 42 },
{ label: "02/04", revenue: 980000, orders: 35 },
{ label: "03/04", revenue: 1540000, orders: 55 },
{ label: "04/04", revenue: 1120000, orders: 40 },
{ label: "05/04", revenue: 1890000, orders: 68 },
{ label: "06/04", revenue: 2100000, orders: 74 },
{ label: "07/04", revenue: 2350000, orders: 82 },
{ label: "08/04", revenue: 1680000, orders: 60 },
{ label: "09/04", revenue: 1430000, orders: 50 },
{ label: "10/04", revenue: 1750000, orders: 63 },
{ label: "11/04", revenue: 1560000, orders: 56 },
{ label: "12/04", revenue: 1920000, orders: 70 },
{ label: "13/04", revenue: 2230000, orders: 80 },
{ label: "14/04", revenue: 2480000, orders: 90 },
{ label: "15/04", revenue: 1870000, orders: 66 },
{ label: "16/04", revenue: 1340000, orders: 48 },
{ label: "17/04", revenue: 1610000, orders: 58 },
{ label: "18/04", revenue: 1490000, orders: 53 },
{ label: "19/04", revenue: 1970000, orders: 71 },
{ label: "20/04", revenue: 2140000, orders: 77 },
{ label: "21/04", revenue: 2560000, orders: 93 },
{ label: "22/04", revenue: 1780000, orders: 64 },
{ label: "23/04", revenue: 1520000, orders: 54 },
{ label: "24/04", revenue: 1840000, orders: 66 },
{ label: "25/04", revenue: 1660000, orders: 60 },
{ label: "26/04", revenue: 2050000, orders: 74 },
{ label: "27/04", revenue: 2280000, orders: 82 },
{ label: "28/04", revenue: 2490000, orders: 89 },
{ label: "29/04", revenue: 1950000, orders: 70 },
{ label: "30/04", revenue: 1720000, orders: 62 },
];
// Weekly revenue (last 12 weeks)
export const MOCK_REVENUE_WEEKLY: RevenueDataPoint[] = [
{ label: "Jan/W1", revenue: 8200000, orders: 295 },
{ label: "Jan/W2", revenue: 9450000, orders: 340 },
{ label: "Jan/W3", revenue: 10100000, orders: 362 },
{ label: "Jan/W4", revenue: 8750000, orders: 315 },
{ label: "Feb/W1", revenue: 9200000, orders: 330 },
{ label: "Feb/W2", revenue: 10500000, orders: 378 },
{ label: "Feb/W3", revenue: 11200000, orders: 400 },
{ label: "Feb/W4", revenue: 9800000, orders: 352 },
{ label: "Mar/W1", revenue: 10400000, orders: 374 },
{ label: "Mar/W2", revenue: 11800000, orders: 424 },
{ label: "Mar/W3", revenue: 12500000, orders: 448 },
{ label: "Mar/W4", revenue: 10900000, orders: 392 },
];
// Monthly revenue (last 12 months)
export const MOCK_REVENUE_MONTHLY: RevenueDataPoint[] = [
{ label: "Apr/2025", revenue: 42000000, orders: 1512 },
{ label: "May/2025", revenue: 45500000, orders: 1638 },
{ label: "Jun/2025", revenue: 48000000, orders: 1728 },
{ label: "Jul/2025", revenue: 52000000, orders: 1872 },
{ label: "Aug/2025", revenue: 49500000, orders: 1782 },
{ label: "Sep/2025", revenue: 46800000, orders: 1685 },
{ label: "Oct/2025", revenue: 51200000, orders: 1843 },
{ label: "Nov/2025", revenue: 55000000, orders: 1980 },
{ label: "Dec/2025", revenue: 62000000, orders: 2232 },
{ label: "Jan/2026", revenue: 44000000, orders: 1584 },
{ label: "Feb/2026", revenue: 47500000, orders: 1710 },
{ label: "Mar/2026", revenue: 53500000, orders: 1926 },
];
// Yearly revenue (last 5 years)
export const MOCK_REVENUE_YEARLY: RevenueDataPoint[] = [
{ label: "2022", revenue: 420000000, orders: 15120 },
{ label: "2023", revenue: 485000000, orders: 17460 },
{ label: "2024", revenue: 530000000, orders: 19080 },
{ label: "2025", revenue: 598000000, orders: 21528 },
{ label: "2026", revenue: 180000000, orders: 6480 },
];
/**
* Generate mock shift slots for the weeks around today (April 2026).
* Covers Mon 6 Apr Sun 26 Apr 2026.
*/
function generateMockShifts(): ShiftEntity[] {
const shifts: ShiftEntity[] = [];
const departments = ["waiter"];
const timeSlots = [
{ start: "07:00", end: "11:00", hours: 4, wage: 120000 },
{ start: "11:00", end: "15:00", hours: 4, wage: 120000 },
{ start: "15:00", end: "19:00", hours: 4, wage: 120000 },
{ start: "19:00", end: "22:00", hours: 3, wage: 100000 },
];
const staffPool = [
{ id: 2, name: "Alex Nguyen" },
{ id: 3, name: "Binh Tran" },
{ id: 4, name: "Cuong Le" },
];
// Generate shifts from April 6 to April 26, 2026
let shiftCounter = 0;
for (let day = 6; day <= 26; day++) {
const dateStr = `2026-04-${day.toString().padStart(2, "0")}`;
for (const dept of departments) {
// Not every department has shifts every day
if (dept === "janitor" && day % 3 !== 0) continue;
for (const slot of timeSlots) {
// Skip some slots randomly for variety
if (dept === "kitchen" && slot.start === "19:00") continue;
if (dept === "cashier" && slot.start === "07:00" && day % 2 === 0)
continue;
shiftCounter++;
const shiftId = `shift_${shiftCounter.toString().padStart(3, "0")}`;
// Determine registration status
const registered: { id: number; name: string }[] = [];
// let status: ShiftEntity["status"] = "available";
// Past shifts (before April 10) are mostly registered
if (day < 10) {
const staffIdx = shiftCounter % staffPool.length;
registered.push(staffPool[staffIdx]);
if (shiftCounter % 7 === 0) {
registered.push(staffPool[(staffIdx + 1) % staffPool.length]);
}
// status = "registered";
// Some past shifts have leave/absent
// if (shiftCounter % 11 === 0) status = "approved_leave";
// if (shiftCounter % 13 === 0) status = "absent";
}
// Current week (April 6-12): mix of registered and available
else if (day >= 10 && day <= 12) {
if (shiftCounter % 3 === 0) {
registered.push(staffPool[shiftCounter % staffPool.length]);
// status = "registered";
}
}
// Future shifts: mostly available, some registered
else {
if (shiftCounter % 5 === 0) {
registered.push(staffPool[shiftCounter % staffPool.length]);
// status = "registered";
}
}
shifts.push({
id: "shiftId",
date: new Date(dateStr),
startTime: slot.start,
endTime: slot.end,
// durationHours: slot.hours,
wage: slot.wage,
// department: dept,
maxStaff: dept === "bar" ? 3 : 2,
// registeredStaff: registered,
// status,
});
}
}
}
return shifts;
}
export const MOCK_SHIFT_SLOTS: ShiftEntity[] = generateMockShifts();
export const DEPARTMENTS: Department[] = [
{ id: "waiter", name: "Bar Staff", icon: "fa-brands fa-jenkins" },
];