Fix updating of user roles

Fix adding of items
This commit is contained in:
Nico 2025-11-23 01:41:15 -08:00
parent d9c4a2caf9
commit f30474cb5d
8 changed files with 56 additions and 21 deletions

View File

@ -6,6 +6,12 @@ exports.getList = async (req, res) => {
res.json(items);
};
exports.getItemByName = async (req, res) => {
const { itemName } = req.query;
const item = await List.getItemByName(itemName);
res.json(item);
}
exports.addItem = async (req, res) => {
const { itemName, quantity } = req.body;

View File

@ -14,10 +14,10 @@ exports.getAllUsers = async (req, res) => {
exports.updateUserRole = async (req, res) => {
try {
const { id } = req.params;
const { role } = req.body;
const { id, role } = req.body;
if (!Object.values(ROLES).includes(role))
console.log(`Updating user ${id} to role ${role}`);
if (!Object.values(User.ROLES).includes(role))
return res.status(400).json({ error: "Invalid role" });
const updated = await User.updateUserRole(id, role);

View File

@ -8,23 +8,37 @@ exports.getUnboughtItems = async () => {
return result.rows;
};
exports.addOrUpdateItem = async (item_name, quantity) => {
exports.getItemByName = async (itemName) => {
const result = await pool.query(
"SELECT id, bought FROM grocery_list WHERE item_name = $1",
[item_name]
"SELECT * FROM grocery_list WHERE item_name ILIKE $1",
[itemName]
);
return result.rows[0] || null;
};
exports.addOrUpdateItem = async (itemName, quantity) => {
const result = await pool.query(
"SELECT id, bought FROM grocery_list WHERE item_name ILIKE $1",
[itemName]
);
if (result.rowCount > 0) {
await pool.query(
"UPDATE grocery_list SET quantity = $1, bought = FALSE WHERE id = $2",
`UPDATE grocery_list
SET quantity = $1,
bought = FALSE
WHERE id = $2`,
[quantity, result.rows[0].id]
);
return result.rows[0].id;
} else {
const insert = await pool.query(
"INSERT INTO grocery_list (item_name, quantity) VALUES ($1, $2) RETURNING id",
[item_name, quantity]
`INSERT INTO grocery_list
(item_name, quantity)
VALUES ($1, $2) RETURNING id`,
[itemName, quantity]
);
return insert.rows[0].id;
}

View File

@ -7,8 +7,9 @@ const User = require("../models/user.model");
router.get("/", auth, requireRole(ROLES.VIEWER, ROLES.EDITOR, ROLES.ADMIN), controller.getList);
router.get("/suggest", auth, requireRole(ROLES.VIEWER, ROLES.EDITOR, ROLES.ADMIN), controller.getSuggestions);
router.get("/", auth, requireRole(...Object.values(ROLES)), controller.getList);
router.get("/item-by-name", auth, requireRole(...Object.values(ROLES)), controller.getItemByName);
router.get("/suggest", auth, requireRole(...Object.values(ROLES)), controller.getSuggestions);
router.post("/add", auth, requireRole(ROLES.EDITOR, ROLES.ADMIN), controller.addItem);

View File

@ -1,6 +1,7 @@
import api from "./axios";
export const getList = () => api.get("/list");
export const addItem = (itemName, quantiy) => api.post("/list/add", { itemName, quantiy });
export const getItemByName = (itemName) => api.get("/list/item-by-name", { params: { itemName: itemName } });
export const addItem = (itemName, quantity) => api.post("/list/add", { itemName, quantity });
export const markBought = (id) => api.post("/list/mark-bought", { id });
export const getSuggestions = (query) => api.get("/list/suggest", { params: { query: query } });

View File

@ -1,6 +1,6 @@
import api from "./axios";
export const getAllUsers = () => api.get("/admin/users");
export const updateRole = (id, role) => api.put(`/admin/users/${id}/role`, { role });
export const updateRole = (id, role) => api.put(`/admin/users`, { id, role });
export const deleteUser = (id) => api.delete(`/admin/users/${id}`);
export const checkIfUserExists = (username) => api.get(`/users/exists`, { params: { username: username } });

View File

@ -17,7 +17,8 @@ export default function AdminPanel() {
const changeRole = async (id, role) => {
const updated = await updateRole(id, role);
setUsers(users.map(u => (u.id === id ? updated.data : u)))
if (updated.status !== 200) return;
loadUsers();
}
return (

View File

@ -1,5 +1,5 @@
import { useContext, useEffect, useState } from "react";
import { addItem, getList, getSuggestions, markBought } from "../api/list";
import { addItem, getItemByName, getList, getSuggestions, markBought } from "../api/list";
import { ROLES } from "../constants/roles";
import { AuthContext } from "../context/AuthContext";
import "../styles/GroceryList.css";
@ -12,6 +12,7 @@ export default function GroceryList() {
const [sortMode, setSortMode] = useState("az");
const [showSuggestions, setShowSuggestions] = useState(false);
const [itemName, setItemName] = useState("");
const [quantity, setQuantity] = useState(1);
const [suggestions, setSuggestions] = useState([]);
@ -57,10 +58,8 @@ export default function GroceryList() {
}
try {
console.log("Getting suggestions for:", text);
let suggestions = await getSuggestions(text);
suggestions = suggestions.data.map(s => s.item_name);
console.log(`Suggestions: ${suggestions}`);
setSuggestions(suggestions);
} catch {
setSuggestions([]);
@ -70,8 +69,20 @@ export default function GroceryList() {
const handleAdd = async (e) => {
e.preventDefault();
if (!itemName.trim()) return;
let newQuantity = quantity;
await addItem(itemName, quantity);
const item = await getItemByName(itemName);
if (item) {
let currentQuantity = item.data.quantity;
const yes = window.confirm(
`Item "${itemName}" already exists in the list. Do you want to update its quantity from ${currentQuantity} to ${currentQuantity + newQuantity}?`
);
if (!yes) return;
newQuantity += currentQuantity;
}
await addItem(itemName, newQuantity);
setItemName("");
setQuantity(1);
@ -93,7 +104,6 @@ export default function GroceryList() {
return (
<div className="glist-body">
<div className="glist-container">
<h1 className="glist-title">Costco Grocery List</h1>
{/* Sorting dropdown */}
@ -117,9 +127,11 @@ export default function GroceryList() {
placeholder="Item name"
value={itemName}
onChange={(e) => handleSuggest(e.target.value)}
onBlur={() => setTimeout(() => setShowSuggestions(false), 150)}
onClick={() => setShowSuggestions(true)}
/>
{suggestions.length > 0 && (
{showSuggestions && suggestions.length > 0 && (
<ul className="glist-suggest-box">
{suggestions.map((s, i) => (
<li