diff --git a/00-backend/datasource/database.sqlite b/00-backend/datasource/database.sqlite index 7190194..b3079e3 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 6ab4562..02e940a 100644 --- a/01-frontend/public/locales/de/translation.json +++ b/01-frontend/public/locales/de/translation.json @@ -149,5 +149,8 @@ "imageUploadedSuccessfully": "Bild hochgeladen", "uploading": "Lädt hoch...", "upload": "Hochladen", - "imageUploadNoticeFs": "Die Auflösung der Farming Station beträgt 720 x 960 px" + "imageUploadNoticeFs": "Die Auflösung der Farming Station beträgt 720 x 960 px", + "itemCreatedSuccessfully": "Artikel erfolgreich erstellt", + "createNewItem": "Neuen Artikel erstellen", + "stockExpected": "Erwarteter Bestand" } \ No newline at end of file diff --git a/01-frontend/public/locales/en/translation.json b/01-frontend/public/locales/en/translation.json index ac747e6..512a764 100644 --- a/01-frontend/public/locales/en/translation.json +++ b/01-frontend/public/locales/en/translation.json @@ -149,5 +149,8 @@ "imageUploadedSuccessfully": "Uploaded Image Successfully", "uploading": "Uploading...", "upload": "Upload", - "imageUploadNoticeFs": "The Resolution of the Farming Station is 720 x 960 px" + "imageUploadNoticeFs": "The Resolution of the Farming Station is 720 x 960 px", + "itemCreatedSuccessfully": "Item created successfully", + "createNewItem": "Create New Item", + "stockExpected": "Expected Stock" } \ No newline at end of file diff --git a/01-frontend/src/helper/adminpanel/ItemsInfo.tsx b/01-frontend/src/helper/adminpanel/ItemsInfo.tsx index 881f567..953f457 100644 --- a/01-frontend/src/helper/adminpanel/ItemsInfo.tsx +++ b/01-frontend/src/helper/adminpanel/ItemsInfo.tsx @@ -1,25 +1,27 @@ import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; -import {Box, Button, IconButton, Toolbar, useTheme} from "@mui/material"; +import { Box, Button, IconButton, Toolbar, useTheme } from "@mui/material"; +import { Gauge, gaugeClasses } from "@mui/x-charts"; +import { DataGrid, GridColDef, GridRowId, GridRowSelectionModel } from "@mui/x-data-grid"; +import { useQuery } from "@tanstack/react-query"; +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; 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, gaugeClasses} from "@mui/x-charts"; -import {useAccount} from "../AccountProvider.tsx"; -import {useQuery} from "@tanstack/react-query"; -import {fetchItems} from "../query/Queries.tsx"; import { mapValueToColor } from "../../util/ColorUtil.tsx"; +import { useAccount } from "../AccountProvider.tsx"; +import { fetchItems } from "../query/Queries.tsx"; import ItemImageDialog from "./ItemImageDialog.tsx"; +import NewItemDialog from "./NewItemDialog.tsx"; export default function ItemsInfo() { const theme = useTheme(); - const {t} = useTranslation(); + const { t } = useTranslation(); const [rows, setRows] = useState([]); const [selectedRows, setSelectedRows] = useState>(new Set()); const [editImageDialog, setEditImageDialog] = useState(false); + const [newItemDialog, setNewItemDialog] = useState(false); const [selectedItem, setSelectedItem] = useState(null); const [isFarmStationImage, setIsFarmStationImage] = useState(false); @@ -41,10 +43,10 @@ export default function ItemsInfo() { function handleAddItem() { - //TODO: flsp + setNewItemDialog(true); } - const {user: loginData} = useAccount(); + const { user: loginData } = useAccount(); const { data } = useQuery({ queryKey: ["fetchItems", loginData], @@ -73,7 +75,7 @@ export default function ItemsInfo() { }; const columns: GridColDef<(typeof rows)[number]>[] = [ - {field: 'id', headerName: 'ID', width: 60}, + { field: 'id', headerName: 'ID', width: 60 }, { field: 'uuid', headerName: t('uuid'), @@ -123,7 +125,7 @@ export default function ItemsInfo() { type: 'number', renderCell: params => {return mapValueToColor(0, params.row.stockExpected, params.row.stock)}, + fill: () => { return mapValueToColor(0, params.row.stockExpected, params.row.stock) }, }, }} text={() => `${params.row.stock}`} /> }, @@ -135,7 +137,7 @@ export default function ItemsInfo() { type: 'number', renderCell: params => {return mapValueToColor(0, 10, params.row.rating)}, + fill: () => { return mapValueToColor(0, 10, params.row.rating) }, }, }} text={() => `${params.row.rating.toFixed(2)}`} /> }, @@ -144,21 +146,21 @@ export default function ItemsInfo() { headerName: t('actualPrice'), width: 90, editable: false, - valueGetter: (_, row) => (row.price100 / 100 * ((100-row.discount100)/100)).toFixed(2) + valueGetter: (_, row) => (row.price100 / 100 * ((100 - row.discount100) / 100)).toFixed(2) }, { field: 'images', headerName: t('images'), width: 90, editable: false, - renderCell: params => handleImageEdit(params.row)}> , + renderCell: params => handleImageEdit(params.row)}> , }, { field: 'farmImage', headerName: t('fsImage'), width: 90, editable: false, - renderCell: params => handleFarmImageEdit(params.row)}> , + renderCell: params => handleFarmImageEdit(params.row)}> , } ]; @@ -177,12 +179,13 @@ export default function ItemsInfo() { checkboxSelection disableRowSelectionOnClick onRowSelectionModelChange={handleSelectionChange} - slots={{ toolbar: () => ( + slots={{ + toolbar: () => ( - )}} + ) + }} showToolbar processRowUpdate={(updatedRow) => { setRows(rows.map(row => row.id === updatedRow.id ? updatedRow : row)); @@ -224,6 +227,11 @@ export default function ItemsInfo() { isFarmStationImage={isFarmStationImage} /> )} + + setNewItemDialog(false)} + /> ); } \ No newline at end of file diff --git a/01-frontend/src/helper/adminpanel/NewItemDialog.tsx b/01-frontend/src/helper/adminpanel/NewItemDialog.tsx new file mode 100644 index 0000000..ea2413a --- /dev/null +++ b/01-frontend/src/helper/adminpanel/NewItemDialog.tsx @@ -0,0 +1,157 @@ + +import CloseIcon from '@mui/icons-material/Close'; +import CloudUploadIcon from '@mui/icons-material/CloudUpload'; +import { + Alert, + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + IconButton, + TextField, + Typography +} from '@mui/material'; +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Item } from '../../components/Item'; + +interface NewItemDialogProps { + open: boolean; + onClose: () => void; +} + +export default function NewItemDialog({ open, onClose }: NewItemDialogProps) { + const { t } = useTranslation(); + const [item, setItem] = useState({ + id: 0, + uuid: "", + name: "", + description: "", + price100: 0, + stock: 0, + stockExpected: 1, + category: "", + rating: -1, + discount100: 0, + }); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [success, setSuccess] = useState(false); + + const handleClose = () => { + setError(null); + setSuccess(false); + setLoading(false); + onClose(); + }; + + const handleChange = (e: React.ChangeEvent) => { + setItem({ ...item, [e.target.name]: e.target.value }); + }; + + const handleSave = async () => { + setLoading(true); + setError(null); + setSuccess(false); + }; + + return ( + + + {t('createNewItem')} + + + + + + + + {/* Name, Kategorie, Beschreibung, Preis, Rabatt, Bestand, Bestand erwartet */} + + + + + + + + + {/* Error Message */} + {error && ( + setError(null)}> + {error} + + )} + + {/* Success Message */} + {success && ( + + {t('itemCreatedSuccessfully')} + + )} + + + + + + + + + ); +} \ No newline at end of file