import bug fixed
This commit is contained in:
parent
722d9fcaae
commit
142bd4f21f
@ -77,7 +77,7 @@ const AddAdminUsers = ({ isOpen, onClose, onSave }) => {
|
|||||||
if (!/[a-z]/.test(password)) return 'Must contain at least one lowercase letter';
|
if (!/[a-z]/.test(password)) return 'Must contain at least one lowercase letter';
|
||||||
if (!/\d/.test(password)) return 'Must contain at least one number';
|
if (!/\d/.test(password)) return 'Must contain at least one number';
|
||||||
if (!/[!@#$%^&*]/.test(password)) return 'Must contain at least one special character (!@#$%^&*)';
|
if (!/[!@#$%^&*]/.test(password)) return 'Must contain at least one special character (!@#$%^&*)';
|
||||||
return '';
|
return ''; // Return empty string if password is valid
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
@ -85,20 +85,27 @@ const AddAdminUsers = ({ isOpen, onClose, onSave }) => {
|
|||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||||
|
|
||||||
// Clear any existing error for this field
|
// Clear any existing error for this field
|
||||||
if (errors[name]) setErrors((prev) => ({ ...prev, [name]: '' }));
|
if (errors[name]) {
|
||||||
|
setErrors(prev => ({ ...prev, [name]: '' }));
|
||||||
|
}
|
||||||
|
|
||||||
// Real-time password validation
|
// Handle password field changes
|
||||||
if (name === 'password') {
|
if (name === 'password') {
|
||||||
setPasswordTouched(true);
|
setPasswordTouched(true);
|
||||||
const error = validatePassword(value);
|
const error = validatePassword(value);
|
||||||
setPasswordError(error);
|
setPasswordError(error);
|
||||||
|
|
||||||
|
// If password is valid and matches confirm password, clear confirm password error
|
||||||
|
if (!error && formData.confirmPassword && value === formData.confirmPassword) {
|
||||||
|
setErrors(prev => ({ ...prev, confirmPassword: '' }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear confirm password error when either password changes
|
// Handle confirm password field changes
|
||||||
if ((name === 'password' || name === 'confirmPassword') && formData.password && formData.confirmPassword) {
|
if (name === 'confirmPassword') {
|
||||||
if (formData.password !== formData.confirmPassword) {
|
if (value && formData.password !== value) {
|
||||||
setErrors(prev => ({ ...prev, confirmPassword: 'Passwords do not match' }));
|
setErrors(prev => ({ ...prev, confirmPassword: 'Passwords do not match' }));
|
||||||
} else {
|
} else if (value && formData.password === value) {
|
||||||
setErrors(prev => ({ ...prev, confirmPassword: '' }));
|
setErrors(prev => ({ ...prev, confirmPassword: '' }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,9 +218,9 @@ const AddAdminUsers = ({ isOpen, onClose, onSave }) => {
|
|||||||
placeholder="Confirm password"
|
placeholder="Confirm password"
|
||||||
showToggle
|
showToggle
|
||||||
/>
|
/>
|
||||||
{formData.confirmPassword && !errors.confirmPassword && (
|
{/* {formData.confirmPassword && !errors.confirmPassword && (
|
||||||
<p className="mt-1 text-xs text-green-600">Passwords match</p>
|
<p className="mt-1 text-xs text-green-600">Passwords match</p>
|
||||||
)}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="md:col-span-2 space-y-2">
|
<div className="md:col-span-2 space-y-2">
|
||||||
|
|||||||
@ -17,10 +17,7 @@ const EditUserModal = ({ formData, setFormData, onClose, onUpdate }) => {
|
|||||||
|
|
||||||
{/* Form */}
|
{/* Form */}
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={onUpdate}
|
||||||
e.preventDefault();
|
|
||||||
onUpdate();
|
|
||||||
}}
|
|
||||||
className="flex flex-col gap-4"
|
className="flex flex-col gap-4"
|
||||||
>
|
>
|
||||||
{/* Name & Email in one row */}
|
{/* Name & Email in one row */}
|
||||||
|
|||||||
@ -104,11 +104,13 @@ const AdminUsers = () => {
|
|||||||
}, 4000);
|
}, 4000);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch users
|
// Fetch users with pagination
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchUsers = async () => {
|
const fetchUsers = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
// Pass currentPage and pageSize to the API if it supports pagination
|
||||||
|
// If not, we'll handle pagination client-side
|
||||||
const res = await getAdminUser();
|
const res = await getAdminUser();
|
||||||
|
|
||||||
const usersData = Array.isArray(res)
|
const usersData = Array.isArray(res)
|
||||||
@ -117,7 +119,7 @@ const AdminUsers = () => {
|
|||||||
? res.data
|
? res.data
|
||||||
: Array.isArray(res?.data?.data)
|
: Array.isArray(res?.data?.data)
|
||||||
? res.data.data
|
? res.data.data
|
||||||
: null;
|
: [];
|
||||||
|
|
||||||
if (!usersData) {
|
if (!usersData) {
|
||||||
showToast('Failed to load users', 'error');
|
showToast('Failed to load users', 'error');
|
||||||
@ -163,7 +165,7 @@ const AdminUsers = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fetchUsers();
|
fetchUsers();
|
||||||
}, []);
|
}, [currentPage]); // Add currentPage as a dependency
|
||||||
|
|
||||||
const totalUsers = users.length;
|
const totalUsers = users.length;
|
||||||
const activeUsers = users.filter((user) => user.status === 'Active').length;
|
const activeUsers = users.filter((user) => user.status === 'Active').length;
|
||||||
@ -294,38 +296,41 @@ const AdminUsers = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEditingRow(user);
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await getAdminUserById(user.id);
|
setLoading(true);
|
||||||
const payload = res?.data ?? res;
|
|
||||||
if (!payload) throw new Error('No user data returned from API');
|
|
||||||
|
|
||||||
const name = payload.name ?? payload.fullName ?? user.name ?? '';
|
// Fetch the latest user data from the API
|
||||||
const email = payload.email ?? user.email ?? '';
|
const response = await getAdminUserById(user.id);
|
||||||
const is_active =
|
const userData = response?.data?.data || response?.data || response;
|
||||||
payload.is_active !== undefined ? !!payload.is_active : !!user.is_active;
|
|
||||||
|
|
||||||
setCurrentUser({
|
if (!userData) {
|
||||||
...payload,
|
throw new Error('Failed to fetch user data');
|
||||||
id: user.id,
|
}
|
||||||
name,
|
|
||||||
email,
|
|
||||||
is_active,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Map the API response to match our form data structure
|
||||||
|
const userToEdit = {
|
||||||
|
id: userData.id || userData._id || user.id,
|
||||||
|
name: userData.name || userData.fullName || '',
|
||||||
|
email: userData.email || '',
|
||||||
|
status: userData.is_active ? 'Active' : 'Inactive',
|
||||||
|
is_active: userData.is_active !== undefined ? userData.is_active : true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the current user and form data
|
||||||
|
setCurrentUser(userToEdit);
|
||||||
setFormData({
|
setFormData({
|
||||||
name,
|
name: userToEdit.name,
|
||||||
email,
|
email: userToEdit.email,
|
||||||
status: is_active ? 'Active' : 'Inactive',
|
status: userToEdit.status,
|
||||||
});
|
});
|
||||||
|
|
||||||
setErrors({});
|
setEditingRow(userToEdit);
|
||||||
setIsEditModalOpen(true);
|
setIsEditModalOpen(true);
|
||||||
|
setErrors({});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching user data:', error);
|
console.error('Error fetching user data:', error);
|
||||||
showToast(error?.response?.data?.message || 'Failed to load user data', 'error');
|
showToast('Failed to load user data. Please try again.', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@ -476,13 +481,21 @@ const AdminUsers = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (rowIndex) => {
|
const handleDelete = (rowIndex) => {
|
||||||
const user = users[rowIndex];
|
// Calculate the actual index in the full users array based on pagination
|
||||||
setSelectedUser(user);
|
const actualIndex = (currentPage - 1) * pageSize + rowIndex;
|
||||||
setShowDeleteModal(true);
|
const user = users[actualIndex];
|
||||||
|
if (user) {
|
||||||
|
setSelectedUser(user);
|
||||||
|
setShowDeleteModal(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditSubmit = async (e) => {
|
const handleEditSubmit = async (e) => {
|
||||||
e.preventDefault();
|
// Prevent default form submission if event is provided
|
||||||
|
if (e && e.preventDefault) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
const formErrors = validateForm();
|
const formErrors = validateForm();
|
||||||
if (Object.keys(formErrors).length > 0) {
|
if (Object.keys(formErrors).length > 0) {
|
||||||
setErrors(formErrors);
|
setErrors(formErrors);
|
||||||
@ -512,6 +525,7 @@ const AdminUsers = () => {
|
|||||||
|
|
||||||
if (!success) throw new Error(res?.message || 'Failed to update user');
|
if (!success) throw new Error(res?.message || 'Failed to update user');
|
||||||
|
|
||||||
|
// Update the users list with the updated user data
|
||||||
setUsers((prev) =>
|
setUsers((prev) =>
|
||||||
prev.map((u) =>
|
prev.map((u) =>
|
||||||
u.id === currentUser.id
|
u.id === currentUser.id
|
||||||
@ -521,6 +535,13 @@ const AdminUsers = () => {
|
|||||||
email: formData.email,
|
email: formData.email,
|
||||||
status: formData.status,
|
status: formData.status,
|
||||||
is_active: formData.status === 'Active',
|
is_active: formData.status === 'Active',
|
||||||
|
lastLogin: u.lastLogin, // Preserve the last login time
|
||||||
|
raw: {
|
||||||
|
...(u.raw || {}),
|
||||||
|
name: formData.name,
|
||||||
|
email: formData.email,
|
||||||
|
is_active: formData.status === 'Active'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
: u
|
: u
|
||||||
)
|
)
|
||||||
@ -530,6 +551,13 @@ const AdminUsers = () => {
|
|||||||
setIsEditModalOpen(false);
|
setIsEditModalOpen(false);
|
||||||
setEditingRow(null);
|
setEditingRow(null);
|
||||||
setCurrentUser(null);
|
setCurrentUser(null);
|
||||||
|
|
||||||
|
// Reset form data
|
||||||
|
setFormData({
|
||||||
|
name: '',
|
||||||
|
email: '',
|
||||||
|
status: 'Active',
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error updating user:', error);
|
console.error('Error updating user:', error);
|
||||||
showToast(error?.response?.data?.message || 'Failed to update user', 'error');
|
showToast(error?.response?.data?.message || 'Failed to update user', 'error');
|
||||||
@ -630,7 +658,11 @@ const AdminUsers = () => {
|
|||||||
}}
|
}}
|
||||||
renderCell={(value, rowIndex, colIndex) => {
|
renderCell={(value, rowIndex, colIndex) => {
|
||||||
if (colIndex === 4) {
|
if (colIndex === 4) {
|
||||||
const user = users[rowIndex];
|
// Calculate the actual index in the full users array based on pagination
|
||||||
|
const actualIndex = (currentPage - 1) * pageSize + rowIndex;
|
||||||
|
const user = users[actualIndex];
|
||||||
|
if (!user) return null;
|
||||||
|
|
||||||
const isActive = user.status === 'Active';
|
const isActive = user.status === 'Active';
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@ -638,7 +670,7 @@ const AdminUsers = () => {
|
|||||||
type="button"
|
type="button"
|
||||||
className="h-8 w-8 grid place-items-center rounded hover:bg-gray-50 cursor-pointer"
|
className="h-8 w-8 grid place-items-center rounded hover:bg-gray-50 cursor-pointer"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
onClick={() => handleEdit(user)}
|
onClick={() => handleEdit(user.raw || user)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={editingRow?.id === user.id ? pencilActiveSrc : pencilInactiveSrc}
|
src={editingRow?.id === user.id ? pencilActiveSrc : pencilInactiveSrc}
|
||||||
@ -707,12 +739,18 @@ const AdminUsers = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Edit Modal */}
|
{/* Edit Modal */}
|
||||||
{isEditModalOpen && (
|
{isEditModalOpen && currentUser && (
|
||||||
<EditUserModal
|
<EditUserModal
|
||||||
formData={formData}
|
formData={formData}
|
||||||
setFormData={setFormData}
|
setFormData={setFormData}
|
||||||
onClose={() => setIsEditModalOpen(false)}
|
onClose={() => {
|
||||||
onUpdate={handleUpdateUser}
|
setIsEditModalOpen(false);
|
||||||
|
setCurrentUser(null);
|
||||||
|
setFormData({ name: '', email: '', status: 'Active' });
|
||||||
|
setErrors({});
|
||||||
|
}}
|
||||||
|
onUpdate={handleEditSubmit}
|
||||||
|
key={currentUser.id} // Add key to force re-render when user changes
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -535,13 +535,16 @@ const IsicHsCodes = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleView = async (index) => {
|
const handleView = async (index) => {
|
||||||
const selected = rowsData[index];
|
// Calculate the actual index in the filtered data based on pagination
|
||||||
|
const actualIndex = (currentPage - 1) * pageSize + index;
|
||||||
|
const selected = filteredData[actualIndex];
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const productId = selected.id;
|
// Get fresh data from the server using the ID
|
||||||
const response = await productService.getProductById(productId);
|
const response = await productService.getProductById(selected.id);
|
||||||
|
|
||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
const product = response.data;
|
const product = response.data;
|
||||||
setForm({
|
setForm({
|
||||||
@ -551,8 +554,8 @@ const IsicHsCodes = () => {
|
|||||||
status: product.is_active ? 'Active' : 'Inactive',
|
status: product.is_active ? 'Active' : 'Inactive',
|
||||||
description: product.hs_description || '',
|
description: product.hs_description || '',
|
||||||
createdBy: selected.createdBy,
|
createdBy: selected.createdBy,
|
||||||
createdOn: selected.createdOn,
|
createdOn: selected.createdOn || new Date(product.created_at).toLocaleDateString('en-GB'),
|
||||||
updated: selected.updated
|
updated: selected.updated || (product.updated_at ? new Date(product.updated_at).toLocaleDateString('en-GB') : '')
|
||||||
});
|
});
|
||||||
setModalMode('view');
|
setModalMode('view');
|
||||||
} else {
|
} else {
|
||||||
@ -568,7 +571,9 @@ const IsicHsCodes = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleEdit = async (index) => {
|
const handleEdit = async (index) => {
|
||||||
const selected = rowsData[index];
|
// Calculate the actual index in the filtered data based on pagination
|
||||||
|
const actualIndex = (currentPage - 1) * pageSize + index;
|
||||||
|
const selected = filteredData[actualIndex];
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -621,38 +626,37 @@ const IsicHsCodes = () => {
|
|||||||
|
|
||||||
const handleDelete = async (paginationIndex) => {
|
const handleDelete = async (paginationIndex) => {
|
||||||
const dataIndex = (currentPage - 1) * pageSize + paginationIndex;
|
const dataIndex = (currentPage - 1) * pageSize + paginationIndex;
|
||||||
if (dataIndex < 0 || dataIndex >= rowsData.length) {
|
const selected = rowsData[dataIndex];
|
||||||
console.error('Invalid row index for deletion');
|
|
||||||
|
if (!selected || !selected.id) {
|
||||||
|
console.error('No product selected or missing ID');
|
||||||
|
showToast('Cannot delete: Product information is incomplete', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const productId = rowsData[dataIndex]?.id;
|
|
||||||
if (!productId) {
|
|
||||||
console.error('No product ID found for deletion');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDeletingRowIndex(dataIndex);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await productService.getProductById(productId);
|
|
||||||
|
// Fetch the latest product data before showing delete confirmation
|
||||||
|
const response = await productService.getProductById(selected.id);
|
||||||
|
|
||||||
if (!response || !response.data) {
|
if (!response || !response.data) {
|
||||||
throw new Error('Invalid product data received');
|
throw new Error('Invalid product data received');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the local data with the latest information
|
||||||
const updatedRowsData = [...rowsData];
|
const updatedRowsData = [...rowsData];
|
||||||
updatedRowsData[dataIndex] = {
|
updatedRowsData[dataIndex] = {
|
||||||
...updatedRowsData[dataIndex],
|
...selected,
|
||||||
...response.data
|
...response.data
|
||||||
};
|
};
|
||||||
|
|
||||||
setRowsData(updatedRowsData);
|
setRowsData(updatedRowsData);
|
||||||
|
setDeletingRowIndex(dataIndex);
|
||||||
setShowDeleteConfirm(true);
|
setShowDeleteConfirm(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error preparing product for deletion:', error);
|
console.error('Error preparing product for deletion:', error);
|
||||||
showToast('Error loading product details for deletion', 'error');
|
showToast('Error loading product details for deletion', 'error');
|
||||||
setDeletingRowIndex(null);
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@ -670,7 +674,6 @@ const IsicHsCodes = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteConfirm = async () => {
|
const handleDeleteConfirm = async () => {
|
||||||
|
|
||||||
if (deletingRowIndex === null || deletingRowIndex < 0 || deletingRowIndex >= rowsData.length) {
|
if (deletingRowIndex === null || deletingRowIndex < 0 || deletingRowIndex >= rowsData.length) {
|
||||||
const errorMsg = 'Invalid row selected for deletion';
|
const errorMsg = 'Invalid row selected for deletion';
|
||||||
console.error(errorMsg, { deletingRowIndex, rowsDataLength: rowsData.length });
|
console.error(errorMsg, { deletingRowIndex, rowsDataLength: rowsData.length });
|
||||||
@ -693,6 +696,16 @@ const IsicHsCodes = () => {
|
|||||||
try {
|
try {
|
||||||
await productService.deleteProduct(productId);
|
await productService.deleteProduct(productId);
|
||||||
|
|
||||||
|
// Calculate the current page after deletion
|
||||||
|
const currentItemsCount = rowsData.length - 1; // After deletion
|
||||||
|
const maxPage = Math.max(1, Math.ceil(currentItemsCount / pageSize));
|
||||||
|
|
||||||
|
// If we're on a page that no longer exists after deletion, go to the previous page
|
||||||
|
// But only if we're not already on the first page
|
||||||
|
if (currentPage > maxPage && maxPage > 0) {
|
||||||
|
setCurrentPage(maxPage);
|
||||||
|
}
|
||||||
|
|
||||||
const newData = [...rowsData];
|
const newData = [...rowsData];
|
||||||
newData.splice(deletingRowIndex, 1);
|
newData.splice(deletingRowIndex, 1);
|
||||||
setRowsData(newData);
|
setRowsData(newData);
|
||||||
@ -701,6 +714,16 @@ const IsicHsCodes = () => {
|
|||||||
} catch (apiError) {
|
} catch (apiError) {
|
||||||
console.error('API Error:', apiError);
|
console.error('API Error:', apiError);
|
||||||
if (apiError.response && apiError.response.status === 204) {
|
if (apiError.response && apiError.response.status === 204) {
|
||||||
|
// Calculate the current page after deletion for 204 response
|
||||||
|
const currentItemsCount = rowsData.length - 1; // After deletion
|
||||||
|
const maxPage = Math.max(1, Math.ceil(currentItemsCount / pageSize));
|
||||||
|
|
||||||
|
// If we're on a page that no longer exists after deletion, go to the previous page
|
||||||
|
// But only if we're not already on the first page
|
||||||
|
if (currentPage > maxPage && maxPage > 0) {
|
||||||
|
setCurrentPage(maxPage);
|
||||||
|
}
|
||||||
|
|
||||||
const newData = [...rowsData];
|
const newData = [...rowsData];
|
||||||
newData.splice(deletingRowIndex, 1);
|
newData.splice(deletingRowIndex, 1);
|
||||||
setRowsData(newData);
|
setRowsData(newData);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect, useMemo, useRef } from 'react';
|
import React, { useState, useEffect, useMemo, useRef } from 'react';
|
||||||
import Table from '@/components/common/Table';
|
import Table from '@/components/common/Table';
|
||||||
import { TextField } from '@/components/common/FormControls';
|
import { TextField } from '@/components/common/FormControls';
|
||||||
import { getUnits, createUnit, updateUnit, deleteUnit, uploadUnitCSV } from '@/services/configuration/unitService';
|
import { getUnits, getUnitById, createUnit, updateUnit, deleteUnit, uploadUnitCSV } from '@/services/configuration/unitService';
|
||||||
|
|
||||||
const downloadIconSrc = '/assets/images/DownloadSimple.svg';
|
const downloadIconSrc = '/assets/images/DownloadSimple.svg';
|
||||||
const addIconSrc = '/assets/images/ic_baseline-plus.svg';
|
const addIconSrc = '/assets/images/ic_baseline-plus.svg';
|
||||||
@ -193,27 +193,108 @@ const UnitMaster = () => {
|
|||||||
setForm(createEmptyUnitForm());
|
setForm(createEmptyUnitForm());
|
||||||
setModalMode('add');
|
setModalMode('add');
|
||||||
};
|
};
|
||||||
const handleView = (index) => {
|
const handleView = async (index) => {
|
||||||
const selected = units[index];
|
try {
|
||||||
if (!selected) return;
|
setLoading(true);
|
||||||
setSelectedUnit(selected);
|
|
||||||
setModalMode('view');
|
// Get the actual index in the full units array based on pagination
|
||||||
|
const actualIndex = (currentPage - 1) * pageSize + index;
|
||||||
|
const selected = filteredUnits[actualIndex];
|
||||||
|
|
||||||
|
if (!selected) return;
|
||||||
|
|
||||||
|
// Fetch the latest unit data by ID using the getUnitById function
|
||||||
|
const response = await getUnitById(selected.id);
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
throw new Error('Failed to fetch unit data');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The API returns data in response.data
|
||||||
|
const unitData = response.data || response;
|
||||||
|
|
||||||
|
setSelectedUnit(unitData);
|
||||||
|
setModalMode('view');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching unit data:', error);
|
||||||
|
setToastData({
|
||||||
|
message: 'Failed to load unit data. Please try again.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEdit = (index) => {
|
const handleEdit = async (index) => {
|
||||||
const selected = filteredUnits[index];
|
try {
|
||||||
if (!selected) return;
|
setLoading(true);
|
||||||
setEditingRow(index);
|
|
||||||
setSelectedUnit(selected);
|
// Get the actual index in the full units array based on pagination
|
||||||
setForm({
|
const actualIndex = (currentPage - 1) * pageSize + index;
|
||||||
uom: selected.uom || '',
|
const selected = filteredUnits[actualIndex];
|
||||||
description: selected.description || '',
|
|
||||||
});
|
if (!selected) return;
|
||||||
setModalMode('edit');
|
|
||||||
|
// Fetch the latest unit data by ID using the getUnitById function
|
||||||
|
const response = await getUnitById(selected.id);
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
throw new Error('Failed to fetch unit data');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The API returns data in response.data
|
||||||
|
const unitData = response.data || response;
|
||||||
|
|
||||||
|
setEditingRow(selected.id);
|
||||||
|
setSelectedUnit(unitData);
|
||||||
|
setForm({
|
||||||
|
uom: unitData.uom || '',
|
||||||
|
description: unitData.description || '',
|
||||||
|
});
|
||||||
|
setModalMode('edit');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching unit data:', error);
|
||||||
|
setToastData({
|
||||||
|
message: 'Failed to load unit data. Please try again.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (index) => {
|
const handleDelete = async (index) => {
|
||||||
setDeletingRow(index);
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
// Get the actual index in the full units array based on pagination
|
||||||
|
const actualIndex = (currentPage - 1) * pageSize + index;
|
||||||
|
const selected = filteredUnits[actualIndex];
|
||||||
|
|
||||||
|
if (!selected) return;
|
||||||
|
|
||||||
|
// Fetch the latest unit data by ID using the getUnitById function
|
||||||
|
const response = await getUnitById(selected.id);
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
throw new Error('Failed to fetch unit data');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The API returns data in response.data
|
||||||
|
const unitData = response.data || response;
|
||||||
|
|
||||||
|
// Set the actual index in the filtered array for deletion
|
||||||
|
setDeletingRow(actualIndex);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching unit data:', error);
|
||||||
|
setToastData({
|
||||||
|
message: 'Failed to load unit data. Please try again.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
@ -276,8 +357,7 @@ const UnitMaster = () => {
|
|||||||
setSaveLoading(true);
|
setSaveLoading(true);
|
||||||
|
|
||||||
if (modalMode === 'edit' && editingRow !== null) {
|
if (modalMode === 'edit' && editingRow !== null) {
|
||||||
const unitToUpdate = filteredUnits[editingRow];
|
await updateUnit(editingRow, unitData);
|
||||||
await updateUnit(unitToUpdate.id, unitData);
|
|
||||||
|
|
||||||
setToastData({
|
setToastData({
|
||||||
message: 'Unit updated successfully!',
|
message: 'Unit updated successfully!',
|
||||||
|
|||||||
@ -10,6 +10,16 @@ export const getQuarterlyWindows = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getQuarterlyWindowById = async (id) => {
|
||||||
|
try {
|
||||||
|
const response = await getRequest(`/quarterly_windows/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching quarterly window with ID ${id}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const createQuarterlyWindow = async (data) => {
|
export const createQuarterlyWindow = async (data) => {
|
||||||
try {
|
try {
|
||||||
const response = await postRequest('/quarterly_windows', data);
|
const response = await postRequest('/quarterly_windows', data);
|
||||||
|
|||||||
@ -13,6 +13,17 @@ export const getUnits = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUnitById = async (id) => {
|
||||||
|
try {
|
||||||
|
const response = await getRequest(`${UNIT_MASTER_ENDPOINT}/${id}`);
|
||||||
|
// Handle nested data structure
|
||||||
|
return response.data || response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching unit with ID ${id}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const createUnit = async (unitData) => {
|
export const createUnit = async (unitData) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user