Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/actions/bmdashboard/consumableActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,8 @@ export const rejectConsumablePurchase = purchaseId => {
}
};
};

export default {
approveConsumablePurchase,
rejectConsumablePurchase,
};
202 changes: 25 additions & 177 deletions src/components/BMDashboard/ItemList/ItemListView.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
import { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { useSelector } from 'react-redux';

import BMError from '../shared/BMError';
import SelectForm from './SelectForm';
import SelectItem from './SelectItem';
import ItemsTable from './ItemsTable';
import UpdateHistoryModal from '../UpdateHistory/UpdateHistoryModal';
import styles from './ItemListView.module.css';
import { Form, FormGroup, Label } from 'reactstrap';
import AddMaterialModal from '../AddMaterial/AddMaterialModal';
import {
fetchMaterialTypes,
fetchConsumableTypes,
} from '../../../actions/bmdashboard/invTypeActions';
import EditNameUnitModal from './EditNameUnitModal';
import ViewUpdateHistoryModal from './ViewUpdateHistoryModal';
import AddConsumableModal from '../AddConsumable/AddConsumableModal';

export function ItemListView({
itemType,
Expand All @@ -27,29 +16,11 @@ export function ItemListView({
dynamicColumns,
children,
}) {
const darkMode = useSelector(state => state.theme.darkMode);
const [filteredItems, setFilteredItems] = useState(items);
const [selectedProject, setSelectedProject] = useState('all');
const [selectedItem, setSelectedItem] = useState('all');
const [isError, setIsError] = useState(false);
const [selectedTime, setSelectedTime] = useState(new Date());
const [updateHistoryModalOpen, setUpdateHistoryModalOpen] = useState(false);
const darkMode = useSelector(state => state.theme.darkMode);

const toggleUpdateHistoryModal = () => {
setUpdateHistoryModalOpen(prev => !prev);
};
const dispatch = useDispatch();
const materialTypes = useSelector(state => state.bmInvTypes.list);
const consumableTypes = useSelector(state => state.bmInvTypes.consumablesList);
const [isAMOpen, setisAMOpen] = useState(false); //MaterialsPage
const [selectedCondition, setSelectedCondition] = useState('all');
const [selectedToolStatus, setSelectedToolStatus] = useState('all');
const [isEditOpen, setisEditOpen] = useState(false);
const [selectedRow, setSelectedRow] = useState(null);
const [viewUpdate, setViewUpdate] = useState(false);
const [isACOpen, setisACOpen] = useState(false); //Consumables Page
const selectList = itemType === 'Consumables' ? consumableTypes : materialTypes;
const [rowToEdit, setRowtoEdit] = useState(null);

useEffect(() => {
if (items) setFilteredItems([...items]);
Expand All @@ -58,17 +29,14 @@ export function ItemListView({
useEffect(() => {
let filterItems;
if (!items) return;

if (selectedProject === 'all' && selectedItem === 'all') {
setFilteredItems([...items]);
} else if (selectedProject !== 'all' && selectedItem === 'all') {
filterItems = items.filter(item => item.project?.name === selectedProject);
setFilteredItems([...filterItems]);
} else if (selectedProject === 'all' && selectedItem !== 'all') {
if (itemType === 'Materials') {
filterItems = items.filter(item => item.name === selectedItem);
} else if (itemType === 'Consumables') {
filterItems = items.filter(item => item.itemType?.name === selectedItem);
}
filterItems = items.filter(item => item.itemType?.name === selectedItem);
setFilteredItems([...filterItems]);
} else {
filterItems = items.filter(
Expand All @@ -82,131 +50,44 @@ export function ItemListView({
setIsError(Object.entries(errors).length > 0);
}, [errors]);

useEffect(() => {
if (itemType === 'Materials') dispatch(fetchMaterialTypes());
if (itemType === 'Consumables') dispatch(fetchConsumableTypes());
}, [dispatch, itemType]);

if (isError) {
return (
<main className={`${styles.itemsListContainer} ${darkMode ? styles.darkMode : ''}`}>
<h2>
{itemType}
{' List'}
</h2>
<main className={`${styles.items_list_container} ${darkMode ? 'dark-mode dm-text' : ''}`}>
<h2 className={darkMode ? 'dm-text' : ''}>{itemType} List</h2>
<BMError errors={errors} />
</main>
);
}

const openAddModal = () => {
if (itemType === 'Materials') {
setisAMOpen(true);
} else if (itemType === 'Consumables') {
setisACOpen(true);
}
};
const handleEditClick = () => {
if (!selectedRow) return;
setRowtoEdit(selectedRow); // save for modal
setisEditOpen(true);
setSelectedRow(null);
};

const handleUpdateHistory = () => {
if (!selectedRow) return;
setRowtoEdit(selectedRow);
setViewUpdate(true);
setSelectedRow(null);
};

return (
<main className={`${styles.itemsListContainer} ${darkMode ? styles.darkMode : ''}`}>
<h3>{itemType}</h3>
<section>
<div
style={{ display: 'flex', flexDirection: 'column', gap: '15px', marginBottom: '20px' }}
<main className={`${styles.items_list_container} ${darkMode ? 'dark-mode dm-text' : ''}`}>
<h3 className={darkMode ? 'dm-text dm-heading' : ''}>{itemType}</h3>

<section className={darkMode ? 'dm-bg dm-border dm-section-solid' : ''}>
<span
style={{ display: 'flex', margin: '5px' }}
className={darkMode ? 'dm-bg dm-filter-contrast dm-border dm-text' : ''}
>
{items && (
<div className={`${styles.dropdownRow}`}>
<Form>
<FormGroup className={styles.datePickerGroup}>
<Label htmlFor="itemListTime">Time:</Label>
<DatePicker
selected={selectedTime}
onChange={date => setSelectedTime(date)}
showTimeSelect
timeFormat="HH:mm"
timeIntervals={15}
dateFormat="yyyy-MM-dd HH:mm:ss"
placeholderText="Select date and time"
id="itemListTime"
inputId="itemListTime" // This is the key line
className={darkMode ? styles.darkDatePickerInput : styles.lightDatePickerInput}
calendarClassName={darkMode ? styles.darkDatePicker : styles.lightDatePicker}
popperClassName={
darkMode ? styles.darkDatePickerPopper : styles.lightDatePickerPopper
}
/>
</FormGroup>
</Form>
<>
<SelectForm
items={items}
selectedProject={selectedProject}
setSelectedProject={setSelectedProject}
setSelectedItem={setSelectedItem}
setSelectedCondition={setSelectedCondition}
setSelectedToolStatus={setSelectedToolStatus}
/>

<SelectItem
items={selectList}
selectedItem={selectedItem}
items={items}
selectedProject={selectedProject}
selectedItem={selectedItem}
setSelectedItem={setSelectedItem}
label={itemType}
label={itemType === 'Materials' ? 'Material' : itemType}
darkMode={darkMode}
/>
</div>
</>
)}
</span>

<div className={`${styles.buttonsRow}`}>
<button type="button" className={`${styles.btnPrimary}`} onClick={openAddModal}>
Add {itemType}
</button>
<button type="button" className={`${styles.btnPrimary}`} onClick={handleEditClick}>
Edit Name/Measurement
</button>
<button type="button" className={`${styles.btnPrimary}`} onClick={handleUpdateHistory}>
View Update History
</button>
</div>
</div>

<UpdateHistoryModal
isOpen={updateHistoryModalOpen}
toggle={toggleUpdateHistoryModal}
itemType={itemType}
selectedProject={selectedProject}
/>

{children && (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: '15px',
flexWrap: 'wrap',
gap: '15px',
backgroundColor: darkMode ? '#2d2d2d' : '#f8f9fa',
padding: '12px 15px',
borderRadius: '6px',
border: darkMode ? '1px solid #444' : '1px solid #dee2e6',
}}
>
{children}
</div>
)}
{children}

{filteredItems && (
<ItemsTable
Expand All @@ -217,57 +98,24 @@ export function ItemListView({
dynamicColumns={dynamicColumns}
darkMode={darkMode}
itemType={itemType}
selectedRowId={selectedRow?._id}
onRowSelect={setSelectedRow}
/>
)}
</section>
<section>
<AddMaterialModal isAMOpen={isAMOpen} toggle={() => setisAMOpen(false)} />
</section>
<section>
<EditNameUnitModal
item={rowToEdit}
isOpen={isEditOpen}
toggle={() => setisEditOpen(false)}
/>
</section>
<section>
<ViewUpdateHistoryModal
item={rowToEdit}
isOpen={viewUpdate}
toggle={() => setViewUpdate(false)}
/>
</section>
<section>
<AddConsumableModal isACOpen={isACOpen} toggle={() => setisACOpen(false)} />
</section>
</main>
);
}

ItemListView.propTypes = {
itemType: PropTypes.string.isRequired,
items: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
itemType: PropTypes.shape({
name: PropTypes.string,
unit: PropTypes.string,
}),
project: PropTypes.shape({
_id: PropTypes.string,
name: PropTypes.string,
}),
stockAvailable: PropTypes.number,
stockBought: PropTypes.number,
stockUsed: PropTypes.number,
stockWasted: PropTypes.number,
id: PropTypes.number,
name: PropTypes.string,
}),
).isRequired,
errors: PropTypes.shape({
message: PropTypes.string,
}),
itemType: PropTypes.string.isRequired,
UpdateItemModal: PropTypes.elementType.isRequired,
dynamicColumns: PropTypes.arrayOf(
PropTypes.shape({
Expand Down
Loading
Loading