80 lines
3.9 KiB
JavaScript
80 lines
3.9 KiB
JavaScript
import React from 'react';
|
|
|
|
/**
|
|
* Reusable DataTable component matching the premium Branch Management style.
|
|
*
|
|
* @param {Array} columns - Array of column definitions: { header: string, key?: string, render?: (row) => node, align?: 'left'|'right', width?: string }
|
|
* @param {Array} data - Array of data objects to display.
|
|
* @param {boolean} loading - Loading state for the table.
|
|
* @param {Function} onRowClick - Optional callback for row click events.
|
|
* @param {string} emptyMessage - Message to show when no data is available.
|
|
*/
|
|
export default function DataTable({
|
|
columns,
|
|
data,
|
|
loading = false,
|
|
onRowClick,
|
|
emptyMessage = "No records found matching your criteria."
|
|
}) {
|
|
return (
|
|
<div className="bg-white rounded-[1.25rem] border border-gray-100 shadow-sm overflow-hidden overflow-x-auto">
|
|
<table className="w-full min-w-[1000px] border-collapse">
|
|
<thead>
|
|
<tr className="bg-[#FBFCFD] border-b border-gray-100">
|
|
{columns.map((col, idx) => (
|
|
<th
|
|
key={idx}
|
|
className={`px-8 py-5 text-left text-[11px] font-bold text-gray-400 uppercase tracking-[0.1em] ${col.align === 'right' ? 'text-right' : ''}`}
|
|
style={{ width: col.width || 'auto' }}
|
|
>
|
|
{col.header}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-gray-50/50">
|
|
{loading ? (
|
|
<tr>
|
|
<td colSpan={columns.length} className="px-8 py-24 text-center">
|
|
<div className="flex flex-col items-center gap-4">
|
|
<div className="w-8 h-8 border-4 border-emerald-500 border-t-transparent rounded-full animate-spin"></div>
|
|
<p className="text-sm font-bold text-gray-400 uppercase tracking-widest italic">Loading data...</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
) : data && data.length > 0 ? (
|
|
data.map((row, rowIdx) => (
|
|
<tr
|
|
key={row.id || rowIdx}
|
|
className={`group hover:bg-[#F9FAFB]/60 transition-all duration-200 ${onRowClick ? 'cursor-pointer' : ''}`}
|
|
onClick={() => onRowClick && onRowClick(row)}
|
|
>
|
|
{columns.map((col, colIdx) => (
|
|
<td
|
|
key={colIdx}
|
|
className={`px-8 py-5 text-sm ${col.align === 'right' ? 'text-right' : ''}`}
|
|
>
|
|
{col.render ? (
|
|
col.render(row)
|
|
) : (
|
|
<span className="text-[#111827] font-semibold">{row[col.key] || '-'}</span>
|
|
)}
|
|
</td>
|
|
))}
|
|
</tr>
|
|
))
|
|
) : (
|
|
<tr>
|
|
<td colSpan={columns.length} className="px-8 py-16 text-center">
|
|
<div className="flex flex-col items-center gap-3">
|
|
<p className="text-sm font-bold text-gray-400 italic">{emptyMessage}</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|