Add product and storage management routes and database functions
This commit is contained in:
@@ -9,4 +9,59 @@ const pool = mysql
|
|||||||
password: process.env.DB_PASSWORD,
|
password: process.env.DB_PASSWORD,
|
||||||
database: process.env.DB_NAME,
|
database: process.env.DB_NAME,
|
||||||
})
|
})
|
||||||
.promise();
|
.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) {
|
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) {
|
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) => {
|
export const loginUser = async (username) => {
|
||||||
@@ -35,8 +35,8 @@ export const loginUser = async (username) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (result.affectedRows > 0) {
|
if (result.affectedRows > 0) {
|
||||||
return { code: "s002" };
|
return { code: "su002" };
|
||||||
} else {
|
} else {
|
||||||
return { code: "e003" };
|
return { code: "eu003" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,70 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
|
import { authenticate } from "../../services/tokenService.js";
|
||||||
|
import { allProducts, newProduct } from "./database/products.database.js";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
const router = express.Router();
|
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;
|
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);
|
const result = await findUser(username, password);
|
||||||
|
|
||||||
if (result.code === "e001") {
|
if (result.code === "eu001") {
|
||||||
res.status(404).json({
|
res.status(404).json({
|
||||||
success: false,
|
success: false,
|
||||||
code: "e001",
|
code: "eu001",
|
||||||
data: null,
|
data: null,
|
||||||
message: "username oder password is wrong",
|
message: "username oder password is wrong",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.code === "e002") {
|
if (result.code === "eu002") {
|
||||||
res.status(403).json({
|
res.status(403).json({
|
||||||
success: false,
|
success: false,
|
||||||
code: "e002",
|
code: "eu002",
|
||||||
data: null,
|
data: null,
|
||||||
message: "user is deactivated",
|
message: "user is deactivated",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.code === "s001") {
|
if (result.code === "su001") {
|
||||||
const token = await generateToken(result.data);
|
const token = await generateToken(result.data);
|
||||||
const login = await loginUser(result.data.username);
|
const login = await loginUser(result.data.username);
|
||||||
|
|
||||||
if (login.code === "e003") {
|
if (login.code === "e003") {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
code: "e003",
|
code: "eu003",
|
||||||
data: null,
|
data: null,
|
||||||
message: "Unexpected server error. Please contact system admin.",
|
message: "Unexpected server error. Please contact system admin.",
|
||||||
});
|
});
|
||||||
@@ -44,7 +44,7 @@ router.post("/login", async (req, res) => {
|
|||||||
|
|
||||||
res.status(202).json({
|
res.status(202).json({
|
||||||
success: true,
|
success: true,
|
||||||
code: "s001",
|
code: "su001",
|
||||||
data: {
|
data: {
|
||||||
token,
|
token,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ app.use("/users", userRouter);
|
|||||||
import productRouter from "./routes/app/products.route.js";
|
import productRouter from "./routes/app/products.route.js";
|
||||||
app.use("/products", productRouter);
|
app.use("/products", productRouter);
|
||||||
|
|
||||||
|
import storageRouter from "./routes/app/storage.route.js";
|
||||||
|
app.use("/storage", storageRouter);
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Server is running on http://localhost:${PORT}`);
|
console.log(`Server is running on http://localhost:${PORT}`);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from "vite";
|
||||||
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
|
import react, { reactCompilerPreset } from "@vitejs/plugin-react";
|
||||||
import babel from '@rolldown/plugin-babel'
|
import babel from "@rolldown/plugin-babel";
|
||||||
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
babel({ presets: [reactCompilerPreset()] })
|
tailwindcss(),
|
||||||
|
babel({ presets: [reactCompilerPreset()] }),
|
||||||
],
|
],
|
||||||
})
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user