diff --git a/backend/routes/app/database/products.database.js b/backend/routes/app/database/products.database.js
index 43c4ac2..b91dfe8 100644
--- a/backend/routes/app/database/products.database.js
+++ b/backend/routes/app/database/products.database.js
@@ -91,3 +91,42 @@ export const allProducts = async () => {
return { code: "ep002" };
}
};
+
+export const setAmount = async (itemUUID, amount) => {
+ const [result] = await pool.query(
+ `
+ UPDATE products SET amount = ? WHERE uuid = UUID_TO_BIN(?)
+ `,
+ [amount, itemUUID],
+ );
+
+ if (result.affectedRows > 0) {
+ return { code: "sp004" }; // success
+ } else {
+ return { code: "ep004" }; // error
+ }
+};
+
+export const updateItem = async (itemUUID, newValues) => {
+ const [result] = await pool.query(
+ `
+ UPDATE products SET name = ?, description = ?, price = ?, amount = ?, storage_location = UUID_TO_BIN(?), expiry_date = ?, bottling_date = ? WHERE uuid = UUID_TO_BIN(?);
+ `,
+ [
+ newValues.name,
+ newValues.description,
+ newValues.price,
+ newValues.amount,
+ newValues.storage_location_uuid,
+ newValues.expiry_date,
+ newValues.bottling_date,
+ itemUUID,
+ ],
+ );
+
+ if (result.affectedRows > 0) {
+ return { code: "sp005" }; // success
+ } else {
+ return { code: "ep005" }; // error
+ }
+};
diff --git a/backend/routes/app/products.route.js b/backend/routes/app/products.route.js
index 167cf90..d6d7410 100644
--- a/backend/routes/app/products.route.js
+++ b/backend/routes/app/products.route.js
@@ -5,6 +5,8 @@ import {
allProducts,
newProduct,
productDetails,
+ setAmount,
+ updateItem,
} from "./database/products.database.js";
dotenv.config();
const router = express.Router();
@@ -95,4 +97,54 @@ router.get("/view", authenticate, async (req, res) => {
}
});
+router.put("/mutate/set-amount", authenticate, async (req, res) => {
+ const amount = req.query.amount;
+ const itemUUID = req.query.item;
+
+ const result = await setAmount(itemUUID, amount);
+
+ if (result.code === "ep004") {
+ res.status(406).json({
+ success: false,
+ code: "ep004",
+ data: null,
+ message: "Error while updating product amount",
+ });
+ }
+
+ if (result.code === "sp004") {
+ res.status(200).json({
+ success: true,
+ code: "sp004",
+ data: null,
+ message: "",
+ });
+ }
+});
+
+router.post("/mutate/update-item", authenticate, async (req, res) => {
+ const itemUUID = req.query.item;
+ const newValues = req.body;
+
+ const result = await updateItem(itemUUID, newValues);
+
+ if (result.code === "ep005") {
+ res.status(406).json({
+ success: false,
+ code: "ep005",
+ data: null,
+ message: "Error while updating product",
+ });
+ }
+
+ if (result.code === "sp005") {
+ res.status(200).json({
+ success: true,
+ code: "sp005",
+ data: null,
+ message: "",
+ });
+ }
+});
+
export default router;
diff --git a/frontend/src/misc/interfaces.ts b/frontend/src/misc/interfaces.ts
new file mode 100644
index 0000000..10f4a25
--- /dev/null
+++ b/frontend/src/misc/interfaces.ts
@@ -0,0 +1,22 @@
+export interface productDetailsInterface {
+ amount: number;
+ bottling_date: string;
+ description: string;
+ expiry_date: string;
+ name: string;
+ picture: string | null;
+ price: string;
+ storage_location_name: string;
+ storage_location_uuid: string;
+ uuid: string;
+}
+
+export type ProductFormValues = {
+ amount: number;
+ bottling_date: string;
+ description: string;
+ expiry_date: string;
+ name: string;
+ price: string;
+ storage_location_uuid: string;
+};
diff --git a/frontend/src/pages/ViewProduct.tsx b/frontend/src/pages/ViewProduct.tsx
index 6c715c5..4821430 100644
--- a/frontend/src/pages/ViewProduct.tsx
+++ b/frontend/src/pages/ViewProduct.tsx
@@ -1,22 +1,20 @@
-import { useQuery } from "@tanstack/react-query";
-import { getProductDetails } from "../utils/uxFncs";
-import { CircularProgress, Typography } from "@mui/joy";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import { getProductDetails, getStorages } from "../utils/uxFncs";
+import {
+ CircularProgress,
+ Typography,
+ Select,
+ Option,
+ Input,
+ Button,
+} from "@mui/joy";
import { useTranslation } from "react-i18next";
import { useEffect } from "react";
-import { formatDate } from "../utils/uxFncs";
-
-interface productDetailsInterface {
- amount: number;
- bottling_date: string;
- description: string;
- expiry_date: string;
- name: string;
- picture: string | null;
- price: string;
- storage_location_name: string;
- storage_location_uuid: string;
- uuid: string;
-}
+import { useForm } from "@tanstack/react-form";
+import { mutateProduct } from "../utils/uxFncs";
+import { toInputDate } from "../utils/uxFncs";
+import type { ProductFormValues } from "../misc/interfaces";
+import type { productDetailsInterface } from "../misc/interfaces";
interface ViewProductProps {
uuid: string;
@@ -25,6 +23,7 @@ interface ViewProductProps {
export const ViewProduct = (props: ViewProductProps) => {
const uuid = props.uuid;
const { t } = useTranslation();
+ const queryClient = useQueryClient();
const {
data: productDetails,
@@ -35,9 +34,62 @@ export const ViewProduct = (props: ViewProductProps) => {
queryFn: () => getProductDetails(uuid),
});
+ const { data: storages } = useQuery({
+ queryKey: ["storages"],
+ queryFn: () => getStorages(),
+ });
+
+ const form = useForm({
+ defaultValues: {
+ amount: 0,
+ bottling_date: "",
+ description: "",
+ expiry_date: "",
+ name: "",
+ price: "",
+ storage_location_uuid: "",
+ },
+ onSubmit: async ({ value }) => {
+ if (!productDetails?.uuid) {
+ return;
+ }
+
+ mutate({ values: value, uuid: productDetails.uuid });
+ },
+ });
+
+ const { mutate, isPending } = useMutation({
+ mutationFn: ({
+ values,
+ uuid,
+ }: {
+ values: ProductFormValues;
+ uuid: string;
+ }) => mutateProduct(values, uuid),
+ onSuccess: (_data, variables) => {
+ queryClient.invalidateQueries({ queryKey: ["product", variables.uuid] });
+ },
+ });
+
useEffect(() => {
- console.log(productDetails);
- }, [isSuccess]);
+ if (!productDetails) {
+ return;
+ }
+
+ form.setFieldValue("amount", productDetails.amount ?? 0);
+ form.setFieldValue(
+ "bottling_date",
+ toInputDate(productDetails.bottling_date),
+ );
+ form.setFieldValue("description", productDetails.description ?? "");
+ form.setFieldValue("expiry_date", toInputDate(productDetails.expiry_date));
+ form.setFieldValue("name", productDetails.name ?? "");
+ form.setFieldValue("price", productDetails.price ?? "");
+ form.setFieldValue(
+ "storage_location_uuid",
+ productDetails.storage_location_uuid ?? "",
+ );
+ }, [form, productDetails]);
return (
<>
@@ -45,11 +97,100 @@ export const ViewProduct = (props: ViewProductProps) => {
{productDetailsLoading &&