import React, { useState, useEffect } from 'react';
import {
Calendar,
ChevronDown,
Users,
DollarSign,
FileText,
Settings,
PlusCircle,
Upload,
Search,
Edit,
Trash2,
AlertCircle,
BarChart2,
Clock,
FileSpreadsheet,
Send
} from 'lucide-react';
// Main App Component
export default function RetailPayrollSystem() {
const [activeTab, setActiveTab] = useState('dashboard');
const [employees, setEmployees] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [showAddEmployee, setShowAddEmployee] = useState(false);
const [showBulkUpload, setShowBulkUpload] = useState(false);
const [showPayrollForm, setShowPayrollForm] = useState(false);
const [currentPayPeriod, setCurrentPayPeriod] = useState({
startDate: new Date().toISOString().split('T')[0],
endDate: new Date().toISOString().split('T')[0]
});
// Fetch employees data
useEffect(() => {
// Simulate API call
setTimeout(() => {
setEmployees([
{
id: 1,
name: 'John Kamau',
role: 'Cashier',
department: 'Checkout',
shift: 'Morning',
basicSalary: 25000,
dateHired: '2023-01-15',
status: 'Active',
salesTarget: 100000,
contactNumber: '+254712345678',
idNumber: '12345678'
},
{
id: 2,
name: 'Mary Wanjiku',
role: 'Supervisor',
department: 'Electronics',
shift: 'Evening',
basicSalary: 45000,
dateHired: '2022-06-10',
status: 'Active',
salesTarget: 200000,
contactNumber: '+254723456789',
idNumber: '23456789'
},
{
id: 3,
name: 'James Omondi',
role: 'Cleaner',
department: 'Housekeeping',
shift: 'Night',
basicSalary: 18000,
dateHired: '2023-03-22',
status: 'Active',
salesTarget: 0,
contactNumber: '+254734567890',
idNumber: '34567890'
},
{
id: 4,
name: 'Sarah Akinyi',
role: 'Merchandiser',
department: 'Apparel',
shift: 'Morning',
basicSalary: 30000,
dateHired: '2022-11-05',
status: 'Active',
salesTarget: 150000,
contactNumber: '+254745678901',
idNumber: '45678901'
},
{
id: 5,
name: 'David Mwangi',
role: 'Security',
department: 'Security',
shift: 'Evening',
basicSalary: 28000,
dateHired: '2023-02-18',
status: 'Active',
salesTarget: 0,
contactNumber: '+254756789012',
idNumber: '56789012'
}
]);
setIsLoading(false);
}, 1000);
}, []);
// Dashboard metrics
const dashboardMetrics = {
totalEmployees: employees.length,
activeEmployees: employees.filter(emp => emp.status === 'Active').length,
totalPayroll: employees.reduce((sum, emp) => sum + emp.basicSalary, 0),
averageSalary: employees.length > 0 ?
Math.round(employees.reduce((sum, emp) => sum + emp.basicSalary, 0) / employees.length) : 0,
departmentBreakdown: {
Checkout: employees.filter(emp => emp.department === 'Checkout').length,
Electronics: employees.filter(emp => emp.department === 'Electronics').length,
Housekeeping: employees.filter(emp => emp.department === 'Housekeeping').length,
Apparel: employees.filter(emp => emp.department === 'Apparel').length,
Security: employees.filter(emp => emp.department === 'Security').length
},
shiftDistribution: {
Morning: employees.filter(emp => emp.shift === 'Morning').length,
Evening: employees.filter(emp => emp.shift === 'Evening').length,
Night: employees.filter(emp => emp.shift === 'Night').length
}
};
// Sample payroll data
const payrollHistory = [
{ id: 1, period: 'May 2024', processedDate: '2024-05-30', totalAmount: 1250000, status: 'Completed' },
{ id: 2, period: 'April 2024', processedDate: '2024-04-30', totalAmount: 1225000, status: 'Completed' },
{ id: 3, period: 'March 2024', processedDate: '2024-03-30', totalAmount: 1200000, status: 'Completed' }
];
// Sample attendance data
const attendanceData = [
{ id: 1, employeeId: 1, employeeName: 'John Kamau', date: '2024-05-15', clockIn: '07:55:00', clockOut: '17:05:00', status: 'Present' },
{ id: 2, employeeId: 2, employeeName: 'Mary Wanjiku', date: '2024-05-15', clockIn: '14:50:00', clockOut: '23:10:00', status: 'Present' },
{ id: 3, employeeId: 3, employeeName: 'James Omondi', date: '2024-05-15', clockIn: '22:00:00', clockOut: '06:05:00', status: 'Present' },
{ id: 4, employeeId: 4, employeeName: 'Sarah Akinyi', date: '2024-05-15', clockIn: '08:15:00', clockOut: '17:00:00', status: 'Late' },
{ id: 5, employeeId: 5, employeeName: 'David Mwangi', date: '2024-05-15', clockIn: null, clockOut: null, status: 'Absent' }
];
// Sample commission data
const commissionData = [
{ id: 1, employeeId: 1, employeeName: 'John Kamau', month: 'May 2024', sales: 120000, target: 100000, commission: 6000, status: 'Paid' },
{ id: 2, employeeId: 2, employeeName: 'Mary Wanjiku', month: 'May 2024', sales: 210000, target: 200000, commission: 10500, status: 'Paid' },
{ id: 4, employeeId: 4, employeeName: 'Sarah Akinyi', month: 'May 2024', sales: 145000, target: 150000, commission: 0, status: 'Not Paid' }
];
// Handle employee form submission
const handleEmployeeSubmit = (e) => {
e.preventDefault();
// Implementation would go here
setShowAddEmployee(false);
alert('Employee added successfully!');
};
// Handle bulk upload
const handleBulkUpload = (e) => {
e.preventDefault();
// Implementation would go here
setShowBulkUpload(false);
alert('Employees uploaded successfully!');
};
// Handle payroll processing
const handleProcessPayroll = (e) => {
e.preventDefault();
// Implementation would go here
setShowPayrollForm(false);
alert('Payroll processed successfully!');
};
return (
{/* Sidebar */}
RetailPay Kenya
Retail Payroll System
{/* Main Content */}
{/* Header */}
{activeTab === 'dashboard' && 'Dashboard'}
{activeTab === 'employees' && 'Employee Management'}
{activeTab === 'payroll' && 'Payroll Processing'}
{activeTab === 'attendance' && 'Attendance Tracking'}
{activeTab === 'commissions' && 'Sales Commissions'}
{activeTab === 'reports' && 'Reports & Compliance'}
{activeTab === 'settings' && 'System Settings'}
{/* Content Area */}
{/* Dashboard */}
{activeTab === 'dashboard' && (
Total Employees
{dashboardMetrics.totalEmployees}
+2 from last month
Active Employees
{dashboardMetrics.activeEmployees}
{Math.round((dashboardMetrics.activeEmployees / dashboardMetrics.totalEmployees) * 100)}% of total
Total Monthly Payroll
KES {dashboardMetrics.totalPayroll.toLocaleString()}
+5.2% from last month
Average Salary
KES {dashboardMetrics.averageSalary.toLocaleString()}
Based on {dashboardMetrics.totalEmployees} employees
Department Distribution
{Object.entries(dashboardMetrics.departmentBreakdown).map(([dept, count]) => (
))}
Shift Distribution
{Object.entries(dashboardMetrics.shiftDistribution).map(([shift, count]) => (
{shift} Shift
{count} employees
))}
Recent Payroll History
| Period |
Processed Date |
Total Amount |
Status |
Actions |
{payrollHistory.map((payroll) => (
| {payroll.period} |
{payroll.processedDate} |
KES {payroll.totalAmount.toLocaleString()} |
{payroll.status}
|
|
))}
)}
{/* Employees */}
{activeTab === 'employees' && (
Employee Directory
Manage your retail staff information
{isLoading ? (
) : (
| Employee |
Role |
Department |
Shift |
Basic Salary |
Date Hired |
Status |
Actions |
{employees.map((employee) => (
{employee.name.charAt(0)}
{employee.name}
ID: {employee.idNumber}
|
{employee.role} |
{employee.department} |
{employee.shift} |
KES {employee.basicSalary.toLocaleString()} |
{employee.dateHired} |
{employee.status}
|
|
))}
)}
Showing 1 to 5 of 5 results
{/* Add Employee Modal */}
{showAddEmployee && (
)}
{/* Bulk Upload Modal */}
{showBulkUpload && (
)}
)}
{/* Payroll */}
{activeTab === 'payroll' && (
Payroll Processing
Process payroll for your retail staff
Pending Processing
Due in 10 days
Estimated Total
KES 1,250,000
Based on current staff
Payroll History
| Period |
Processed Date |
Total Amount |
Employees |
Status |
Actions |
{payrollHistory.map((payroll) => (
| {payroll.period} |
{payroll.processedDate} |
KES {payroll.totalAmount.toLocaleString()} |
5 |
{payroll.status}
|
|
))}
Allowances & Bonuses
Sales Commissions
KES 75,000
Night Shift Allowance
KES 15,000
Transport Allowance
KES 25,000
{/* Process Payroll Modal */}
{showPayrollForm && (
)}
)}
{/* Attendance */}
{activeTab === 'attendance' && (
Attendance Tracking
Monitor staff attendance and time records
| Employee |
Department |
Date |
Clock In |
Clock Out |
Hours Worked |
Status |
Actions |
{attendanceData.map((record) => {
const employee = employees.find(emp => emp.id === record.employeeId) || {};
let hoursWorked = '-';
if (record.clockIn && record.clockOut) {
const clockIn = new Date(`2024-05-15T${record.clockIn}`);
const clockOut = new Date(`2024-05-15T${record.clockOut}`);
const diff = (clockOut - clockIn) / (1000 * 60 * 60);
hoursWorked = diff.toFixed(2);
}
return (
{record.employeeName.charAt(0)}
{record.employeeName}
{employee.role || 'N/A'}
|
{employee.department || 'N/A'} |
{record.date} |
{record.clockIn || '-'} |
{record.clockOut || '-'} |
{hoursWorked} |
{record.status}
|
|
);
})}
Showing 1 to 5 of 5 results
)}
{/* Commissions */}
{activeTab === 'commissions' && (
Sales Commissions
Track and manage sales-based commissions
Total Sales
KES 475,000
For May 2024
Total Commissions
KES 16,500
For May 2024
| Employee |
Department |
Month |
Sales Amount |
Target |
Achievement |
Commission |
Status |
{commissionData.map((record) => {
const employee = employees.find(emp => emp.id === record.employeeId) || {};
const achievement = Math.round((record.sales / record.target) * 100);
return (
{record.employeeName.charAt(0)}
{record.employeeName}
{employee.role || 'N/A'}
|
{employee.department || 'N/A'} |
{record.month} |
KES {record.sales.toLocaleString()} |
KES {record.target.toLocaleString()} |
{achievement}%
= 100 ? 'bg-green-500' : 'bg-yellow-500'}`}
style={{ width: `${Math.min(achievement, 100)}%` }}
>
|
KES {record.commission.toLocaleString()} |
{record.status}
|
);
})}
)}
{/* Reports */}
{activeTab === 'reports' && (
Reports & Compliance
Generate and manage statutory and management reports
P9 Forms
Tax deduction cards
Generate P9 forms for individual employees or all staff for tax filing purposes.
Generate monthly P10 forms for PAYE returns to KRA.
NHIF/NSSF Reports
Statutory contributions
Generate monthly NHIF and NSSF contribution reports.
Payroll Summary
Monthly payroll reports
Generate detailed payroll summary reports by department, role, or for all staff.
Commission Reports
Sales performance reports
Generate detailed commission and sales performance reports by employee or department.
Recent Reports
| Report Name |
Type |
Period |
Generated On |
Generated By |
Actions |
| P9 Forms |
Tax |
2023 |
2024-01-15 |
Admin User |
|
| P10 Form |
Tax |
April 2024 |
2024-05-05 |
Admin User |
|
| NHIF Report |
Statutory |
April 2024 |
2024-05-05 |
Admin User |
|
| Payroll Summary |
Payroll |
April 2024 |
2024-04-30 |
Admin User |
|
| Commission Report |
Sales |
April 2024 |
2024-05-02 |
Admin User |
|
)}
{/* Settings */}
{activeTab === 'settings' && (
System Settings
Configure your payroll system settings
Navigation
-
-
-
-
-
-
-
-
Company Information
Company Logo
LOGO
Recommended size: 200x200px, Max: 1MB
)}
);
}