Files
TenX PM 87e9346d62 feat: complete HR portal full-stack application
- NestJS backend with 11 modules: Auth, Employees, Departments, Attendance, Leaves, Payroll, Reimbursements, Announcements, Tax, Reports, Admin
- JWT authentication with refresh tokens, role-based access (employee/hr_admin/super_admin)
- MongoDB schemas with Mongoose for all entities
- PDF payslip generation with pdfkit
- OpenTelemetry tracing to SigNoz
- Automatic database seeding on first startup
- Next.js 14 frontend with App Router, Tailwind CSS
- 25 pages covering all employee, HR admin, and super admin workflows
- Multi-stage Dockerfile with nginx proxy
- test-manifest.json for E2E testing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:32:52 +00:00

49 lines
1.7 KiB
TypeScript

export function formatDate(date: string | Date, format = 'DD/MM/YYYY'): string {
if (!date) return '';
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const day = d.getDate().toString().padStart(2, '0');
const month = (d.getMonth() + 1).toString().padStart(2, '0');
const year = d.getFullYear();
if (format === 'YYYY-MM') return `${year}-${month}`;
if (format === 'MMM YYYY') {
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return `${monthNames[d.getMonth()]} ${year}`;
}
return `${day}/${month}/${year}`;
}
export function formatCurrency(amount: number): string {
return new Intl.NumberFormat('en-IN', {
style: 'currency',
currency: 'INR',
maximumFractionDigits: 0,
}).format(amount || 0);
}
export const monthNames = [
'', 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
export function getStatusColor(status: string): string {
const colors: Record<string, string> = {
present: 'bg-green-100 text-green-800',
absent: 'bg-red-100 text-red-800',
wfh: 'bg-blue-100 text-blue-800',
half_day: 'bg-yellow-100 text-yellow-800',
holiday: 'bg-purple-100 text-purple-800',
pending: 'bg-yellow-100 text-yellow-800',
approved: 'bg-green-100 text-green-800',
rejected: 'bg-red-100 text-red-800',
paid: 'bg-blue-100 text-blue-800',
generated: 'bg-gray-100 text-gray-800',
completed: 'bg-green-100 text-green-800',
};
return colors[status] || 'bg-gray-100 text-gray-800';
}
export function getDaysInMonth(year: number, month: number): number {
return new Date(year, month, 0).getDate();
}