Merge branch 'master' of https://bitbucket.org/jubilian/fcsc_ipi_frontend
This commit is contained in:
commit
6157d92d1b
@ -226,7 +226,7 @@ function App() {
|
|||||||
</RequireRole>
|
</RequireRole>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route path="/admin/configuration">
|
{/* <Route path="/admin/configuration">
|
||||||
<Route
|
<Route
|
||||||
index
|
index
|
||||||
element={
|
element={
|
||||||
@ -235,7 +235,14 @@ function App() {
|
|||||||
</RequireRole>
|
</RequireRole>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route> */}
|
||||||
|
<Route path="/admin/configuration/*" element={
|
||||||
|
<RequireRole allowedRoles={['Admin', 'EstablishmentUser']}>
|
||||||
|
<Configuration />
|
||||||
|
</RequireRole>
|
||||||
|
} />
|
||||||
|
{/* /> */}
|
||||||
|
{/* </Route> */}
|
||||||
<Route
|
<Route
|
||||||
path="/admin/users"
|
path="/admin/users"
|
||||||
element={
|
element={
|
||||||
|
|||||||
@ -135,16 +135,16 @@ const Table = ({
|
|||||||
'h-9 px-2 text-sm text-[#232528] disabled:text-[#C3C6CB] disabled:cursor-not-allowed transition-colors flex items-center gap-2 hover:text-[#92722A]';
|
'h-9 px-2 text-sm text-[#232528] disabled:text-[#C3C6CB] disabled:cursor-not-allowed transition-colors flex items-center gap-2 hover:text-[#92722A]';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`rounded-lg bg-white ${className}`}>
|
<div className={`overflow-hidden rounded-lg bg-white ${className}`}>
|
||||||
{beforeHeader}
|
{beforeHeader}
|
||||||
<div
|
<div
|
||||||
className="w-full overflow-x-auto px-6 pt-2 pb-6"
|
className={`${disableHorizontalScroll ? 'overflow-x-hidden' : 'overflow-x-auto'} px-6 pt-2 pb-6`}
|
||||||
style={{ scrollbarWidth: 'thin' }}
|
style={disableHorizontalScroll ? undefined : { scrollbarWidth: 'thin' }}
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className={`min-w-full w-auto table-fixed${
|
className={`min-w-[720px] w-full table-fixed rounded-2xl px-4 py-4${
|
||||||
separated ? ` border-separate ${rowGapClass}` : ' divide-y divide-[#C3C6CB]'
|
separated ? `border-separate ${rowGapClass}` : 'divide-y'
|
||||||
} border border-[#C3C6CB] rounded-2xl`}
|
} border border-[#C3C6CB] rounded-2xl divide-[#C3C6CB]`}
|
||||||
>
|
>
|
||||||
<thead className={headerClassName || 'bg-[#F2ECCF] rounded-2xl'}>
|
<thead className={headerClassName || 'bg-[#F2ECCF] rounded-2xl'}>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@ -33,20 +33,20 @@ const Configuration = () => {
|
|||||||
}, [active, navigate]);
|
}, [active, navigate]);
|
||||||
|
|
||||||
// Update active tab based on URL
|
// Update active tab based on URL
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const pathToTab = {
|
const pathToTab = {
|
||||||
'quarterly': 'Quarterly Windows',
|
'quarterly': 'Quarterly Windows',
|
||||||
'hscodes': 'HS Codes',
|
'hscodes': 'HS Codes',
|
||||||
'unitmaster': 'Unit Master',
|
'unitmaster': 'Unit Master',
|
||||||
'admin-users': 'Admin Users',
|
'admin-users': 'Admin Users',
|
||||||
'profile': 'Company Profile'
|
'profile': 'Company Profile'
|
||||||
};
|
};
|
||||||
|
|
||||||
const path = location.pathname.split('/').pop();
|
const path = location.pathname.split('/').pop();
|
||||||
if (pathToTab[path] && pathToTab[path] !== active) {
|
if (pathToTab[path] && pathToTab[path] !== active) {
|
||||||
setActive(pathToTab[path]);
|
setActive(pathToTab[path]);
|
||||||
}
|
}
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
||||||
const Breadcrumbs = (
|
const Breadcrumbs = (
|
||||||
<nav className="mb-6 text-sm text-[#8F9299] flex items-center gap-3">
|
<nav className="mb-6 text-sm text-[#8F9299] flex items-center gap-3">
|
||||||
|
|||||||
@ -149,7 +149,6 @@ const CompanyProfile = () => {
|
|||||||
const [selectedEmirateFilter, setSelectedEmirateFilter] = React.useState('');
|
const [selectedEmirateFilter, setSelectedEmirateFilter] = React.useState('');
|
||||||
const [selectedStatusFilter, setSelectedStatusFilter] = React.useState('');
|
const [selectedStatusFilter, setSelectedStatusFilter] = React.useState('');
|
||||||
const [debouncedSearch, setDebouncedSearch] = React.useState('');
|
const [debouncedSearch, setDebouncedSearch] = React.useState('');
|
||||||
const [sortConfig, setSortConfig] = React.useState({ field: 'establishmentName', direction: 'asc' });
|
|
||||||
const [activeStep, setActiveStep] = React.useState(0);
|
const [activeStep, setActiveStep] = React.useState(0);
|
||||||
const [confirmError, setConfirmError] = React.useState('');
|
const [confirmError, setConfirmError] = React.useState('');
|
||||||
const [passwordError, setPasswordError] = React.useState('');
|
const [passwordError, setPasswordError] = React.useState('');
|
||||||
@ -167,6 +166,7 @@ const CompanyProfile = () => {
|
|||||||
const initialSnapshotRef = React.useRef(createEmptyProfile());
|
const initialSnapshotRef = React.useRef(createEmptyProfile());
|
||||||
const toastTimeoutRef = React.useRef(null);
|
const toastTimeoutRef = React.useRef(null);
|
||||||
const [isDeletingApi, setIsDeletingApi] = React.useState(false);
|
const [isDeletingApi, setIsDeletingApi] = React.useState(false);
|
||||||
|
const [totalItems, setTotalItems] = React.useState(0);
|
||||||
|
|
||||||
const showToast = React.useCallback((type, message) => {
|
const showToast = React.useCallback((type, message) => {
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
@ -812,112 +812,7 @@ const CompanyProfile = () => {
|
|||||||
setActiveStep((prev) => Math.min(prev + 1, formSteps.length - 1));
|
setActiveStep((prev) => Math.min(prev + 1, formSteps.length - 1));
|
||||||
}, [activeStep, form.userProfilePassword, form.userProfileConfirmPassword, formSteps.length, validateStepFields]);
|
}, [activeStep, form.userProfilePassword, form.userProfileConfirmPassword, formSteps.length, validateStepFields]);
|
||||||
|
|
||||||
const handleSort = React.useCallback(
|
const handleToggleStatus = (item) => {
|
||||||
(field) => {
|
|
||||||
setSortConfig((prev) => {
|
|
||||||
if (prev.field === field) {
|
|
||||||
return { field, direction: prev.direction === 'asc' ? 'desc' : 'asc' };
|
|
||||||
}
|
|
||||||
return { field, direction: 'asc' };
|
|
||||||
});
|
|
||||||
setCurrentPage(1);
|
|
||||||
},
|
|
||||||
[setCurrentPage]
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderSortableHeader = React.useCallback(
|
|
||||||
(label, field) => {
|
|
||||||
const isActive = sortConfig.field === field;
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleSort(field)}
|
|
||||||
className="flex items-center text-left w-full group focus:outline-none"
|
|
||||||
aria-label={`Sort by ${label}`}
|
|
||||||
>
|
|
||||||
<span className={`text-xs font-medium ${isActive ? 'text-[#92722A]' : 'text-[#1B1D21]'}`}>{label}</span>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[handleSort, sortConfig]
|
|
||||||
);
|
|
||||||
|
|
||||||
const headers = [
|
|
||||||
'Establishment Name',
|
|
||||||
'Contact Name',
|
|
||||||
'Emirate',
|
|
||||||
'ISIC Code',
|
|
||||||
'Establishment ID',
|
|
||||||
'Products',
|
|
||||||
'Total Employees',
|
|
||||||
'Created By',
|
|
||||||
'Created On',
|
|
||||||
'Last Updated',
|
|
||||||
'Status',
|
|
||||||
'Actions',
|
|
||||||
];
|
|
||||||
|
|
||||||
const columnWidths = React.useMemo(() => {
|
|
||||||
const base = [
|
|
||||||
250, // Establishment Name (250px)
|
|
||||||
150, // Contact Name (150px)
|
|
||||||
120, // Emirate (120px)
|
|
||||||
120, // ISIC Code (120px)
|
|
||||||
150, // Establishment ID (150px)
|
|
||||||
100, // Products (100px)
|
|
||||||
120, // Total Employees (120px)
|
|
||||||
120, // Created By (120px)
|
|
||||||
120, // Created On (120px)
|
|
||||||
120, // Last Updated (120px)
|
|
||||||
100, // Status (100px)
|
|
||||||
150, // Actions (150px)
|
|
||||||
];
|
|
||||||
return base;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const contactToCorporateMap = React.useMemo(
|
|
||||||
() => ({
|
|
||||||
contactName: 'corporateName',
|
|
||||||
contactAddress: 'corporateAddress',
|
|
||||||
contactCityTown: 'corporateCityTown',
|
|
||||||
contactCityTownId: 'corporateCityTownId',
|
|
||||||
contactEmirate: 'corporateEmirate',
|
|
||||||
contactEmirateId: 'corporateEmirateId',
|
|
||||||
contactPostalCode: 'corporatePostalCode',
|
|
||||||
contactPoBox: 'corporatePoBox',
|
|
||||||
contactMakaniNumber: 'corporateMakaniNumber',
|
|
||||||
contactPersonName: 'corporateContactPersonName',
|
|
||||||
contactPersonDesignation: 'corporateContactPersonDesignation',
|
|
||||||
contactCountryCode: 'corporateCountryCode',
|
|
||||||
contactMobileNumber: 'corporateMobileNumber',
|
|
||||||
contactEmail: 'corporateEmail',
|
|
||||||
contactWebsite: 'corporateWebsite',
|
|
||||||
}),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const computeFieldErrorMessage = React.useCallback((field, value) => {
|
|
||||||
if (field === 'contactWebsite' || field === 'corporateWebsite') {
|
|
||||||
return getWebsiteValidationMessage(value);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const corporateFieldKeys = React.useMemo(() => Object.values(contactToCorporateMap), [contactToCorporateMap]);
|
|
||||||
const corporateBackupRef = React.useRef(null);
|
|
||||||
|
|
||||||
const captureCorporateValues = React.useCallback(
|
|
||||||
(source) => {
|
|
||||||
const snapshot = {};
|
|
||||||
corporateFieldKeys.forEach((key) => {
|
|
||||||
snapshot[key] = source?.[key] ?? '';
|
|
||||||
});
|
|
||||||
return snapshot;
|
|
||||||
},
|
|
||||||
[corporateFieldKeys]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleToggleStatus = (item) => {
|
|
||||||
const updatedStatus = item.status === 'Active' ? 'Inactive' : 'Active';
|
const updatedStatus = item.status === 'Active' ? 'Inactive' : 'Active';
|
||||||
|
|
||||||
// Optional: call your API to update backend
|
// Optional: call your API to update backend
|
||||||
@ -947,103 +842,30 @@ const CompanyProfile = () => {
|
|||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(normalized)
|
.includes(normalized)
|
||||||
);
|
);
|
||||||
}, [profiles, debouncedSearch]);
|
}, [profiles, debouncedSearch, selectedStatusFilter]);
|
||||||
|
|
||||||
const sortedProfiles = React.useMemo(() => {
|
// Render status badge with appropriate styling
|
||||||
const parseDateValue = (value) => {
|
const renderStatusBadge = (status) => {
|
||||||
if (!value) return 0;
|
const statusMap = {
|
||||||
if (value instanceof Date) return value.getTime();
|
active: { text: 'Active', bgColor: 'bg-[#F3FAF4]', textColor: 'text-[#2F663C]' },
|
||||||
if (typeof value === 'number') return value;
|
inactive: { text: 'Inactive', bgColor: 'bg-[#FEF2F2]', textColor: 'text-[#B91C1C]' },
|
||||||
if (typeof value === 'string') {
|
pending: { text: 'Pending', bgColor: 'bg-[#FFFBEB]', textColor: 'text-[#B45309]' },
|
||||||
const parts = value.split(/[\/-]/).map((part) => part.trim());
|
// Add more status mappings as needed
|
||||||
if (parts.length === 3) {
|
|
||||||
const day = Number(parts[0]);
|
|
||||||
const month = Number(parts[1]);
|
|
||||||
const year = Number(parts[2]);
|
|
||||||
if ([day, month, year].every((part) => Number.isFinite(part))) {
|
|
||||||
const timestamp = Date.UTC(year, month - 1, day);
|
|
||||||
if (!Number.isNaN(timestamp)) {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const parsed = Date.parse(value);
|
|
||||||
return Number.isNaN(parsed) ? 0 : parsed;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!sortConfig?.field) {
|
const statusConfig = statusMap[status?.toLowerCase()] || { text: status, bgColor: 'bg-gray-100', textColor: 'text-gray-800' };
|
||||||
return filteredProfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
const multiplier = sortConfig.direction === 'asc' ? 1 : -1;
|
|
||||||
const items = [...filteredProfiles];
|
|
||||||
items.sort((a, b) => {
|
|
||||||
let result = 0;
|
|
||||||
switch (sortConfig.field) {
|
|
||||||
case 'totalEmployees': {
|
|
||||||
const aValue = Number(a.totalEmployees) || 0;
|
|
||||||
const bValue = Number(b.totalEmployees) || 0;
|
|
||||||
result = aValue - bValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'createdOn': {
|
|
||||||
const aValue = parseDateValue(a.createdOn);
|
|
||||||
const bValue = parseDateValue(b.createdOn);
|
|
||||||
result = aValue - bValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'lastUpdated': {
|
|
||||||
const aValue = (a.lastUpdated || '').toString();
|
|
||||||
const bValue = (b.lastUpdated || '').toString();
|
|
||||||
result = aValue.localeCompare(bValue, undefined, { sensitivity: 'base' });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
const aValue = (a.establishmentName || '').toString();
|
|
||||||
const bValue = (b.establishmentName || '').toString();
|
|
||||||
result = aValue.localeCompare(bValue, undefined, { sensitivity: 'base' });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result === 0) {
|
|
||||||
const fallbackA = (a.establishmentName || '').toString();
|
|
||||||
const fallbackB = (b.establishmentName || '').toString();
|
|
||||||
result = fallbackA.localeCompare(fallbackB, undefined, { sensitivity: 'base' });
|
|
||||||
}
|
|
||||||
|
|
||||||
return result * multiplier;
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
|
||||||
}, [filteredProfiles, sortConfig]);
|
|
||||||
|
|
||||||
const renderStatusBadge = React.useCallback((status) => {
|
|
||||||
const normalized = typeof status === 'string' ? status.trim().toLowerCase() : '';
|
|
||||||
const isActiveStatus = normalized !== 'inactive';
|
|
||||||
const label = isActiveStatus ? 'Active' : 'Inactive';
|
|
||||||
const baseClasses =
|
|
||||||
'inline-flex items-center justify-center px-3 py-1 text-xs font-medium rounded-md';
|
|
||||||
const activeClasses = 'text-[#2F663C] bg-[#F3FAF4]';
|
|
||||||
const inactiveClasses = 'text-[#344054] bg-[#F8F9FC] border-[#D0D5DD]';
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${statusConfig.bgColor} ${statusConfig.textColor}`}>
|
||||||
className={`${baseClasses} ${isActiveStatus ? activeClasses : inactiveClasses}`}
|
{statusConfig.text}
|
||||||
aria-label={`Status: ${label}`}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
// Apply pagination to sorted profiles
|
// Calculate pagination range
|
||||||
const paginatedProfiles = React.useMemo(() => {
|
const startIndex = (currentPage - 1) * pageSize;
|
||||||
const startIndex = (currentPage - 1) * pageSize;
|
const endIndex = Math.min(startIndex + pageSize, filteredProfiles.length);
|
||||||
const endIndex = startIndex + pageSize;
|
const paginatedProfiles = filteredProfiles.slice(startIndex, endIndex);
|
||||||
return sortedProfiles.slice(startIndex, endIndex);
|
|
||||||
}, [sortedProfiles, currentPage, pageSize]);
|
|
||||||
|
|
||||||
const displayedRows = paginatedProfiles.map((item) => {
|
const displayedRows = paginatedProfiles.map((item) => {
|
||||||
const isEditing =
|
const isEditing =
|
||||||
@ -1326,37 +1148,39 @@ const CompanyProfile = () => {
|
|||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
|
||||||
const loadProfiles = async () => {
|
const loadProfiles = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const params = {
|
const params = {
|
||||||
page: exportInProgressRef.current ? 1 : currentPage,
|
page: currentPage,
|
||||||
limit: exportInProgressRef.current ? pageSize : pageSize,
|
limit: pageSize,
|
||||||
search: debouncedSearch || undefined,
|
search: debouncedSearch || undefined,
|
||||||
emirateId: selectedEmirateFilter || undefined,
|
emirateId: selectedEmirateFilter || undefined,
|
||||||
isicCode: undefined,
|
status: selectedStatusFilter || undefined,
|
||||||
status: selectedStatusFilter || undefined,
|
};
|
||||||
sortBy: sortConfig.field === 'establishmentName' ? 'factory_name' : sortConfig.field,
|
|
||||||
sortOrder: sortConfig.direction?.toUpperCase(),
|
try {
|
||||||
};
|
const response = await fetchEstablishments({ params, signal: controller.signal });
|
||||||
try {
|
const payload = response?.data ?? response;
|
||||||
const response = await fetchEstablishments({ params, signal: controller.signal });
|
const records = Array.isArray(payload?.data) ? payload.data : Array.isArray(payload) ? payload : [];
|
||||||
const payload = response?.data ?? response;
|
|
||||||
const records = Array.isArray(payload?.data) ? payload.data : Array.isArray(payload) ? payload : [];
|
if (!cancelled) {
|
||||||
if (!cancelled) {
|
setProfiles(records.map(mapApiEstablishmentToProfile));
|
||||||
setProfiles(records.map(mapApiEstablishmentToProfile));
|
// Update total items from API response or use records length as fallback
|
||||||
}
|
const apiTotal = payload?.total || payload?.count || records.length;
|
||||||
} catch (error) {
|
setTotalItems(apiTotal);
|
||||||
if (cancelled) return;
|
}
|
||||||
if (error.name === 'CanceledError' || error.name === 'AbortError') return;
|
} catch (error) {
|
||||||
console.error('Failed to fetch establishments list.', error);
|
if (cancelled) return;
|
||||||
const message = error?.response?.data?.message || error?.message || 'Unable to load establishments. Using default data.';
|
if (error.name === 'CanceledError' || error.name === 'AbortError') return;
|
||||||
showToast('error', message);
|
console.error('Failed to fetch establishments list.', error);
|
||||||
} finally {
|
const message = error?.response?.data?.message || error?.message || 'Unable to load establishments.';
|
||||||
if (!cancelled) {
|
showToast('error', message);
|
||||||
setIsLoading(false);
|
} finally {
|
||||||
}
|
if (!cancelled) {
|
||||||
}
|
setIsLoading(false);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (!exportInProgressRef.current) {
|
if (!exportInProgressRef.current) {
|
||||||
loadProfiles();
|
loadProfiles();
|
||||||
@ -1367,7 +1191,7 @@ const CompanyProfile = () => {
|
|||||||
controller.abort();
|
controller.abort();
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
}, [currentPage, pageSize, debouncedSearch, sortConfig, selectedEmirateFilter, selectedStatusFilter, mapApiEstablishmentToProfile, showToast]);
|
}, [currentPage, pageSize, debouncedSearch, selectedEmirateFilter, selectedStatusFilter, mapApiEstablishmentToProfile, showToast]);
|
||||||
|
|
||||||
const handleExport = React.useCallback(async () => {
|
const handleExport = React.useCallback(async () => {
|
||||||
if (isLoading) return;
|
if (isLoading) return;
|
||||||
@ -1380,8 +1204,6 @@ const CompanyProfile = () => {
|
|||||||
search: debouncedSearch || undefined,
|
search: debouncedSearch || undefined,
|
||||||
emirateId: selectedEmirateFilter || undefined,
|
emirateId: selectedEmirateFilter || undefined,
|
||||||
status: selectedStatusFilter || undefined,
|
status: selectedStatusFilter || undefined,
|
||||||
sortBy: sortConfig.field === 'establishmentName' ? 'factory_name' : sortConfig.field,
|
|
||||||
sortOrder: sortConfig.direction?.toUpperCase(),
|
|
||||||
export: 'excel',
|
export: 'excel',
|
||||||
},
|
},
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
@ -1410,7 +1232,7 @@ const CompanyProfile = () => {
|
|||||||
} finally {
|
} finally {
|
||||||
exportInProgressRef.current = false;
|
exportInProgressRef.current = false;
|
||||||
}
|
}
|
||||||
}, [currentPage, pageSize, debouncedSearch, sortConfig, selectedEmirateFilter, selectedStatusFilter, isLoading, showToast]);
|
}, [currentPage, pageSize, debouncedSearch, selectedEmirateFilter, selectedStatusFilter, isLoading, showToast]);
|
||||||
|
|
||||||
const emirateFilterOptions = React.useMemo(() => [{ label: 'All Emirates', value: '' }, ...emirateOptions], [emirateOptions]);
|
const emirateFilterOptions = React.useMemo(() => [{ label: 'All Emirates', value: '' }, ...emirateOptions], [emirateOptions]);
|
||||||
|
|
||||||
@ -2072,15 +1894,49 @@ const CompanyProfile = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Table
|
<Table
|
||||||
headers={headers}
|
headers={[
|
||||||
|
'Establishment Name',
|
||||||
|
'Contact Name',
|
||||||
|
'Emirate',
|
||||||
|
'ISIC Code',
|
||||||
|
'Establishment ID',
|
||||||
|
'Products',
|
||||||
|
'Total Employees',
|
||||||
|
'Created By',
|
||||||
|
'Created On',
|
||||||
|
'Last Updated',
|
||||||
|
'Status',
|
||||||
|
'Actions',
|
||||||
|
]}
|
||||||
rows={displayedRows}
|
rows={displayedRows}
|
||||||
columnWidths={columnWidths}
|
columnWidths={[
|
||||||
|
250, // Establishment Name (250px)
|
||||||
|
150, // Contact Name (150px)
|
||||||
|
120, // Emirate (120px)
|
||||||
|
120, // ISIC Code (120px)
|
||||||
|
150, // Establishment ID (150px)
|
||||||
|
100, // Products (100px)
|
||||||
|
120, // Total Employees (120px)
|
||||||
|
120, // Created By (120px)
|
||||||
|
120, // Created On (120px)
|
||||||
|
120, // Last Updated (120px)
|
||||||
|
100, // Status (100px)
|
||||||
|
150, // Actions (150px)
|
||||||
|
]}
|
||||||
pagination={{
|
pagination={{
|
||||||
currentPage,
|
currentPage,
|
||||||
onPageChange: setCurrentPage,
|
onPageChange: (page) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
// Scroll to top when changing pages
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
},
|
||||||
pageSize,
|
pageSize,
|
||||||
totalItems: filteredProfiles.length,
|
totalItems: filteredProfiles.length, // Use filtered count for pagination
|
||||||
pageSizeOptions: [10, 20, 50, 100],
|
pageSizeOptions: [10, 20, 50, 100],
|
||||||
|
onPageSizeChange: (size) => {
|
||||||
|
setPageSize(size);
|
||||||
|
setCurrentPage(1); // Reset to first page when changing page size
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user