diff --git a/00-backend/datasource/database.sqlite b/00-backend/datasource/database.sqlite
index 6049a25..3ed449b 100644
Binary files a/00-backend/datasource/database.sqlite and b/00-backend/datasource/database.sqlite differ
diff --git a/01-frontend/public/locales/de/translation.json b/01-frontend/public/locales/de/translation.json
index d0d83b1..1ec3081 100644
--- a/01-frontend/public/locales/de/translation.json
+++ b/01-frontend/public/locales/de/translation.json
@@ -102,6 +102,11 @@
"surname": "Nachname",
"language": "Sprache",
"password": "Passwort",
- "adminize": "Admin ernennen",
- "unadminize": "Admin abernennen",
+ "actualPrice": "Endpreis in €",
+ "stock": "Bestand",
+ "price100": "Preis in ct",
+ "discount100": "Rabatt in %",
+ "deleteProduct": "Produkt löschen",
+ "description": "Beschreibung",
+ "images": "Bilder"
}
diff --git a/01-frontend/public/locales/en/translation.json b/01-frontend/public/locales/en/translation.json
index 98eb829..baac535 100644
--- a/01-frontend/public/locales/en/translation.json
+++ b/01-frontend/public/locales/en/translation.json
@@ -102,6 +102,11 @@
"surname": "Surname",
"language": "Language",
"password": "Password",
- "adminize": "Make Admin",
- "unadminize": "Revoke Admin"
+ "actualPrice": "Price in €",
+ "stock": "Stock",
+ "price100": "Price in ct",
+ "discount100": "Discount in %",
+ "deleteProduct": "Delete Product",
+ "description": "Description",
+ "images": "Images"
}
\ No newline at end of file
diff --git a/01-frontend/src/components/Item.tsx b/01-frontend/src/components/Item.tsx
index 8c1ddd9..81895ca 100644
--- a/01-frontend/src/components/Item.tsx
+++ b/01-frontend/src/components/Item.tsx
@@ -5,6 +5,7 @@ type Item = {
description: string;
price100: number;
stock: number;
+ stockExpected: number;
category: string;
rating: number;
discount100: number;
diff --git a/01-frontend/src/helper/adminpanel/ItemsInfo.tsx b/01-frontend/src/helper/adminpanel/ItemsInfo.tsx
index c233e0d..ed5ae6c 100644
--- a/01-frontend/src/helper/adminpanel/ItemsInfo.tsx
+++ b/01-frontend/src/helper/adminpanel/ItemsInfo.tsx
@@ -1,27 +1,199 @@
-import { Typography, Box, useTheme } from "@mui/material";
+import DeleteIcon from "@mui/icons-material/Delete";
+import EditIcon from "@mui/icons-material/Edit";
+import {Box, Button, IconButton, Toolbar, useTheme} from "@mui/material";
+import Item from "../../components/Item";
+import {useTranslation} from "react-i18next";
+import {DataGrid, GridColDef, GridRowId, GridRowSelectionModel} from "@mui/x-data-grid";
+import {useEffect, useState} from "react";
+import {Gauge} from "@mui/x-charts";
-export default function ItemInfo() {
+export default function ItemsInfo() {
const theme = useTheme();
+ const {t} = useTranslation();
+
+ //TODO: add colors to gauges for rating adn stock
+ function mapValueToColor(minVal: number, maxVal: number, actualVal: number): string {
+ const clamped = Math.min(Math.max(actualVal, minVal), maxVal);
+
+ // Calculate interpolation ratio (0-1)
+ const ratio = maxVal !== minVal
+ ? (clamped - minVal) / (maxVal - minVal)
+ : 0;
+
+ const red = Math.floor(255 * (1 - ratio));
+ const green = Math.floor(255 * ratio)
+
+ const redHex = red.toString(16).padStart(2, '0').toUpperCase();
+ const greenHex = green.toString(16).padStart(2, '0').toUpperCase();
+
+ return `#${redHex}${greenHex}00`; // Blue is always 00
+ }
+
+ function handleIconEdit(item: Item) {
+ //TODO: implement
+ console.log("IconEdit", item);
+ }
+
+ const _rows: Item[] = [
+ {
+ id: "1",
+ uuid: "uuid123",
+ name: "Item",
+ description: "Super duper geil wichtiger text ",
+ price100: 1000,
+ stock: 100,
+ stockExpected: 1200,
+ category: "garden",
+ rating: 5,
+ discount100: 21,
+ },
+ {
+ id: "2",
+ uuid: "uuid12312412",
+ name: "Schlauch",
+ description: "Schlauchiger Schlauch für Schlauchige Angelegenheiten",
+ price100: 10,
+ stock: 50,
+ stockExpected: 100,
+ category: "technicalComponents",
+ rating: 10,
+ discount100: 21,
+ },
+ ]
+
+ //TODO: get per REST
+ const [rows, setRows] = useState- (_rows);
+ const [selectedRows, setSelectedRows] = useState>(new Set());
+
+ const handleSelectionChange = (newSelection: GridRowSelectionModel) => {
+ setSelectedRows(newSelection.ids);
+ };
+
+ const handleDeleteSelected = async () => {
+ selectedRows.forEach((row) => {
+ //TODO: send delete command, or send deleteall
+ console.log(row);
+ })
+
+ setRows(rows.filter((row) => !selectedRows.has(row.id)));
+ };
+
+ const columns: GridColDef<(typeof rows)[number]>[] = [
+ {field: 'id', headerName: 'ID', width: 60},
+ {
+ field: 'uuid',
+ headerName: "UUID",
+ type: "string",
+ width: 120,
+ editable: true
+ },
+ {
+ field: 'name',
+ headerName: t('name'),
+ width: 150,
+ editable: true,
+ },
+ {
+ field: 'category',
+ headerName: t('category'),
+ width: 150,
+ editable: true,
+ },
+ {
+ field: 'description',
+ headerName: t('description'),
+ width: 150,
+ editable: true,
+ },
+ {
+ field: 'price100',
+ headerName: t('price100'),
+ width: 100,
+ editable: true,
+ type: 'number'
+ },
+ {
+ field: 'discount100',
+ headerName: t('discount100'),
+ width: 120,
+ editable: true,
+ type: 'number'
+ },
+ {
+ field: 'stock',
+ headerName: t('stock'),
+ width: 100,
+ editable: true,
+ type: 'number',
+ renderCell: params =>
+ },
+ {
+ field: 'rating',
+ headerName: t('rating'),
+ width: 100,
+ editable: true,
+ type: 'number',
+ renderCell: params =>
+ },
+ { //edit billing information button
+ field: "actualPrice",
+ headerName: t('actualPrice'),
+ width: 90,
+ editable: false,
+ valueGetter: (_, row) => (row.price100 / 100 * ((100-row.discount100)/100)).toFixed(2)
+ },
+ {
+ field: 'images',
+ headerName: t('images'),
+ width: 90,
+ editable: false,
+ renderCell: params => handleIconEdit(params.row)}> ,
+ }
+ ];
+
+ useEffect(() => {
+ console.log(mapValueToColor(0,10,2))
+ console.log(mapValueToColor(0,10,7))
+ }, []);
return (
-
- 🚧 Under construction...
-
+ (
+
+
+
+ )}}
+ showToolbar
+ processRowUpdate={(updatedRow, originalRow) => {
+ setRows(rows.map(row => row.id === updatedRow.id ? updatedRow : row));
+ //TODO: make REST callback
+ return updatedRow;
+ }}
+ />
);
}