brands-in-shops feature implemented
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Shop, Product, ShoppingEventCreate, ProductInEvent, ShoppingEvent } from '../types';
|
||||
import { shopApi, productApi, shoppingEventApi } from '../services/api';
|
||||
import { Shop, Product, ShoppingEventCreate, ProductInEvent, ShoppingEvent, BrandInShop } from '../types';
|
||||
import { shopApi, productApi, shoppingEventApi, brandInShopApi } from '../services/api';
|
||||
|
||||
interface AddShoppingEventModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -17,6 +17,7 @@ const AddShoppingEventModal: React.FC<AddShoppingEventModalProps> = ({
|
||||
}) => {
|
||||
const [shops, setShops] = useState<Shop[]>([]);
|
||||
const [products, setProducts] = useState<Product[]>([]);
|
||||
const [shopBrands, setShopBrands] = useState<BrandInShop[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [message, setMessage] = useState('');
|
||||
|
||||
@@ -160,6 +161,30 @@ const AddShoppingEventModal: React.FC<AddShoppingEventModalProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const fetchShopBrands = async (shopId: number) => {
|
||||
if (shopId === 0) {
|
||||
setShopBrands([]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await brandInShopApi.getByShop(shopId);
|
||||
setShopBrands(response.data);
|
||||
} catch (error) {
|
||||
console.error('Error fetching shop brands:', error);
|
||||
setShopBrands([]);
|
||||
}
|
||||
};
|
||||
|
||||
// Effect to load shop brands when shop selection changes
|
||||
useEffect(() => {
|
||||
if (formData.shop_id > 0) {
|
||||
fetchShopBrands(formData.shop_id);
|
||||
} else {
|
||||
setShopBrands([]);
|
||||
}
|
||||
}, [formData.shop_id]);
|
||||
|
||||
const addProductToEvent = () => {
|
||||
if (newProductItem.product_id > 0 && newProductItem.amount > 0 && newProductItem.price >= 0) {
|
||||
setSelectedProducts([...selectedProducts, { ...newProductItem }]);
|
||||
@@ -224,6 +249,23 @@ const AddShoppingEventModal: React.FC<AddShoppingEventModalProps> = ({
|
||||
return `${product.name}${organicEmoji} ${weightInfo}`;
|
||||
};
|
||||
|
||||
// Filter products based on selected shop's brands
|
||||
const getFilteredProducts = () => {
|
||||
// If no shop is selected or shop has no brands, show all products
|
||||
if (formData.shop_id === 0 || shopBrands.length === 0) {
|
||||
return products;
|
||||
}
|
||||
|
||||
// Get brand IDs available in the selected shop
|
||||
const availableBrandIds = shopBrands.map(sb => sb.brand_id);
|
||||
|
||||
// Filter products to only show those with brands available in the shop
|
||||
// Also include products without brands (brand_id is null/undefined)
|
||||
return products.filter(product =>
|
||||
!product.brand_id || availableBrandIds.includes(product.brand_id)
|
||||
);
|
||||
};
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
@@ -306,7 +348,7 @@ const AddShoppingEventModal: React.FC<AddShoppingEventModalProps> = ({
|
||||
>
|
||||
<option value={0}>Select a product</option>
|
||||
{Object.entries(
|
||||
products.reduce((groups, product) => {
|
||||
getFilteredProducts().reduce((groups, product) => {
|
||||
const category = product.grocery.category.name;
|
||||
if (!groups[category]) {
|
||||
groups[category] = [];
|
||||
@@ -329,6 +371,14 @@ const AddShoppingEventModal: React.FC<AddShoppingEventModalProps> = ({
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
{formData.shop_id > 0 && (
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
{shopBrands.length === 0
|
||||
? `Showing all ${products.length} products (no brand restrictions for this shop)`
|
||||
: `Showing ${getFilteredProducts().length} of ${products.length} products (filtered by shop's available brands)`
|
||||
}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-24">
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
||||
|
||||
Reference in New Issue
Block a user