Add product and storage management routes and database functions
This commit is contained in:
@@ -10,3 +10,58 @@ const pool = mysql
|
||||
database: process.env.DB_NAME,
|
||||
})
|
||||
.promise();
|
||||
|
||||
export const newProduct = async (
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
amount,
|
||||
storage_location,
|
||||
expiry_date,
|
||||
bottling_date,
|
||||
) => {
|
||||
const [result] = await pool.query(
|
||||
"INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES (?, ?, ?, ?, UUID_TO_BIN(?), ?, ?)",
|
||||
[
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
amount,
|
||||
storage_location,
|
||||
expiry_date,
|
||||
bottling_date,
|
||||
],
|
||||
);
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
return { code: "sp001" }; // success
|
||||
} else {
|
||||
return { code: "ep001" }; // error
|
||||
}
|
||||
};
|
||||
|
||||
export const allProducts = async () => {
|
||||
const [result] = await pool.query(`
|
||||
SELECT
|
||||
BIN_TO_UUID(p.uuid) AS uuid,
|
||||
p.name,
|
||||
p.description,
|
||||
p.price,
|
||||
p.amount,
|
||||
BIN_TO_UUID(s.uuid) AS storage_location_uuid,
|
||||
s.name AS storage_location_name,
|
||||
p.expiry_date,
|
||||
p.bottling_date,
|
||||
p.picture,
|
||||
p.created_at,
|
||||
p.updated_at
|
||||
FROM products p
|
||||
JOIN storage_locations s ON p.storage_location = s.uuid
|
||||
`);
|
||||
|
||||
if (result.length > 0) {
|
||||
return { code: "sp002", data: result };
|
||||
} else {
|
||||
return { code: "ep002" };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import mysql from "mysql2";
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
const pool = mysql
|
||||
.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
})
|
||||
.promise();
|
||||
|
||||
export const allStorages = async () => {
|
||||
const [result] = await pool.query(
|
||||
"SELECT BIN_TO_UUID(uuid) AS uuid, name, description, created_at, updated_at FROM storage_locations;",
|
||||
);
|
||||
|
||||
if (result.length > 0) {
|
||||
return { code: "ss001", data: result };
|
||||
} else {
|
||||
return { code: "es001" };
|
||||
}
|
||||
};
|
||||
|
||||
export const newStorage = async (name, description) => {
|
||||
const [result] = await pool.query(
|
||||
"INSERT INTO storage_locations (name, description) VALUES (?, ?)",
|
||||
[name, description],
|
||||
);
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
return { code: "ss002" };
|
||||
} else {
|
||||
return { code: "es002" };
|
||||
}
|
||||
};
|
||||
@@ -18,14 +18,14 @@ export const findUser = async (username, password) => {
|
||||
);
|
||||
|
||||
if (result.length <= 0) {
|
||||
return { code: "e001" }; // username or password is wrong
|
||||
return { code: "eu001" }; // username or password is wrong
|
||||
}
|
||||
|
||||
if (!result[0].is_active) {
|
||||
return { code: "e002" }; // user is deactivated
|
||||
return { code: "eu002" }; // user is deactivated
|
||||
}
|
||||
|
||||
return { code: "s001", data: result[0] }; // user found
|
||||
return { code: "su001", data: result[0] }; // user found
|
||||
};
|
||||
|
||||
export const loginUser = async (username) => {
|
||||
@@ -35,8 +35,8 @@ export const loginUser = async (username) => {
|
||||
);
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
return { code: "s002" };
|
||||
return { code: "su002" };
|
||||
} else {
|
||||
return { code: "e003" };
|
||||
return { code: "eu003" };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,70 @@
|
||||
import express from "express";
|
||||
import dotenv from "dotenv";
|
||||
import { authenticate } from "../../services/tokenService.js";
|
||||
import { allProducts, newProduct } from "./database/products.database.js";
|
||||
dotenv.config();
|
||||
const router = express.Router();
|
||||
|
||||
router.post("/new-product", authenticate, async (req, res) => {
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
amount,
|
||||
storage_location,
|
||||
expiry_date,
|
||||
bottling_date,
|
||||
} = req.body;
|
||||
|
||||
const result = await newProduct(
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
amount,
|
||||
storage_location,
|
||||
expiry_date,
|
||||
bottling_date,
|
||||
);
|
||||
|
||||
if (result.code === "ep001") {
|
||||
res.status(406).json({
|
||||
success: false,
|
||||
code: "ep001",
|
||||
data: null,
|
||||
message: "Error while creating product",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "sp001") {
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
code: "sp001",
|
||||
data: null,
|
||||
message: "",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/all-products", authenticate, async (req, res) => {
|
||||
const result = await allProducts();
|
||||
|
||||
if (result.code === "ep002") {
|
||||
res.status(406).json({
|
||||
success: false,
|
||||
code: "ep002",
|
||||
data: null,
|
||||
message: "Error while fetching products",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "sp002") {
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: "sp002",
|
||||
data: result.data,
|
||||
message: "",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import express from "express";
|
||||
import dotenv from "dotenv";
|
||||
import { authenticate } from "../../services/tokenService.js";
|
||||
import { allStorages, newStorage } from "./database/storage.database.js";
|
||||
dotenv.config();
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/all-storages", authenticate, async (req, res) => {
|
||||
const result = await allStorages();
|
||||
|
||||
if (result.code === "es001") {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
code: "es001",
|
||||
data: null,
|
||||
message: "unexpected server error",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "ss001") {
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: "ss001",
|
||||
data: result.data,
|
||||
message: "",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/new-storage", authenticate, async (req, res) => {
|
||||
const { name, description } = req.body;
|
||||
|
||||
const result = await newStorage(name, description);
|
||||
|
||||
if (result.code === "es002") {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
code: "es002",
|
||||
data: null,
|
||||
message: "unexpected server error",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "ss002") {
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
code: "ss002",
|
||||
data: null,
|
||||
message: "",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -11,32 +11,32 @@ router.post("/login", async (req, res) => {
|
||||
|
||||
const result = await findUser(username, password);
|
||||
|
||||
if (result.code === "e001") {
|
||||
if (result.code === "eu001") {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
code: "e001",
|
||||
code: "eu001",
|
||||
data: null,
|
||||
message: "username oder password is wrong",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "e002") {
|
||||
if (result.code === "eu002") {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
code: "e002",
|
||||
code: "eu002",
|
||||
data: null,
|
||||
message: "user is deactivated",
|
||||
});
|
||||
}
|
||||
|
||||
if (result.code === "s001") {
|
||||
if (result.code === "su001") {
|
||||
const token = await generateToken(result.data);
|
||||
const login = await loginUser(result.data.username);
|
||||
|
||||
if (login.code === "e003") {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
code: "e003",
|
||||
code: "eu003",
|
||||
data: null,
|
||||
message: "Unexpected server error. Please contact system admin.",
|
||||
});
|
||||
@@ -44,7 +44,7 @@ router.post("/login", async (req, res) => {
|
||||
|
||||
res.status(202).json({
|
||||
success: true,
|
||||
code: "s001",
|
||||
code: "su001",
|
||||
data: {
|
||||
token,
|
||||
},
|
||||
|
||||
@@ -18,6 +18,9 @@ app.use("/users", userRouter);
|
||||
import productRouter from "./routes/app/products.route.js";
|
||||
app.use("/products", productRouter);
|
||||
|
||||
import storageRouter from "./routes/app/storage.route.js";
|
||||
app.use("/storage", storageRouter);
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server is running on http://localhost:${PORT}`);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
|
||||
import babel from '@rolldown/plugin-babel'
|
||||
import { defineConfig } from "vite";
|
||||
import react, { reactCompilerPreset } from "@vitejs/plugin-react";
|
||||
import babel from "@rolldown/plugin-babel";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
babel({ presets: [reactCompilerPreset()] })
|
||||
tailwindcss(),
|
||||
babel({ presets: [reactCompilerPreset()] }),
|
||||
],
|
||||
})
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user