some code and stuff

This commit is contained in:
Smigz 2025-01-16 16:28:53 -05:00
parent 75b83e30ea
commit 17d664eaeb
19 changed files with 762 additions and 4 deletions

View file

@ -7,8 +7,9 @@ const port = 8080;
const { indexRouter } = require("./routes/indexRouter");
const assetsPath = path.join(path.dirname(__dirname), "public");
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
app.set(express.static(assetsPath));
app.use(express.static(assetsPath));
app.use(express.urlencoded({ extended: true }));

6
inventory/src/config.js Normal file
View file

@ -0,0 +1,6 @@
exports.links = [
{ name: "home", href: "/" },
{ name: "store", href: "/store" },
{ name: "categories", href: "/category" },
{ name: "new item", href: "/add" },
];

View file

@ -0,0 +1,150 @@
const db = require("../db/queries");
const { links } = require("../config");
async function indexGet(req, res) {
const items = await db.getAllItemsWithRelationships();
res.render("base", {
links: links,
pageTitle: "Iventory Home",
items: items,
page: "",
});
}
async function storeGet(req, res) {
const stores = await db.getStores();
res.render("base", {
page: "add",
links: links,
pageTitle: "Inventory | Stores",
type: "store",
data: stores,
});
}
async function storesGetAll(req, res) {
const stores = await db.getStores();
res.json(stores);
}
async function storePost(req, res) {
const r = await handlePostRequets({ reqBody: req.body, dbName: "store" });
res.redirect("/store");
}
async function categoryGet(req, res) {
const categories = await db.getCategories();
res.render("base", {
page: "add",
links: links,
pageTitle: "Inventory | Categories",
type: "category",
data: categories,
});
}
async function categoryGetAll(req, res) {
const categories = await db.getCategories();
res.json(categories);
}
async function categoryPost(req, res) {
const r = await handlePostRequets({ reqBody: req.body, dbName: "category" });
if (r) {
console.log("something went wrong");
}
res.redirect("/category");
}
async function handlePostRequets(data) {
const { dbName } = data;
const { name } = data.reqBody;
let res;
if (dbName === "store") {
res = db.insertStore(name);
} else if (dbName === "category") {
res = db.insertCategory(name);
}
return res;
}
async function itemPost(req, res) {
const categoryId = await db.getCategoryId({ name: req.body.category });
const storeId = await db.getStoreId({ name: req.body.store });
let formData = req.body;
const data = {
name: formData.name,
price: formData.price,
qty: formData.qty,
store_id: storeId.store_id,
category_id: categoryId.category_id,
};
try {
const r = await db.insertItem(data);
if (r) throw new Error(r);
res.redirect("/");
} catch (e) {
console.log(e);
res.send({ error: e });
}
}
async function itemEditGet(req, res, next) {
const itemId = req.params.id;
const items = await db.getAllItemsWithRelationships();
const item = await db.getItemById(Number(itemId));
const categories = await db.getCategories();
const stores = await db.getStores();
if (item)
res.render("base", {
item: item,
categories: categories,
stores: stores,
pageTitle: `Inventory | Editing Item: ${item.name}`,
page: "edit",
links: links,
});
}
async function itemEditPost(req, res, next) {
const itemId = req.params.id;
console.log(itemId);
res.redirect("/");
}
async function itemDelete(req, res) {
console.log(req.body.name);
const itemId = await db.getItemByName(req.body.name);
if (itemId) db.deleteItem(itemId);
console.log(`Delted item: ${itemId}`);
res.redirect("deleted item: ${item}");
}
async function categoryDelete(req, res) {
const query = await db.deleteCategory(req.body.id);
if (query) {
res.send(`${query}`);
}
res.send("category deleted");
}
module.exports = {
indexGet,
itemPost,
itemEditGet,
itemEditPost,
itemDelete,
storeGet,
storePost,
storesGetAll,
categoryGet,
categoryPost,
categoryGetAll,
categoryDelete,
};

11
inventory/src/db/pool.js Normal file
View file

@ -0,0 +1,11 @@
const { Pool } = require("pg");
// Todo make this env variables
module.exports = new Pool({
host: "smig-ca04.lab.smig.tech",
user: "odin",
database: "odin",
password: "odinproject",
port: 32343,
});
// 32343;

120
inventory/src/db/queries.js Normal file
View file

@ -0,0 +1,120 @@
const pool = require("./pool");
async function getAllItems() {
const { rows } = await pool.query("SELECT * FROM items");
return rows;
}
async function getItemByName(name) {
const { rows } = await pool.query("SELECT * FROM items WHERE name = $1", [
name,
]);
return rows[0];
}
async function getItemById(id) {
const { rows } = await pool.query(
"SELECT id, items.name, price, qty, category.name AS category, store.name AS store FROM items LEFT JOIN category on items.category_id = category.category_id LEFT JOIN store ON items.store_id = store.store_id WHERE items.id = $1 ",
[id],
);
return rows[0];
}
async function insertItem(data) {
const { name, price, qty, category_id, store_id } = data;
try {
await pool.query(
`INSERT INTO items (name, price, qty, category_id, store_id) VALUES ($1, $2, $3, $4, $5)`,
[name, price, qty, category_id, store_id],
);
return null;
} catch (e) {
return e;
}
}
async function deleteItem(item) {
try {
const res = await pool.query("DELETE FROM items WHERE id = $1", [item.id]);
return null;
} catch (e) {
return e;
}
}
async function getAllItemsWithRelationships() {
const { rows } = await pool.query(
`SELECT items.id, items.name, items.price, items.qty, category.name AS category_name, store.name AS store_name FROM items
LEFT JOIN category ON items.category_id = category.category_id
LEFT JOIN store ON items.store_id = store.store_id;`,
);
return rows;
}
async function getCategories() {
const { rows } = await pool.query("SELECT * FROM category");
return rows;
}
async function getCategoryId(item) {
const { rows } = await pool.query("SELECT * FROM category WHERE name = $1", [
item.name,
]);
return rows[0];
}
async function insertCategory(data) {
try {
await pool.query("INSERT INTO category (name) VALUES ($1)", [data]);
return null;
} catch (e) {
return e;
}
}
async function deleteCategory(itemId) {
try {
await pool.query("DELETE FROM category WHERE category_id = $1", [itemId]);
return null;
} catch (e) {
return e;
}
}
async function getStores() {
const { rows } = await pool.query("SELECT * FROM store");
return rows;
}
async function getStoreId(item) {
const { rows } = await pool.query("SELECT * FROM store WHERE name = $1", [
item.name,
]);
return rows[0];
}
async function insertStore(data) {
try {
await pool.query("INSERT INTO store (name) VALUES ($1)", [data]);
return null;
} catch (e) {
return e;
}
}
module.exports = {
insertItem,
getItemById,
getAllItems,
getItemByName,
deleteItem,
getCategories,
getCategoryId,
getStores,
getStoreId,
insertStore,
insertCategory,
deleteCategory,
getAllItemsWithRelationships,
};

View file

@ -0,0 +1,64 @@
#!/usr/bin/env node
const { Client } = require("pg");
const CREATE_DB = `
CREATE DATABASE inventory_app;
`;
const SQL = `
CREATE TABLE IF NOT EXISTS store (
store_id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
name varchar(80) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS category (
category_id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
name varchar(40) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS items (
id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(80) NOT NULL,
price INTEGER,
qty INTEGER,
store_id INTEGER REFERENCES store (store_id),
category_id INTEGER REFERENCES category (category_id)
);
`;
const POPULATE = `
INSERT INTO category (name)
VALUES ('grocery'), ('clothing'), ('household'), ('cleaning'), ('misc');
INSERT INTO store (name)
VALUES ('target'), ('wegmans'), ('giant');
INSERT INTO items (name, price, qty, store_id, category_id)
VALUES ('paper towels', '399', '3', '2','3' );
`;
async function main() {
console.log("DB Creation script");
const client = new Client({
host: "smig-ca05.lab.smig.tech",
user: "odin",
database: "odin",
password: "odinproject",
port: 32343,
});
try {
await client.connect();
await client.query(POPULATE);
await client.end();
} catch (e) {
console.log(`ERROR: ${e}`);
process.exit(1);
}
console.log("Done");
}
main();

View file

@ -1,9 +1,20 @@
const { Router } = require("express");
const indexController = require("../controllers/indexController");
const indexRouter = Router();
indexRouter.get("/", (req, res) => {
res.send("index");
});
indexRouter.get("/", indexController.indexGet);
//indexRouter.post("/add")
indexRouter.get("/store", indexController.storeGet);
indexRouter.get("/stores", indexController.storesGetAll);
indexRouter.post("/store", indexController.storePost);
indexRouter.get("/category", indexController.categoryGet);
indexRouter.get("/categories", indexController.categoryGetAll);
indexRouter.post("/category", indexController.categoryPost);
indexRouter.delete("/category", indexController.categoryDelete);
indexRouter.post("/item", indexController.itemPost);
indexRouter.get("/item/:id", indexController.itemEditGet);
indexRouter.post("/item/:id", indexController.itemEditPost);
indexRouter.delete("/item", indexController.itemDelete);
module.exports = { indexRouter };

View file

@ -0,0 +1,16 @@
<h1><%= type %></h1>
<form method="POST" action="/<%= type %>">
<div class="container">
<div class="form-item">
<label for="name">Name</label>
<input type="text" name="name" placeholder="" required>
</div>
<div class="form-item btn-row">
<button type="submit">Submit</button>
<button type="button">Cancel</button>
</div>
</div>
</form>
<%- include("card", {items: data}) %>

View file

@ -0,0 +1,10 @@
<%- include('header', {links: links}); %>
<% if (page === "add") { %>
<%- include('addForm', {type: type}); %>
<% } else if (page === "edit") { %>
<%- include('editForm', {item: item, categories: categories, stores: stores}); %>
<% } else { %>
<%- include('itemTable', {items: items}); %>
<% }; %>
<%- include('footer'); %>

View file

@ -0,0 +1,14 @@
<div class="container">
<% items.forEach(item => { %>
<div class="container flex">
<p class="title">
<%= item.name %>
</p>
<button>Edit</button>
<% let itemId; %>
<% if (item.category_id) {itemId = item.category_id} else { itemId = item.store_id } %>
<button class="delete-btn" data-id="<%= itemId %>">Delete</button>
</div>
<% }); %>
</div>

View file

@ -0,0 +1,34 @@
<form method="POST" action="/item/id">
<div class="form-item"><label>Name</label><input name="name" value="<%= item.name %>" /></div>
<div class="form-item"><label>Price</label><input name="price" value=<%= item.price %> /></div>
<div class="form-item"><label>QTY</label><input name="qty" value=<%= item.qty %> /></div>
<div class="form-item">
<label>Categories</label>
<select class="categories-list" name="category">
<% categories.forEach((cat) => { %>
<% if (cat.name === item.category) { %>
<option name=<%= cat.value %> data-cat-id=<%= cat.category_id %> selected><%= cat.name %></option>
<% } else { %>
<option name=<%= cat.value %> data-cat-id=<%= cat.category_id%>><%= cat.name %></option>
<% }; %>
<% }); %>
</select>
</div>
<div class="form-item">
<label>stores</label>
<select class="stores-list" name="store">
<% stores.forEach((cat) => { %>
<% if (cat.name === item.store) { %>
<option name=<%= cat.name %> data-cat-id=<%= cat.store_id %> selected><%= cat.name %></option>
<% } else { %>
<option name=<%= cat.name %> data-cat-id=<%= cat.store_id %>><%= cat.name %></option>
<% } %>
<% }); %>
</select>
</div>
<button type="submit" class="btn">Add Item</button><button>Close</button>
</form>

View file

@ -0,0 +1,3 @@
<script type="module" src="/js/script.js"></script>
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><%= pageTitle %></title>
<link href="/css/style.css" rel="stylesheet">
</head>
<body>
<nav class="nav">
<ul>
<% links.forEach(link => { %>
<li><a href="<%= link.href %>"><%= link.name %></a></li>
<% }); %>
</ul>
</nav>

View file

@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
<link href="/css/style.css" rel="stylesheet" />
</head>
<body></body>
</html>

View file

@ -0,0 +1,26 @@
<table class="items">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">QTY</th>
<th scope="col">Store</th>
<th scope="col">Category</th>
</tr>
</thead>
<tbody>
<% items.forEach(item => { %>
<tr data-item-id="<%=item.id %>">
<td><%= item.name %></td>
<td><%= item.price %></td>
<td><%= item.qty %></td>
<td><%= item.store_name %></td>
<td><%= item.category_name %></td>
<td class="edit-button">Edit</td>
<td class="delete-button" data-id="<%= item.name %>">Delete</td>
</tr>
<% }); %>
</tbody>
</table>