Added expiry date to the search page
This commit is contained in:
60
README.md
60
README.md
@@ -8,7 +8,7 @@ Webpage Playground is a lightweight, responsive web application for managing and
|
||||
|
||||
- **Dynamic Navigation** — Easy page switching with a responsive navbar
|
||||
- **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)
|
||||
- **Data Visualization** — Pie chart showing inventory distribution
|
||||
- **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
|
||||
- `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
|
||||
- `pantry.html` — Pantry 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
|
||||
- `main.css` — Global styles and responsive design
|
||||
- `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
|
||||
- `piechart.js` — Inventory distribution pie chart visualization
|
||||
|
||||
@@ -55,20 +55,33 @@ Advanced inventory search and filtering interface.
|
||||
- Search by item name (case-insensitive)
|
||||
- Filter by storage location (All, Pantry, Fridge, Freezer)
|
||||
- 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
|
||||
- Visual expiry status indicators (Fresh, Expiring Soon, Expired)
|
||||
- Reset button to clear all filters
|
||||
- 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:**
|
||||
```
|
||||
Search for "milk" in the Fridge with quantity >= 1
|
||||
Results displayed using item-component for consistency
|
||||
Search for items expiring between March 15 and April 15
|
||||
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):**
|
||||
- Pantry: Pasta, Rice, Cereal, Flour, Sugar, Salt, Olive Oil, Canned Beans
|
||||
- Fridge: Milk, Cheese, Greek Yogurt, Eggs, Butter, Chicken Salad
|
||||
- Freezer: Ice Cream, Frozen Vegetables, Chicken Breast, Ground Beef, Pizza, Ice
|
||||
- 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 (5 days), Cheese (30 days), Greek Yogurt (7 days), Eggs (21 days), Butter (45 days), Chicken Salad (EXPIRED -2 days)
|
||||
- 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 capture interface with console logging for testing.
|
||||
@@ -129,7 +142,7 @@ python -m http.server 8000
|
||||
### Navigation
|
||||
The navbar appears at the top of every page and provides links to:
|
||||
- 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)
|
||||
- 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)
|
||||
- Storage location (optional, defaults to "All")
|
||||
- Quantity range (optional, defaults to 0-999)
|
||||
- **Expiry date range (optional) — Leave blank to ignore**
|
||||
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
|
||||
|
||||
**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
|
||||
1. Open the Barcode Scanner page from the navbar
|
||||
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',
|
||||
text1: 'Milk',
|
||||
text2: 'Fridge — 1 carton',
|
||||
text3: 'Expires in 5 days'
|
||||
text3: 'Expires Mar 15, 2026'
|
||||
});
|
||||
|
||||
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:
|
||||
```javascript
|
||||
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
|
||||
];
|
||||
```
|
||||
|
||||
**Date Format:** Use ISO 8601 format (YYYY-MM-DD) for expiry dates.
|
||||
|
||||
### Styling
|
||||
- Override styles in `main.css` for global changes
|
||||
- Page-specific styles are included in `<style>` tags within each HTML file
|
||||
- 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
|
||||
1. Create a new `.html` file following the template:
|
||||
@@ -220,9 +250,11 @@ export const inventoryData = [
|
||||
- Replace placeholder images with real inventory photos
|
||||
- Implement backend storage (currently using static data)
|
||||
- Add user authentication
|
||||
- Integrate with real barcode/UPC database
|
||||
- Consider a frontend framework (React, Vue, etc.) for scale
|
||||
- Add unit/integration tests
|
||||
- Set up CI/CD pipeline
|
||||
- Implement database for persistent storage and expiry date tracking
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -235,7 +267,9 @@ Contributions are welcome! Suggested improvements:
|
||||
- [ ] Implement item editing/deletion on storage pages
|
||||
- [ ] Add barcode/UPC lookup for real products
|
||||
- [ ] 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
|
||||
|
||||
|
||||
84
search.html
84
search.html
@@ -46,13 +46,15 @@
|
||||
box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.quantity-range {
|
||||
.quantity-range,
|
||||
.date-range {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.quantity-range .form-group {
|
||||
.quantity-range .form-group,
|
||||
.date-range .form-group {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -102,6 +104,30 @@
|
||||
color: #999;
|
||||
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>
|
||||
</head>
|
||||
<body>
|
||||
@@ -155,6 +181,28 @@
|
||||
</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">
|
||||
<button type="button" class="btn btn-primary" id="search-btn">Search</button>
|
||||
<button type="button" class="btn btn-secondary" id="reset-btn">Reset</button>
|
||||
@@ -170,7 +218,7 @@
|
||||
|
||||
<script src="navbar.js"></script>
|
||||
<script type="module">
|
||||
import { searchInventory, getLocations } from './search.js';
|
||||
import { searchInventory, getLocations, formatDate, getExpiryStatus } from './search.js';
|
||||
import createItemComponent from './item-component.js';
|
||||
|
||||
const searchForm = document.getElementById('search-form');
|
||||
@@ -178,6 +226,8 @@
|
||||
const locationSelect = document.getElementById('search-location');
|
||||
const minQuantityInput = document.getElementById('min-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 resetBtn = document.getElementById('reset-btn');
|
||||
const resultsGrid = document.getElementById('results-grid');
|
||||
@@ -192,6 +242,14 @@
|
||||
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
|
||||
function displayResults(results) {
|
||||
resultsGrid.innerHTML = '';
|
||||
@@ -207,9 +265,15 @@
|
||||
imgAlt: item.name,
|
||||
text1: item.name,
|
||||
text2: `${item.location} — ${item.quantity} ${item.unit}`,
|
||||
text3: `Total: ${item.quantity} ${item.unit}`,
|
||||
text3: `Expires: ${formatDate(item.expiryDate)}`,
|
||||
editable: false
|
||||
});
|
||||
|
||||
// Add expiry badge
|
||||
const badge = document.createElement('div');
|
||||
badge.innerHTML = getExpiryBadgeHtml(item.expiryDate);
|
||||
comp.appendChild(badge.firstChild);
|
||||
|
||||
resultsGrid.appendChild(comp);
|
||||
});
|
||||
resultsInfo.textContent = `Found ${results.length} item${results.length !== 1 ? 's' : ''}`;
|
||||
@@ -222,8 +286,16 @@
|
||||
const location = locationSelect.value;
|
||||
const minQty = parseInt(minQuantityInput.value) || 0;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -233,6 +305,8 @@
|
||||
minQuantityInput.value = '0';
|
||||
maxQuantityInput.value = '999';
|
||||
locationSelect.value = 'All';
|
||||
minExpiryDateInput.value = '';
|
||||
maxExpiryDateInput.value = '';
|
||||
resultsGrid.innerHTML = '';
|
||||
resultsInfo.textContent = '';
|
||||
}
|
||||
|
||||
101
search.js
101
search.js
@@ -1,42 +1,87 @@
|
||||
// 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 = [
|
||||
// Pantry items
|
||||
{ id: 1, name: 'Pasta', location: 'Pantry', quantity: 5, unit: 'boxes', 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: 3, name: 'Cereal', location: 'Pantry', quantity: 2, unit: 'boxes', 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: 5, name: 'Sugar', location: 'Pantry', quantity: 2, unit: 'bags', 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: 7, name: 'Olive Oil', location: 'Pantry', quantity: 2, unit: 'bottles', 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: 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', expiryDate: getDate(180), img: 'https://picsum.photos/seed/rice/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', expiryDate: getDate(150), img: 'https://picsum.photos/seed/flour/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', expiryDate: getDate(365), img: 'https://picsum.photos/seed/salt/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', expiryDate: getDate(-10), img: 'https://picsum.photos/seed/beans/200/200' },
|
||||
|
||||
// Fridge items
|
||||
{ id: 9, name: 'Milk', location: 'Fridge', quantity: 1, unit: 'carton', 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: 11, name: 'Greek Yogurt', location: 'Fridge', quantity: 3, unit: 'containers', 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: 13, name: 'Butter', location: 'Fridge', quantity: 1, unit: 'pack', 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: 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', expiryDate: getDate(30), img: 'https://picsum.photos/seed/cheese/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', expiryDate: getDate(21), img: 'https://picsum.photos/seed/eggs/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', expiryDate: getDate(-2), img: 'https://picsum.photos/seed/salad/200/200' },
|
||||
|
||||
// Freezer items
|
||||
{ id: 15, name: 'Ice Cream', location: 'Freezer', quantity: 1, unit: 'tub', 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: 17, name: 'Chicken Breast', location: 'Freezer', quantity: 4, unit: 'packages', 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: 19, name: 'Pizza', location: 'Freezer', quantity: 2, unit: 'boxes', 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: 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', expiryDate: getDate(180), img: 'https://picsum.photos/seed/veggies/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', expiryDate: getDate(150), img: 'https://picsum.photos/seed/beef/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', 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
|
||||
* @param {string} searchName - Search term for item name (case insensitive)
|
||||
* @param {string} selectedLocation - Filter by location ('All', 'Pantry', 'Fridge', 'Freezer')
|
||||
* @param {number} minQuantity - Minimum 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
|
||||
*/
|
||||
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 => {
|
||||
// Filter by name
|
||||
const nameMatch = item.name.toLowerCase().includes(searchName.toLowerCase());
|
||||
@@ -47,7 +92,19 @@ export function searchInventory(searchName = '', selectedLocation = 'All', minQu
|
||||
// Filter by quantity range
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user