Added expiry date to the search page

This commit is contained in:
2026-03-08 16:36:36 +00:00
parent ec1def4d78
commit 6f0662271f
3 changed files with 205 additions and 40 deletions

View File

@@ -8,7 +8,7 @@ Webpage Playground is a lightweight, responsive web application for managing and
- **Dynamic Navigation** — Easy page switching with a responsive navbar - **Dynamic Navigation** — Easy page switching with a responsive navbar
- **Inventory Demo** — Display items using reusable item components - **Inventory Demo** — Display items using reusable item components
- **Advanced Search** — Filter inventory by name, location, and quantity range - **Advanced Search** — Filter inventory by name, location, quantity range, and expiry date
- **Barcode Scanner** — Scan barcodes for inventory management (keyboard and hardware scanner support) - **Barcode Scanner** — Scan barcodes for inventory management (keyboard and hardware scanner support)
- **Data Visualization** — Pie chart showing inventory distribution - **Data Visualization** — Pie chart showing inventory distribution
- **Responsive Design** — Works on desktop, tablet, and mobile devices - **Responsive Design** — Works on desktop, tablet, and mobile devices
@@ -17,7 +17,7 @@ Webpage Playground is a lightweight, responsive web application for managing and
### Pages ### Pages
- `index.html` — Homepage with item component demo and inventory pie chart - `index.html` — Homepage with item component demo and inventory pie chart
- `search.html` — Search and filter inventory by name, location, and quantity - `search.html` — Search and filter inventory by name, location, quantity, and expiry date
- `barcode.html` — Barcode scanner with console logging for testing - `barcode.html` — Barcode scanner with console logging for testing
- `pantry.html` — Pantry inventory container - `pantry.html` — Pantry inventory container
- `fridge.html` — Fridge inventory container - `fridge.html` — Fridge inventory container
@@ -27,7 +27,7 @@ Webpage Playground is a lightweight, responsive web application for managing and
- `navbar.js` — Dynamic navigation bar system loaded by all pages - `navbar.js` — Dynamic navigation bar system loaded by all pages
- `main.css` — Global styles and responsive design - `main.css` — Global styles and responsive design
- `item-component.js` — Reusable ES6 module for displaying inventory items in a grid - `item-component.js` — Reusable ES6 module for displaying inventory items in a grid
- `search.js` — Search and filtering logic with 20 sample inventory items - `search.js` — Search and filtering logic with 20 sample inventory items including expiry dates
- `barcode-scanner.js` — Barcode capture and console logging module - `barcode-scanner.js` — Barcode capture and console logging module
- `piechart.js` — Inventory distribution pie chart visualization - `piechart.js` — Inventory distribution pie chart visualization
@@ -55,20 +55,33 @@ Advanced inventory search and filtering interface.
- Search by item name (case-insensitive) - Search by item name (case-insensitive)
- Filter by storage location (All, Pantry, Fridge, Freezer) - Filter by storage location (All, Pantry, Fridge, Freezer)
- Filter by quantity range (min/max values) - Filter by quantity range (min/max values)
- **NEW: Filter by expiry date range (start date and end date)**
- Real-time result display with item cards - Real-time result display with item cards
- Visual expiry status indicators (Fresh, Expiring Soon, Expired)
- Reset button to clear all filters - Reset button to clear all filters
- Keyboard support (press Enter to search) - Keyboard support (press Enter to search)
- Date range validation (start date ≤ end date)
**Expiry Date Features:**
- Each inventory item includes an expiry date
- Visual badges show expiry status:
- 🟢 **Fresh** — Items expiring in more than 7 days
- 🟠 **Expiring Soon** — Items expiring within 7 days
- 🔴 **Expired** — Items past expiry date
- Formatted expiry dates displayed on item cards
- Filter by start and end date to find items expiring in a specific timeframe
**Sample Usage:** **Sample Usage:**
``` ```
Search for "milk" in the Fridge with quantity >= 1 Search for items expiring between March 15 and April 15
Results displayed using item-component for consistency Results show all items with expiry dates in that range
Items display formatted dates and expiry status badges
``` ```
**Available Items (20 total across all locations):** **Available Items (20 total across all locations):**
- Pantry: Pasta, Rice, Cereal, Flour, Sugar, Salt, Olive Oil, Canned Beans - Pantry: Pasta (120 days), Rice (180 days), Cereal (60 days), Flour (150 days), Sugar (200 days), Salt (365 days), Olive Oil (90 days), Canned Beans (EXPIRED -10 days)
- Fridge: Milk, Cheese, Greek Yogurt, Eggs, Butter, Chicken Salad - Fridge: Milk (5 days), Cheese (30 days), Greek Yogurt (7 days), Eggs (21 days), Butter (45 days), Chicken Salad (EXPIRED -2 days)
- Freezer: Ice Cream, Frozen Vegetables, Chicken Breast, Ground Beef, Pizza, Ice - Freezer: Ice Cream (90 days), Frozen Vegetables (180 days), Chicken Breast (120 days), Ground Beef (150 days), Pizza (200 days), Ice (365 days)
### 📱 Barcode Scanner (`barcode.html`) ### 📱 Barcode Scanner (`barcode.html`)
Barcode capture interface with console logging for testing. Barcode capture interface with console logging for testing.
@@ -129,7 +142,7 @@ python -m http.server 8000
### Navigation ### Navigation
The navbar appears at the top of every page and provides links to: The navbar appears at the top of every page and provides links to:
- Homepage — Main demo page with pie chart - Homepage — Main demo page with pie chart
- Search — Advanced inventory search and filtering - Search — Advanced inventory search and filtering with expiry date support
- Barcode Scanner — Barcode capture interface (testing via console) - Barcode Scanner — Barcode capture interface (testing via console)
- Pantry, Fridge, Freezer — Individual storage location pages - Pantry, Fridge, Freezer — Individual storage location pages
@@ -139,10 +152,16 @@ The navbar appears at the top of every page and provides links to:
- Item name (optional) - Item name (optional)
- Storage location (optional, defaults to "All") - Storage location (optional, defaults to "All")
- Quantity range (optional, defaults to 0-999) - Quantity range (optional, defaults to 0-999)
- **Expiry date range (optional) — Leave blank to ignore**
3. Click "Search" or press Enter 3. Click "Search" or press Enter
4. Results display as item cards using the item component 4. Results display as item cards using the item component with expiry status badges
5. Click "Reset" to clear all filters 5. Click "Reset" to clear all filters
**Expiry Date Search Examples:**
- Find items expiring soon: Set start date to today, end date to 7 days from today
- Find expired items: Set start date to 100 days ago, end date to today
- Find fresh items: Set start date to tomorrow, end date to 90 days from today
### Using the Barcode Scanner ### Using the Barcode Scanner
1. Open the Barcode Scanner page from the navbar 1. Open the Barcode Scanner page from the navbar
2. Click in the input field (auto-focused) 2. Click in the input field (auto-focused)
@@ -166,7 +185,7 @@ The `item-component` is a reusable UI building block used throughout the app. Se
imgAlt: 'Milk', imgAlt: 'Milk',
text1: 'Milk', text1: 'Milk',
text2: 'Fridge — 1 carton', text2: 'Fridge — 1 carton',
text3: 'Expires in 5 days' text3: 'Expires Mar 15, 2026'
}); });
document.getElementById('container').appendChild(item); document.getElementById('container').appendChild(item);
@@ -179,15 +198,26 @@ The `item-component` is a reusable UI building block used throughout the app. Se
Edit `search.js` and add items to the `inventoryData` array: Edit `search.js` and add items to the `inventoryData` array:
```javascript ```javascript
export const inventoryData = [ export const inventoryData = [
{ id: 21, name: 'Coffee', location: 'Pantry', quantity: 2, unit: 'bags', img: 'https://picsum.photos/seed/coffee/200/200' }, {
id: 21,
name: 'Coffee',
location: 'Pantry',
quantity: 2,
unit: 'bags',
expiryDate: '2026-06-15',
img: 'https://picsum.photos/seed/coffee/200/200'
},
// ... more items // ... more items
]; ];
``` ```
**Date Format:** Use ISO 8601 format (YYYY-MM-DD) for expiry dates.
### Styling ### Styling
- Override styles in `main.css` for global changes - Override styles in `main.css` for global changes
- Page-specific styles are included in `<style>` tags within each HTML file - Page-specific styles are included in `<style>` tags within each HTML file
- The item component injects responsive grid CSS automatically - The item component injects responsive grid CSS automatically
- Expiry badge styles can be customized via `.expiry-fresh`, `.expiry-soon`, `.expiry-expired` classes
### Creating New Pages ### Creating New Pages
1. Create a new `.html` file following the template: 1. Create a new `.html` file following the template:
@@ -220,9 +250,11 @@ export const inventoryData = [
- Replace placeholder images with real inventory photos - Replace placeholder images with real inventory photos
- Implement backend storage (currently using static data) - Implement backend storage (currently using static data)
- Add user authentication - Add user authentication
- Integrate with real barcode/UPC database
- Consider a frontend framework (React, Vue, etc.) for scale - Consider a frontend framework (React, Vue, etc.) for scale
- Add unit/integration tests - Add unit/integration tests
- Set up CI/CD pipeline - Set up CI/CD pipeline
- Implement database for persistent storage and expiry date tracking
## Contributing ## Contributing
@@ -235,7 +267,9 @@ Contributions are welcome! Suggested improvements:
- [ ] Implement item editing/deletion on storage pages - [ ] Implement item editing/deletion on storage pages
- [ ] Add barcode/UPC lookup for real products - [ ] Add barcode/UPC lookup for real products
- [ ] Convert item-component to custom element (`<item-component>`) - [ ] Convert item-component to custom element (`<item-component>`)
- [ ] Add more detailed inventory tracking (expiration dates, locations within rooms, etc.) - [ ] Add more detailed inventory tracking (expiration dates calculations, locations within rooms, batch numbers, etc.)
- [ ] Add email/notification alerts for items expiring soon
- [ ] Implement CSV import/export for inventory
## License ## License

View File

@@ -46,13 +46,15 @@
box-shadow: 0 0 5px rgba(76, 175, 80, 0.3); box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
} }
.quantity-range { .quantity-range,
.date-range {
display: flex; display: flex;
gap: 15px; gap: 15px;
align-items: flex-end; align-items: flex-end;
} }
.quantity-range .form-group { .quantity-range .form-group,
.date-range .form-group {
flex: 1; flex: 1;
} }
@@ -102,6 +104,30 @@
color: #999; color: #999;
font-size: 18px; font-size: 18px;
} }
.item-expiry-badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
margin-top: 4px;
}
.expiry-fresh {
background-color: #e8f5e9;
color: #2e7d32;
}
.expiry-soon {
background-color: #fff3e0;
color: #e65100;
}
.expiry-expired {
background-color: #ffebee;
color: #c62828;
}
</style> </style>
</head> </head>
<body> <body>
@@ -155,6 +181,28 @@
</div> </div>
</div> </div>
<div class="form-group">
<label>Expiry Date Range:</label>
<div class="date-range">
<div class="form-group">
<label for="min-expiry-date" style="font-size: 12px;">Start Date:</label>
<input
type="date"
id="min-expiry-date"
placeholder="Start date"
>
</div>
<div class="form-group">
<label for="max-expiry-date" style="font-size: 12px;">End Date:</label>
<input
type="date"
id="max-expiry-date"
placeholder="End date"
>
</div>
</div>
</div>
<div class="search-buttons"> <div class="search-buttons">
<button type="button" class="btn btn-primary" id="search-btn">Search</button> <button type="button" class="btn btn-primary" id="search-btn">Search</button>
<button type="button" class="btn btn-secondary" id="reset-btn">Reset</button> <button type="button" class="btn btn-secondary" id="reset-btn">Reset</button>
@@ -170,7 +218,7 @@
<script src="navbar.js"></script> <script src="navbar.js"></script>
<script type="module"> <script type="module">
import { searchInventory, getLocations } from './search.js'; import { searchInventory, getLocations, formatDate, getExpiryStatus } from './search.js';
import createItemComponent from './item-component.js'; import createItemComponent from './item-component.js';
const searchForm = document.getElementById('search-form'); const searchForm = document.getElementById('search-form');
@@ -178,6 +226,8 @@
const locationSelect = document.getElementById('search-location'); const locationSelect = document.getElementById('search-location');
const minQuantityInput = document.getElementById('min-quantity'); const minQuantityInput = document.getElementById('min-quantity');
const maxQuantityInput = document.getElementById('max-quantity'); const maxQuantityInput = document.getElementById('max-quantity');
const minExpiryDateInput = document.getElementById('min-expiry-date');
const maxExpiryDateInput = document.getElementById('max-expiry-date');
const searchBtn = document.getElementById('search-btn'); const searchBtn = document.getElementById('search-btn');
const resetBtn = document.getElementById('reset-btn'); const resetBtn = document.getElementById('reset-btn');
const resultsGrid = document.getElementById('results-grid'); const resultsGrid = document.getElementById('results-grid');
@@ -192,6 +242,14 @@
locationSelect.value = 'All'; locationSelect.value = 'All';
} }
// Get expiry status badge HTML
function getExpiryBadgeHtml(expiryDate) {
const status = getExpiryStatus(expiryDate);
const badgeClass = status.status === 'Expired' ? 'expiry-expired' :
status.status === 'Soon' || status.status === 'Today' ? 'expiry-soon' : 'expiry-fresh';
return `<div class="item-expiry-badge ${badgeClass}">${formatDate(expiryDate)}</div>`;
}
// Display search results // Display search results
function displayResults(results) { function displayResults(results) {
resultsGrid.innerHTML = ''; resultsGrid.innerHTML = '';
@@ -207,9 +265,15 @@
imgAlt: item.name, imgAlt: item.name,
text1: item.name, text1: item.name,
text2: `${item.location}${item.quantity} ${item.unit}`, text2: `${item.location}${item.quantity} ${item.unit}`,
text3: `Total: ${item.quantity} ${item.unit}`, text3: `Expires: ${formatDate(item.expiryDate)}`,
editable: false editable: false
}); });
// Add expiry badge
const badge = document.createElement('div');
badge.innerHTML = getExpiryBadgeHtml(item.expiryDate);
comp.appendChild(badge.firstChild);
resultsGrid.appendChild(comp); resultsGrid.appendChild(comp);
}); });
resultsInfo.textContent = `Found ${results.length} item${results.length !== 1 ? 's' : ''}`; resultsInfo.textContent = `Found ${results.length} item${results.length !== 1 ? 's' : ''}`;
@@ -222,8 +286,16 @@
const location = locationSelect.value; const location = locationSelect.value;
const minQty = parseInt(minQuantityInput.value) || 0; const minQty = parseInt(minQuantityInput.value) || 0;
const maxQty = parseInt(maxQuantityInput.value) || Infinity; const maxQty = parseInt(maxQuantityInput.value) || Infinity;
const minExpiry = minExpiryDateInput.value;
const maxExpiry = maxExpiryDateInput.value;
const results = searchInventory(searchName, location, minQty, maxQty); // Validate date range
if (minExpiry && maxExpiry && minExpiry > maxExpiry) {
alert('Start date cannot be after end date');
return;
}
const results = searchInventory(searchName, location, minQty, maxQty, minExpiry, maxExpiry);
displayResults(results); displayResults(results);
} }
@@ -233,6 +305,8 @@
minQuantityInput.value = '0'; minQuantityInput.value = '0';
maxQuantityInput.value = '999'; maxQuantityInput.value = '999';
locationSelect.value = 'All'; locationSelect.value = 'All';
minExpiryDateInput.value = '';
maxExpiryDateInput.value = '';
resultsGrid.innerHTML = ''; resultsGrid.innerHTML = '';
resultsInfo.textContent = ''; resultsInfo.textContent = '';
} }

101
search.js
View File

@@ -1,42 +1,87 @@
// search.js - Search module with inventory data and filtering logic // search.js - Search module with inventory data and filtering logic
// Helper function to create a date string
function getDate(daysFromNow) {
const date = new Date();
date.setDate(date.getDate() + daysFromNow);
return date.toISOString().split('T')[0];
}
export const inventoryData = [ export const inventoryData = [
// Pantry items // Pantry items
{ id: 1, name: 'Pasta', location: 'Pantry', quantity: 5, unit: 'boxes', img: 'https://picsum.photos/seed/pasta/200/200' }, { id: 1, name: 'Pasta', location: 'Pantry', quantity: 5, unit: 'boxes', expiryDate: getDate(120), img: 'https://picsum.photos/seed/pasta/200/200' },
{ id: 2, name: 'Rice', location: 'Pantry', quantity: 3, unit: 'bags', img: 'https://picsum.photos/seed/rice/200/200' }, { id: 2, name: 'Rice', location: 'Pantry', quantity: 3, unit: 'bags', expiryDate: getDate(180), img: 'https://picsum.photos/seed/rice/200/200' },
{ id: 3, name: 'Cereal', location: 'Pantry', quantity: 2, unit: 'boxes', img: 'https://picsum.photos/seed/cereal/200/200' }, { id: 3, name: 'Cereal', location: 'Pantry', quantity: 2, unit: 'boxes', expiryDate: getDate(60), img: 'https://picsum.photos/seed/cereal/200/200' },
{ id: 4, name: 'Flour', location: 'Pantry', quantity: 1, unit: 'bag', img: 'https://picsum.photos/seed/flour/200/200' }, { id: 4, name: 'Flour', location: 'Pantry', quantity: 1, unit: 'bag', expiryDate: getDate(150), img: 'https://picsum.photos/seed/flour/200/200' },
{ id: 5, name: 'Sugar', location: 'Pantry', quantity: 2, unit: 'bags', img: 'https://picsum.photos/seed/sugar/200/200' }, { id: 5, name: 'Sugar', location: 'Pantry', quantity: 2, unit: 'bags', expiryDate: getDate(200), img: 'https://picsum.photos/seed/sugar/200/200' },
{ id: 6, name: 'Salt', location: 'Pantry', quantity: 1, unit: 'box', img: 'https://picsum.photos/seed/salt/200/200' }, { id: 6, name: 'Salt', location: 'Pantry', quantity: 1, unit: 'box', expiryDate: getDate(365), img: 'https://picsum.photos/seed/salt/200/200' },
{ id: 7, name: 'Olive Oil', location: 'Pantry', quantity: 2, unit: 'bottles', img: 'https://picsum.photos/seed/oil/200/200' }, { id: 7, name: 'Olive Oil', location: 'Pantry', quantity: 2, unit: 'bottles', expiryDate: getDate(90), img: 'https://picsum.photos/seed/oil/200/200' },
{ id: 8, name: 'Canned Beans', location: 'Pantry', quantity: 12, unit: 'cans', img: 'https://picsum.photos/seed/beans/200/200' }, { id: 8, name: 'Canned Beans', location: 'Pantry', quantity: 12, unit: 'cans', expiryDate: getDate(-10), img: 'https://picsum.photos/seed/beans/200/200' },
// Fridge items // Fridge items
{ id: 9, name: 'Milk', location: 'Fridge', quantity: 1, unit: 'carton', img: 'https://picsum.photos/seed/milk/200/200' }, { id: 9, name: 'Milk', location: 'Fridge', quantity: 1, unit: 'carton', expiryDate: getDate(5), img: 'https://picsum.photos/seed/milk/200/200' },
{ id: 10, name: 'Cheese', location: 'Fridge', quantity: 2, unit: 'blocks', img: 'https://picsum.photos/seed/cheese/200/200' }, { id: 10, name: 'Cheese', location: 'Fridge', quantity: 2, unit: 'blocks', expiryDate: getDate(30), img: 'https://picsum.photos/seed/cheese/200/200' },
{ id: 11, name: 'Greek Yogurt', location: 'Fridge', quantity: 3, unit: 'containers', img: 'https://picsum.photos/seed/yogurt/200/200' }, { id: 11, name: 'Greek Yogurt', location: 'Fridge', quantity: 3, unit: 'containers', expiryDate: getDate(7), img: 'https://picsum.photos/seed/yogurt/200/200' },
{ id: 12, name: 'Eggs', location: 'Fridge', quantity: 24, unit: 'eggs', img: 'https://picsum.photos/seed/eggs/200/200' }, { id: 12, name: 'Eggs', location: 'Fridge', quantity: 24, unit: 'eggs', expiryDate: getDate(21), img: 'https://picsum.photos/seed/eggs/200/200' },
{ id: 13, name: 'Butter', location: 'Fridge', quantity: 1, unit: 'pack', img: 'https://picsum.photos/seed/butter/200/200' }, { id: 13, name: 'Butter', location: 'Fridge', quantity: 1, unit: 'pack', expiryDate: getDate(45), img: 'https://picsum.photos/seed/butter/200/200' },
{ id: 14, name: 'Chicken Salad', location: 'Fridge', quantity: 2, unit: 'containers', img: 'https://picsum.photos/seed/salad/200/200' }, { id: 14, name: 'Chicken Salad', location: 'Fridge', quantity: 2, unit: 'containers', expiryDate: getDate(-2), img: 'https://picsum.photos/seed/salad/200/200' },
// Freezer items // Freezer items
{ id: 15, name: 'Ice Cream', location: 'Freezer', quantity: 1, unit: 'tub', img: 'https://picsum.photos/seed/icecream/200/200' }, { id: 15, name: 'Ice Cream', location: 'Freezer', quantity: 1, unit: 'tub', expiryDate: getDate(90), img: 'https://picsum.photos/seed/icecream/200/200' },
{ id: 16, name: 'Frozen Vegetables', location: 'Freezer', quantity: 5, unit: 'bags', img: 'https://picsum.photos/seed/veggies/200/200' }, { id: 16, name: 'Frozen Vegetables', location: 'Freezer', quantity: 5, unit: 'bags', expiryDate: getDate(180), img: 'https://picsum.photos/seed/veggies/200/200' },
{ id: 17, name: 'Chicken Breast', location: 'Freezer', quantity: 4, unit: 'packages', img: 'https://picsum.photos/seed/chicken/200/200' }, { id: 17, name: 'Chicken Breast', location: 'Freezer', quantity: 4, unit: 'packages', expiryDate: getDate(120), img: 'https://picsum.photos/seed/chicken/200/200' },
{ id: 18, name: 'Ground Beef', location: 'Freezer', quantity: 3, unit: 'packages', img: 'https://picsum.photos/seed/beef/200/200' }, { id: 18, name: 'Ground Beef', location: 'Freezer', quantity: 3, unit: 'packages', expiryDate: getDate(150), img: 'https://picsum.photos/seed/beef/200/200' },
{ id: 19, name: 'Pizza', location: 'Freezer', quantity: 2, unit: 'boxes', img: 'https://picsum.photos/seed/pizza/200/200' }, { id: 19, name: 'Pizza', location: 'Freezer', quantity: 2, unit: 'boxes', expiryDate: getDate(200), img: 'https://picsum.photos/seed/pizza/200/200' },
{ id: 20, name: 'Ice', location: 'Freezer', quantity: 1, unit: 'bag', img: 'https://picsum.photos/seed/ice/200/200' }, { id: 20, name: 'Ice', location: 'Freezer', quantity: 1, unit: 'bag', expiryDate: getDate(365), img: 'https://picsum.photos/seed/ice/200/200' },
]; ];
/**
* Format a date string (YYYY-MM-DD) to readable format (Mon DD, YYYY)
* @param {string} dateStr - ISO date string
* @returns {string} Formatted date
*/
export function formatDate(dateStr) {
if (!dateStr) return '';
const date = new Date(dateStr + 'T00:00:00');
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
/**
* Get expiry status of an item
* @param {string} expiryDate - ISO date string
* @returns {Object} Status object with text and color
*/
export function getExpiryStatus(expiryDate) {
if (!expiryDate) return { status: 'Unknown', color: '#999', text: '' };
const today = new Date();
today.setHours(0, 0, 0, 0);
const expiry = new Date(expiryDate + 'T00:00:00');
const daysUntilExpiry = Math.floor((expiry - today) / (1000 * 60 * 60 * 24));
if (daysUntilExpiry < 0) {
return { status: 'Expired', color: '#f44336', days: daysUntilExpiry, text: `Expired ${Math.abs(daysUntilExpiry)} days ago` };
} else if (daysUntilExpiry === 0) {
return { status: 'Today', color: '#ff9800', days: 0, text: 'Expires today' };
} else if (daysUntilExpiry <= 7) {
return { status: 'Soon', color: '#ff9800', days: daysUntilExpiry, text: `Expires in ${daysUntilExpiry} days` };
} else {
return { status: 'Fresh', color: '#4CAF50', days: daysUntilExpiry, text: `Expires in ${daysUntilExpiry} days` };
}
}
/** /**
* Search and filter inventory items * Search and filter inventory items
* @param {string} searchName - Search term for item name (case insensitive) * @param {string} searchName - Search term for item name (case insensitive)
* @param {string} selectedLocation - Filter by location ('All', 'Pantry', 'Fridge', 'Freezer') * @param {string} selectedLocation - Filter by location ('All', 'Pantry', 'Fridge', 'Freezer')
* @param {number} minQuantity - Minimum quantity filter * @param {number} minQuantity - Minimum quantity filter
* @param {number} maxQuantity - Maximum quantity filter * @param {number} maxQuantity - Maximum quantity filter
* @param {string} minExpiryDate - Minimum expiry date (YYYY-MM-DD format)
* @param {string} maxExpiryDate - Maximum expiry date (YYYY-MM-DD format)
* @returns {Array} Filtered inventory items * @returns {Array} Filtered inventory items
*/ */
export function searchInventory(searchName = '', selectedLocation = 'All', minQuantity = 0, maxQuantity = Infinity) { export function searchInventory(searchName = '', selectedLocation = 'All', minQuantity = 0, maxQuantity = Infinity, minExpiryDate = '', maxExpiryDate = '') {
return inventoryData.filter(item => { return inventoryData.filter(item => {
// Filter by name // Filter by name
const nameMatch = item.name.toLowerCase().includes(searchName.toLowerCase()); const nameMatch = item.name.toLowerCase().includes(searchName.toLowerCase());
@@ -47,7 +92,19 @@ export function searchInventory(searchName = '', selectedLocation = 'All', minQu
// Filter by quantity range // Filter by quantity range
const quantityMatch = item.quantity >= minQuantity && item.quantity <= maxQuantity; const quantityMatch = item.quantity >= minQuantity && item.quantity <= maxQuantity;
return nameMatch && locationMatch && quantityMatch; // Filter by expiry date range
let expiryMatch = true;
if (minExpiryDate || maxExpiryDate) {
const itemExpiry = item.expiryDate;
if (minExpiryDate && itemExpiry < minExpiryDate) {
expiryMatch = false;
}
if (maxExpiryDate && itemExpiry > maxExpiryDate) {
expiryMatch = false;
}
}
return nameMatch && locationMatch && quantityMatch && expiryMatch;
}); });
} }