hss-pos / frontend /src /lib /utils /helpers.js
sashank1989
feat: KDS side pane split by Dining/Takeaway/Delivery with source badges on cards
f8de0a1
Raw
History Blame Contribute Delete
4.46 kB
// Utility helpers for the frontend
/**
* Format currency in INR
*/
export function formatCurrency(amount) {
if (amount == null) return '₹0.00';
return new Intl.NumberFormat('en-IN', {
style: 'currency',
currency: 'INR',
minimumFractionDigits: 2
}).format(amount);
}
/**
* Format date/time
*/
export function formatDate(dateStr, options = {}) {
if (!dateStr) return '-';
const date = new Date(dateStr);
return new Intl.DateTimeFormat('en-IN', {
dateStyle: 'medium',
timeStyle: 'short',
...options
}).format(date);
}
/**
* Format time only
*/
export function formatTime(dateStr) {
if (!dateStr) return '-';
return new Intl.DateTimeFormat('en-IN', { timeStyle: 'short' }).format(new Date(dateStr));
}
/**
* Time elapsed since a date (e.g., "5 min ago")
*/
export function timeAgo(dateStr) {
if (!dateStr) return '';
const now = Date.now();
const then = new Date(dateStr).getTime();
const diff = Math.floor((now - then) / 1000);
if (diff < 60) return `${diff}s`;
if (diff < 3600) return `${Math.floor(diff / 60)}m`;
if (diff < 86400) return `${Math.floor(diff / 3600)}h`;
return `${Math.floor(diff / 86400)}d`;
}
/**
* Timer display (mm:ss) from a start date
*/
export function elapsedTimer(dateStr) {
if (!dateStr) return '00:00';
const diff = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);
const mins = Math.floor(diff / 60);
const secs = diff % 60;
return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
}
/**
* Debounce function
*/
export function debounce(fn, delay = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
/**
* Generate a short ID for local use
*/
export function shortId() {
return Math.random().toString(36).substring(2, 9);
}
/**
* Capitalize first letter
*/
export function capitalize(str) {
if (!str) return '';
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
/**
* Truncate string
*/
export function truncate(str, len = 30) {
if (!str || str.length <= len) return str || '';
return str.substring(0, len) + '...';
}
/**
* Get order source display label
*/
export function orderSourceLabel(source) {
const labels = {
dine_in: 'Dine In',
take_away: 'Takeaway',
takeaway: 'Takeaway',
delivery: 'Delivery',
website: 'Website',
whatsapp: 'WhatsApp',
swiggy: 'Swiggy',
zomato: 'Zomato',
qr_table: 'QR Order',
qr: 'QR Order'
};
return labels[source] || capitalize(source);
}
/**
* Get status color class
*/
export function statusColor(status) {
const colors = {
pending: 'badge-warning',
preparing: 'badge-info',
ready: 'badge-success',
served: 'badge-success',
completed: 'badge-success',
cancelled: 'badge-danger',
voided: 'badge-danger',
available: 'badge-success',
occupied: 'badge-danger',
reserved: 'badge-warning',
cleaning: 'badge-info'
};
return colors[status] || 'badge-info';
}
/**
* Kitchen station label
*/
export function stationLabel(station) {
const labels = {
south_indian: 'South Indian',
chinese: 'Chinese',
tandoor: 'Tandoor',
juice: 'Juice Bar',
bakery: 'Bakery',
main: 'Main Kitchen',
bar: 'Bar'
};
return labels[station] || capitalize(station);
}
/**
* Play notification sound
*/
export function playSound(type = 'notify') {
try {
const ctx = new (window.AudioContext || window.webkitAudioContext)();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
if (type === 'order') {
osc.frequency.value = 880;
gain.gain.value = 0.3;
osc.start();
osc.stop(ctx.currentTime + 0.15);
setTimeout(() => {
const osc2 = ctx.createOscillator();
osc2.connect(gain);
osc2.frequency.value = 1100;
osc2.start();
osc2.stop(ctx.currentTime + 0.15);
}, 180);
} else {
osc.frequency.value = 660;
gain.gain.value = 0.2;
osc.start();
osc.stop(ctx.currentTime + 0.1);
}
} catch {
// Audio not available
}
}
/**
* Check if user has a specific role
*/
export function hasRole(user, ...roles) {
if (!user?.role?.name) return false;
return roles.includes(user.role.name.toLowerCase());
}
/**
* Calculate GST breakdown
*/
export function calculateGST(amount, gstRate = 5) {
const gstAmount = (amount * gstRate) / 100;
return {
base: amount,
cgst: gstAmount / 2,
sgst: gstAmount / 2,
total: amount + gstAmount,
rate: gstRate
};
}