From 4501c47849d1a09197b0e9680c960fb856496900 Mon Sep 17 00:00:00 2001 From: Nico Date: Sat, 22 Nov 2025 17:05:21 -0800 Subject: [PATCH] Add navbar Fix username not being passed from the api --- backend/app.js | 3 + backend/controllers/auth.controller.js | 2 +- backend/controllers/suggest.controller.js | 9 + backend/models/list.model.js | 14 ++ backend/routes/suggest.routes.js | 9 + frontend/src/App.jsx | 32 ++-- frontend/src/api/auth.js | 1 + frontend/src/api/list.js | 6 +- frontend/src/components/AppLayout.jsx | 11 ++ frontend/src/components/Navbar.jsx | 28 ++- frontend/src/pages/GroceryList.jsx | 211 +++++++++++++++------- frontend/src/styles/GroceryList.css | 134 ++++++++++++++ frontend/src/styles/Navbar.css | 58 ++++++ 13 files changed, 429 insertions(+), 89 deletions(-) create mode 100644 backend/controllers/suggest.controller.js create mode 100644 backend/routes/suggest.routes.js create mode 100644 frontend/src/components/AppLayout.jsx create mode 100644 frontend/src/styles/GroceryList.css create mode 100644 frontend/src/styles/Navbar.css diff --git a/backend/app.js b/backend/app.js index c051ed1..50348af 100644 --- a/backend/app.js +++ b/backend/app.js @@ -44,5 +44,8 @@ app.use("/admin", adminRoutes); const usersRoutes = require("./routes/users.routes"); app.use("/users", usersRoutes); +const suggestController = require("./routes/suggest.routes"); +app.get("/suggest", suggestController); + module.exports = app; \ No newline at end of file diff --git a/backend/controllers/auth.controller.js b/backend/controllers/auth.controller.js index 7f56c80..979f5a4 100644 --- a/backend/controllers/auth.controller.js +++ b/backend/controllers/auth.controller.js @@ -30,5 +30,5 @@ exports.login = async (req, res) => { { expiresIn: "1d" } ); - res.json({ token, role: user.role }); + res.json({ token, username, role: user.role }); }; diff --git a/backend/controllers/suggest.controller.js b/backend/controllers/suggest.controller.js new file mode 100644 index 0000000..5a69a20 --- /dev/null +++ b/backend/controllers/suggest.controller.js @@ -0,0 +1,9 @@ +const List = require("../models/list.model"); + + +exports.getHistory = async (req, res) => { + console.log("GET /suggest called"); + const { query } = req.query; + const items = await List.getHistory(query); + res.json("asdf"); +}; \ No newline at end of file diff --git a/backend/models/list.model.js b/backend/models/list.model.js index e454c03..499a110 100644 --- a/backend/models/list.model.js +++ b/backend/models/list.model.js @@ -44,3 +44,17 @@ exports.addHistoryRecord = async (itemId, quantity) => { ); }; +exports.getHistory = async (query) => { + const result = await pool.query( + `SELECT DISTINCT item_name + FROM grocery_list + WHERE item_name ILIKE $1 + LIMIT 10`, + [`%${query}%`] + ); + console.log("QUERY:"); + console.log(result.query); + return result.rows; + +}; + diff --git a/backend/routes/suggest.routes.js b/backend/routes/suggest.routes.js new file mode 100644 index 0000000..0d13e01 --- /dev/null +++ b/backend/routes/suggest.routes.js @@ -0,0 +1,9 @@ +const router = require("express").Router(); +const controller = require("../controllers/suggest.controller"); +const auth = require("../middleware/auth"); +const requireRole = require("../middleware/rbac"); +const { ROLES } = require("../models/user.model"); + +router.get("/", auth, requireRole(ROLES.VIEWER, ROLES.EDITOR, ROLES.ADMIN), controller.getHistory); + +module.exports = router; diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 683181c..82306bf 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -6,31 +6,41 @@ import AdminPanel from "./pages/AdminPanel.jsx"; import GroceryList from "./pages/GroceryList.jsx"; import Login from "./pages/Login.jsx"; +import AppLayout from "./components/AppLayout.jsx"; import PrivateRoute from "./utils/PrivateRoute.jsx"; + import RoleGuard from "./utils/RoleGuard.jsx"; + function App() { return ( + + {/* Public route */} } /> + + {/* Private routes with layout */} - + } - /> - - - - } - /> + > + } /> + + + + + } + /> + + diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index ad0ca3a..d52cedd 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -2,6 +2,7 @@ import api from "./axios"; export const loginRequest = async (username, password) => { const res = await api.post("/auth/login", { username, password }); + alert(`Response data: ${JSON.stringify(res.data)}`); return res.data; }; diff --git a/frontend/src/api/list.js b/frontend/src/api/list.js index 7595d38..4423986 100644 --- a/frontend/src/api/list.js +++ b/frontend/src/api/list.js @@ -2,4 +2,8 @@ import api from "./axios"; export const getList = () => api.get("/list"); export const addItem = (itemName, quantiy) => api.post("/list/add", { itemName, quantiy }); -export const markBought = (id) => api.post("/list/mark-bought", { id }); \ No newline at end of file +export const markBought = (id) => api.post("/list/mark-bought", { id }); +export const suggest = (query) => { + console.log("API SUGGEST QUERY:", query); + api.get("/suggest", { query }); +}; \ No newline at end of file diff --git a/frontend/src/components/AppLayout.jsx b/frontend/src/components/AppLayout.jsx new file mode 100644 index 0000000..028174a --- /dev/null +++ b/frontend/src/components/AppLayout.jsx @@ -0,0 +1,11 @@ +import { Outlet } from "react-router-dom"; +import Navbar from "./Navbar"; + +export default function AppLayout() { + return ( +
+ + +
+ ); +} diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx index 95591dd..c4845cb 100644 --- a/frontend/src/components/Navbar.jsx +++ b/frontend/src/components/Navbar.jsx @@ -1,16 +1,30 @@ +import "../styles/Navbar.css"; + import { useContext } from "react"; import { Link } from "react-router-dom"; -import { ROLES } from "../constants/roles"; import { AuthContext } from "../context/AuthContext"; export default function Navbar() { - const { role, logout } = useContext(AuthContext); + const { role, logout, username } = useContext(AuthContext); return ( -