- {product.name} {product.organic ? '🌱' : ''}
+
+ {Object.entries(
+ hoveredEvent.products.reduce((groups, product) => {
+ const category = product.category?.name || 'Unknown';
+ if (!groups[category]) {
+ groups[category] = [];
+ }
+ groups[category].push(product);
+ return groups;
+ }, {} as Record
)
+ )
+ .sort(([a], [b]) => a.localeCompare(b))
+ .map(([category, categoryProducts]) => (
+
+
+ {category}
+
+
+ {categoryProducts.map((product, index) => (
+
+ {product.name} {product.organic ? '🌱' : ''} {product.weight ? `${product.weight}${product.weight_unit}` : product.weight_unit}
+
+ {product.amount} × ${product.price.toFixed(2)} = ${(product.amount * product.price).toFixed(2)}
+ {product.discount && 🏷️}
+
-
- {product.category?.name || 'Unknown category'}
-
- {product.brand && (
-
- Brand: {product.brand.name}
-
- )}
-
-
-
- ${product.price.toFixed(2)}
-
-
- Qty: {product.amount}
-
-
- ${(product.amount * product.price).toFixed(2)}
-
-
+ ))}
))}
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
index da76c8e..81a3caf 100644
--- a/frontend/src/types/index.ts
+++ b/frontend/src/types/index.ts
@@ -62,6 +62,7 @@ export interface ProductInEvent {
product_id: number;
amount: number;
price: number;
+ discount: boolean;
}
export interface ProductWithEventData {
@@ -74,6 +75,7 @@ export interface ProductWithEventData {
weight_unit: string;
amount: number;
price: number;
+ discount: boolean;
}
export interface ShoppingEvent {
diff --git a/resources/brands.csv b/resources/brands.csv
new file mode 100644
index 0000000..1e801f9
--- /dev/null
+++ b/resources/brands.csv
@@ -0,0 +1,3 @@
+name
+denree
+Rewe Bio
\ No newline at end of file
diff --git a/resources/categories.csv b/resources/categories.csv
new file mode 100644
index 0000000..fad1dcb
--- /dev/null
+++ b/resources/categories.csv
@@ -0,0 +1,6 @@
+name
+Obst
+Gemüse
+Konserven
+Tiefkühl
+Molkereiprodukte
\ No newline at end of file
diff --git a/resources/database_schema.drawio b/resources/database_schema.drawio
new file mode 100644
index 0000000..24fd330
--- /dev/null
+++ b/resources/database_schema.drawio
@@ -0,0 +1,696 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/products.csv b/resources/products.csv
new file mode 100644
index 0000000..fd4ea4a
--- /dev/null
+++ b/resources/products.csv
@@ -0,0 +1,5 @@
+name,category_name,organic,brand_name,weight,weight_unit
+"Milch 3,5%",Molkereiprodukte,true,denree,1,l
+"Milch 3,5%",Molkereiprodukte,true,Rewe Bio,1,l
+"Frischkäse Natur",Molkereiprodukte,true,Rewe Bio,175,g
+"Frischkäse Kräuter",Molkereiprodukte,true,Rewe Bio,175,g
\ No newline at end of file