From 4913810220e92149f660b510a50cfff8491b204d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 08:49:04 +0000 Subject: [PATCH 1/3] Initial plan From 11f7cb80c1d56184623251a57aba5e05e9ba161f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 08:58:05 +0000 Subject: [PATCH 2/3] Refactor duplicated code with centralized utilities Co-authored-by: Xsidz <146343711+Xsidz@users.noreply.github.com> --- backend/src/controllers/auth.controller.js | 63 ++++++++----------- .../src/controllers/dashboard.controller.js | 6 +- backend/src/controllers/rating.controller.js | 34 +++++----- backend/src/controllers/store.controller.js | 16 ++--- backend/src/controllers/user.controller.js | 33 +++++----- backend/src/models/user.model.js | 5 +- backend/src/utils/errorHandler.js | 16 +++++ backend/src/utils/passwordUtils.js | 19 ++++++ frontend/src/stores/authStore.js | 9 +-- frontend/src/stores/ratingStore.js | 9 +-- frontend/src/stores/storeStore.js | 21 ++----- frontend/src/stores/userStore.js | 23 ++----- frontend/src/utils/storeHelpers.js | 48 ++++++++++++++ 13 files changed, 177 insertions(+), 125 deletions(-) create mode 100644 backend/src/utils/errorHandler.js create mode 100644 backend/src/utils/passwordUtils.js create mode 100644 frontend/src/utils/storeHelpers.js diff --git a/backend/src/controllers/auth.controller.js b/backend/src/controllers/auth.controller.js index 1d74c65..6d7d340 100644 --- a/backend/src/controllers/auth.controller.js +++ b/backend/src/controllers/auth.controller.js @@ -1,7 +1,15 @@ -import bcrypt from "bcryptjs"; import { getPool } from "../utils/initDB.js"; import { gennToken } from "../utils/lib.js"; -const passwordRegex = /^(?=.*[A-Z])(?=.*[!@#$%^&*()_+{}\[\]:;<>,.?~\\-]).{8,16}$/; +import { + validatePassword, + hashPassword, + comparePassword, + PASSWORD_VALIDATION_MESSAGE, +} from "../utils/passwordUtils.js"; +import { + handleError, + handleValidationError, +} from "../utils/errorHandler.js"; export const signUp = async (req, res) => { const { Name, Email, Password, Address } = req.body; try { @@ -9,12 +17,9 @@ export const signUp = async (req, res) => { if (!Name || !Email || !Password || !Address) { return res.status(400).json({ message: "All fields are required !! " }); } - if (!passwordRegex.test(Password)) { - return res.status(400).json({ - message: - "Password must be 8-16 characters, include at least one uppercase letter and one special character." - }); -} + if (!validatePassword(Password)) { + return handleValidationError(res, PASSWORD_VALIDATION_MESSAGE); + } const pool = getPool(); const [existingUser] = await pool.query( `SELECT * FROM users WHERE email = ?`, @@ -24,9 +29,7 @@ export const signUp = async (req, res) => { return res.status(400).json({ message: "User Already Exists" }); } - - const salt = await bcrypt.genSalt(10); - const hashedPass = await bcrypt.hash(Password, salt); + const hashedPass = await hashPassword(Password); const [result] = await pool.query( `INSERT INTO users(name, email,password,address,role) VALUES(?,?,?,?,'user')`, @@ -48,8 +51,7 @@ export const signUp = async (req, res) => { return res.status(200).json(newUser); } catch (error) { - console.log("Error in the Signup controller :", error.message); - return res.status(500).json({ message: "Internal Server Error!!" }); + return handleError(res, error, "Signup controller"); } }; export const logIn = async (req, res) => { @@ -69,8 +71,7 @@ export const logIn = async (req, res) => { if (!user) { return res.status(400).json({ message: "Inavlid Credentials" }); } - - const isPassCorrect = await bcrypt.compare(password, user.password); + const isPassCorrect = await comparePassword(password, user.password); if (!isPassCorrect) { return res.status(400).json({ message: "Inavlid Credentials" }); } @@ -86,8 +87,7 @@ export const logIn = async (req, res) => { updated_at: user.updated_at, }); } catch (error) { - console.log("Error in the Login controller:", error.message); - return res.status(500).json({ message: "Internal server error" }); + return handleError(res, error, "Login controller"); } }; export const logOut = (req, res) => { @@ -104,8 +104,7 @@ export const logOut = (req, res) => { return res.status(200).json({ message: "LoggedOut Successfully" }); } catch (error) { - console.log("Error in the log out controller : ", error.message); - return res.status(500).json({ message: " Internal Server Error" }); + return handleError(res, error, "Logout controller"); } }; @@ -113,11 +112,8 @@ export const updatePassword = async (req, res) => { try { const { currentPassword, newPassword } = req.body; - if (!passwordRegex.test(newPassword)) { - return res.status(400).json({ - message: - "Password must be 8-16 characters, include at least one uppercase letter and one special character." - }); + if (!validatePassword(newPassword)) { + return handleValidationError(res, PASSWORD_VALIDATION_MESSAGE); } const pool = getPool(); @@ -132,15 +128,12 @@ export const updatePassword = async (req, res) => { const user = rows[0]; - - const passwordMatch = await bcrypt.compare(currentPassword, user.password); + const passwordMatch = await comparePassword(currentPassword, user.password); if (!passwordMatch) { return res.status(400).json({ message: "Current password is incorrect!!" }); } - - const salt = await bcrypt.genSalt(10); - const newHashed = await bcrypt.hash(newPassword, salt); + const newHashed = await hashPassword(newPassword); await pool.query(`UPDATE users SET password = ? WHERE id = ?`, [ @@ -155,17 +148,15 @@ export const updatePassword = async (req, res) => { message: "Password updated successfully. Please log in again", }); } catch (error) { - console.log("Error in the updatePassword Controller: ", error.message); - return res.status(500).json({ message: "Internal Server Error" }); + return handleError(res, error, "updatePassword Controller"); } }; -export const checkAuth = (req,res)=>{ +export const checkAuth = (req, res) => { try { - res.status(200).json(req.user) + res.status(200).json(req.user); } catch (error) { - console.log("Error in the CheckAuth controller :", error.message) - res.status(500).json({message : "Internal Server Error"}) + return handleError(res, error, "CheckAuth controller"); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/backend/src/controllers/dashboard.controller.js b/backend/src/controllers/dashboard.controller.js index 445416e..bf219fa 100644 --- a/backend/src/controllers/dashboard.controller.js +++ b/backend/src/controllers/dashboard.controller.js @@ -1,11 +1,11 @@ -import * as dashBoardModel from "../models/dashboard.model.js" +import * as dashBoardModel from "../models/dashboard.model.js"; +import { handleError } from "../utils/errorHandler.js"; export const getDashboard = async (req, res) => { try { const stats = await dashBoardModel.getDashboardStats(); res.status(200).json(stats); } catch (error) { - console.error("Error fetching dashboard stats:", error); - res.status(500).json({ message: "Failed to fetch dashboard stats" }); + return handleError(res, error, "getDashboard controller"); } }; \ No newline at end of file diff --git a/backend/src/controllers/rating.controller.js b/backend/src/controllers/rating.controller.js index 2093f35..e9aea87 100644 --- a/backend/src/controllers/rating.controller.js +++ b/backend/src/controllers/rating.controller.js @@ -1,5 +1,11 @@ import * as ratingModel from "../models/rating.model.js"; import * as storeModel from "../models/store.model.js"; +import { + handleError, + handleValidationError, + handleNotFoundError, + handleUnauthorizedError, +} from "../utils/errorHandler.js"; export const createRating = async (req, res) => { @@ -8,21 +14,20 @@ export const createRating = async (req, res) => { const user_id = req.user.id; if (!store_id || !rating) { - return res.status(400).json({ message: "store_id and rating are required" }); + return handleValidationError(res, "store_id and rating are required"); } if (rating < 1 || rating > 5) { - return res.status(400).json({ message: "Rating must be between 1 and 5" }); + return handleValidationError(res, "Rating must be between 1 and 5"); } const ratingId = await ratingModel.addRating(user_id, store_id, rating); res.status(201).json({ message: "Rating added successfully", ratingId }); } catch (error) { if (error.code === "ER_DUP_ENTRY") { - return res.status(400).json({ message: "You already rated this store" }); + return handleValidationError(res, "You already rated this store"); } - console.error("Error creating rating:", error); - res.status(500).json({ message: "Internal server error" }); + return handleError(res, error, "createRating controller"); } }; @@ -34,18 +39,17 @@ export const editRating = async (req, res) => { const user_id = req.user.id; if (!rating || rating < 1 || rating > 5) { - return res.status(400).json({ message: "Rating must be between 1 and 5" }); + return handleValidationError(res, "Rating must be between 1 and 5"); } const updated = await ratingModel.updateRating(id, user_id, rating); if (!updated) { - return res.status(404).json({ message: "Rating not found or not yours" }); + return handleNotFoundError(res, "Rating not found or not yours"); } res.json({ message: "Rating updated successfully" }); } catch (error) { - console.error("Error updating rating:", error); - res.status(500).json({ message: "Internal server error" }); + return handleError(res, error, "editRating controller"); } }; @@ -59,21 +63,18 @@ export const storeRatings = async (req, res) => { const store = await storeModel.getStoreById(storeId); if (!store) { - return res.status(404).json({ message: "Store not found" }); + return handleNotFoundError(res, "Store not found"); } - if (store.owner_id !== req.user.id) { - return res.status(403).json({ message: "You are not the owner of this store" }); + return handleUnauthorizedError(res, "You are not the owner of this store"); } - const ratings = await ratingModel.getStoreRatings(storeId); res.json({ storeId, ratings }); } catch (error) { - console.error("Error fetching store ratings:", error); - res.status(500).json({ message: "Internal server error" }); + return handleError(res, error, "storeRatings controller"); } }; @@ -84,8 +85,7 @@ export const getUserRatings = async (req, res) => { const ratings = await ratingModel.getUserRatings(user_id); res.json({ ratings }); } catch (error) { - console.error("Error fetching user ratings:", error); - res.status(500).json({ message: "Internal server error" }); + return handleError(res, error, "getUserRatings controller"); } }; diff --git a/backend/src/controllers/store.controller.js b/backend/src/controllers/store.controller.js index b05acdb..bec8f32 100644 --- a/backend/src/controllers/store.controller.js +++ b/backend/src/controllers/store.controller.js @@ -1,17 +1,20 @@ -import * as storeModel from "../models/store.model.js" +import * as storeModel from "../models/store.model.js"; +import { + handleError, + handleValidationError, +} from "../utils/errorHandler.js"; export const addStore = async (req, res) => { try { const { name, email, address, owner_id } = req.body; if (!name || !email || !address || !owner_id) { - return res.status(400).json({ message: "Name, email, address, and owner are required" }); + return handleValidationError(res, "Name, email, address, and owner are required"); } const newStore = await storeModel.addStore({ name, email, address, owner_id }); - console.log(newStore) + console.log(newStore); res.status(201).json({ message: "New Store added Successfuly !!" }); } catch (error) { - console.error("Error in addStore:", error); - res.status(500).json({ message: "Failed to add store" }); + return handleError(res, error, "addStore controller"); } }; @@ -21,8 +24,7 @@ export const getAllStores = async (req, res) => { const stores = await storeModel.getAllStores({ name, address }); res.json(stores); } catch (error) { - console.error("Error in getAllStores Controller:", error); - res.status(500).json({ message: "Failed to fetch stores" }); + return handleError(res, error, "getAllStores controller"); } }; diff --git a/backend/src/controllers/user.controller.js b/backend/src/controllers/user.controller.js index c8b2731..88e3e26 100644 --- a/backend/src/controllers/user.controller.js +++ b/backend/src/controllers/user.controller.js @@ -1,6 +1,13 @@ import * as userModel from "../models/user.model.js"; -const passwordRegex = - /^(?=.*[A-Z])(?=.*[!@#$%^&*()_+{}\[\]:;<>,.?~\\-]).{8,16}$/; +import { + validatePassword, + PASSWORD_VALIDATION_MESSAGE, +} from "../utils/passwordUtils.js"; +import { + handleError, + handleValidationError, + handleNotFoundError, +} from "../utils/errorHandler.js"; export const addUser = async (req, res) => { @@ -12,19 +19,15 @@ export const addUser = async (req, res) => { .json({ message: "All required fields must be provided" }); } - if (!passwordRegex.test(password)) { - return res.status(400).json({ - message: - "Password must be 8-16 characters, include at least one uppercase letter and one special character.", - }); + if (!validatePassword(password)) { + return handleValidationError(res, PASSWORD_VALIDATION_MESSAGE); } const newUser = await userModel.addUser(name, email, password, address, role); - console.log(newUser) - return res.status(201).json({message : "New User Created Successfully !!"}) + console.log(newUser); + return res.status(201).json({ message: "New User Created Successfully !!" }); } catch (error) { - console.error("Error in addUser controller:", error); - res.status(500).json({ message: "Failed to add user" }); + return handleError(res, error, "addUser controller"); } }; @@ -37,8 +40,7 @@ export const getAllUsers = async (req, res) => { const users = await userModel.getAllUsers({ name, email, address, role }); res.json(users); } catch (error) { - console.error("Error in getAllusers Conroller:", error); - res.status(500).json({ message: "Failed to fetch users" }); + return handleError(res, error, "getAllUsers controller"); } }; @@ -47,11 +49,10 @@ export const getUserDetails = async (req, res) => { const { id } = req.params; const user = await userModel.getUserDetails(id); - if (!user) return res.status(404).json({ message: "User not found" }); + if (!user) return handleNotFoundError(res, "User not found"); res.json(user); } catch (error) { - console.error("Error fetching user controller:", error); - res.status(500).json({ message: "Failed to fetch user details" }); + return handleError(res, error, "getUserDetails controller"); } }; \ No newline at end of file diff --git a/backend/src/models/user.model.js b/backend/src/models/user.model.js index 3677da8..ee82084 100644 --- a/backend/src/models/user.model.js +++ b/backend/src/models/user.model.js @@ -1,10 +1,9 @@ import { getPool } from "../utils/initDB.js"; -import bcrypt from "bcryptjs"; +import { hashPassword } from "../utils/passwordUtils.js"; export const addUser = async (name, email, password, address, role) => { const pool = getPool(); - const salt = await bcrypt.genSalt(10); - const hashPass = await bcrypt.hash(password, salt); + const hashPass = await hashPassword(password); const [result] = await pool.query( `INSERT INTO users (name,email,password,address,role) VALUES(?,?,?,?,?)`, diff --git a/backend/src/utils/errorHandler.js b/backend/src/utils/errorHandler.js new file mode 100644 index 0000000..ea0ac3b --- /dev/null +++ b/backend/src/utils/errorHandler.js @@ -0,0 +1,16 @@ +export const handleError = (res, error, context, statusCode = 500) => { + console.log(`Error in ${context}:`, error.message); + return res.status(statusCode).json({ message: "Internal Server Error" }); +}; + +export const handleValidationError = (res, message) => { + return res.status(400).json({ message }); +}; + +export const handleNotFoundError = (res, message) => { + return res.status(404).json({ message }); +}; + +export const handleUnauthorizedError = (res, message) => { + return res.status(403).json({ message }); +}; diff --git a/backend/src/utils/passwordUtils.js b/backend/src/utils/passwordUtils.js new file mode 100644 index 0000000..e75a0c3 --- /dev/null +++ b/backend/src/utils/passwordUtils.js @@ -0,0 +1,19 @@ +import bcrypt from "bcryptjs"; + +export const PASSWORD_REGEX = /^(?=.*[A-Z])(?=.*[!@#$%^&*()_+{}\[\]:;<>,.?~\\-]).{8,16}$/; + +export const PASSWORD_VALIDATION_MESSAGE = + "Password must be 8-16 characters, include at least one uppercase letter and one special character."; + +export const validatePassword = (password) => { + return PASSWORD_REGEX.test(password); +}; + +export const hashPassword = async (password) => { + const salt = await bcrypt.genSalt(10); + return await bcrypt.hash(password, salt); +}; + +export const comparePassword = async (password, hashedPassword) => { + return await bcrypt.compare(password, hashedPassword); +}; diff --git a/frontend/src/stores/authStore.js b/frontend/src/stores/authStore.js index 898c8b8..4939445 100644 --- a/frontend/src/stores/authStore.js +++ b/frontend/src/stores/authStore.js @@ -1,5 +1,6 @@ import { create } from 'zustand'; import { axiosInstance } from '../lib/axios.js'; +import { handleStoreError } from '../utils/storeHelpers.js'; // Auth store for managing authentication state const useAuthStore = create((set) => ({ @@ -20,10 +21,10 @@ const useAuthStore = create((set) => ({ loading: false, error: null }); - console.log(user) + console.log(user); return user; } catch (error) { - const errorMessage = error.response?.data?.message || 'Login failed'; + const errorMessage = handleStoreError(error, 'Login failed'); set({ user: null, isAuthenticated: false, @@ -67,7 +68,7 @@ const useAuthStore = create((set) => ({ set({ loading: false, error: null }); return true; } catch (error) { - const errorMessage = error.response?.data?.message || 'Password update failed'; + const errorMessage = handleStoreError(error, 'Password update failed'); set({ loading: false, error: errorMessage }); throw error; } @@ -111,7 +112,7 @@ const useAuthStore = create((set) => ({ }); return user; } catch (error) { - const errorMessage = error.response?.data?.message || 'Signup failed'; + const errorMessage = handleStoreError(error, 'Signup failed'); set({ user: null, isAuthenticated: false, diff --git a/frontend/src/stores/ratingStore.js b/frontend/src/stores/ratingStore.js index 088a740..7f9c90a 100644 --- a/frontend/src/stores/ratingStore.js +++ b/frontend/src/stores/ratingStore.js @@ -1,5 +1,6 @@ import { create } from 'zustand'; import { axiosInstance } from '../lib/axios.js'; +import { handleStoreError } from '../utils/storeHelpers.js'; const useRatingStore = create((set, get) => ({ @@ -30,7 +31,7 @@ const useRatingStore = create((set, get) => ({ set({ loading: false, error: null }); return newRating; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to submit rating'; + const errorMessage = handleStoreError(error, 'Failed to submit rating'); set({ loading: false, error: errorMessage }); throw error; } @@ -65,7 +66,7 @@ const useRatingStore = create((set, get) => ({ set({ loading: false, error: null }); return response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to update rating'; + const errorMessage = handleStoreError(error, 'Failed to update rating'); set({ loading: false, error: errorMessage }); throw error; } @@ -83,7 +84,7 @@ const useRatingStore = create((set, get) => ({ }); return response.data.ratings || response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to fetch store ratings'; + const errorMessage = handleStoreError(error, 'Failed to fetch store ratings'); set({ storeRatings: [], loading: false, @@ -112,7 +113,7 @@ const useRatingStore = create((set, get) => ({ }); return response.data.ratings || response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to fetch user ratings'; + const errorMessage = handleStoreError(error, 'Failed to fetch user ratings'); set({ userRatings: [], loading: false, diff --git a/frontend/src/stores/storeStore.js b/frontend/src/stores/storeStore.js index 96ed855..0c3571f 100644 --- a/frontend/src/stores/storeStore.js +++ b/frontend/src/stores/storeStore.js @@ -1,5 +1,6 @@ import { create } from 'zustand'; import { axiosInstance } from '../lib/axios.js'; +import { handleStoreError, applyFilters } from '../utils/storeHelpers.js'; // Store for managing store data and operations const useStoreStore = create((set, get) => ({ @@ -31,7 +32,7 @@ const useStoreStore = create((set, get) => ({ }); return stores; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to fetch stores'; + const errorMessage = handleStoreError(error, 'Failed to fetch stores'); set({ stores: [], loading: false, @@ -55,7 +56,7 @@ const useStoreStore = create((set, get) => ({ return response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to create store'; + const errorMessage = handleStoreError(error, 'Failed to create store'); set({ loading: false, error: errorMessage }); throw error; } @@ -81,23 +82,9 @@ const useStoreStore = create((set, get) => ({ filters: { name: '', email: '', address: '', role: '' } }), - getFilteredStores: () => { const { stores, searchTerm, filters } = get(); - return stores.filter(store => { - const matchesSearch = !searchTerm || - store.name?.toLowerCase().includes(searchTerm.toLowerCase()) || - store.address?.toLowerCase().includes(searchTerm.toLowerCase()) || - store.email?.toLowerCase().includes(searchTerm.toLowerCase()); - - const matchesFilters = - (!filters.name || store.name?.toLowerCase().includes(filters.name.toLowerCase())) && - (!filters.email || store.email?.toLowerCase().includes(filters.email.toLowerCase())) && - (!filters.address || store.address?.toLowerCase().includes(filters.address.toLowerCase())) && - (!filters.role || store.role === filters.role); - - return matchesSearch && matchesFilters; - }); + return applyFilters(stores, searchTerm, filters, ['name', 'address', 'email']); }, diff --git a/frontend/src/stores/userStore.js b/frontend/src/stores/userStore.js index e38f796..f514c38 100644 --- a/frontend/src/stores/userStore.js +++ b/frontend/src/stores/userStore.js @@ -1,5 +1,6 @@ import { create } from 'zustand'; import { axiosInstance } from '../lib/axios.js'; +import { handleStoreError, applyFilters } from '../utils/storeHelpers.js'; const useUserStore = create((set, get) => ({ @@ -26,7 +27,7 @@ const useUserStore = create((set, get) => ({ }); return response.data.users || response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to fetch users'; + const errorMessage = handleStoreError(error, 'Failed to fetch users'); set({ users: [], loading: false, @@ -45,7 +46,7 @@ const useUserStore = create((set, get) => ({ set({ loading: false, error: null }); return user; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to fetch user details'; + const errorMessage = handleStoreError(error, 'Failed to fetch user details'); set({ loading: false, error: errorMessage }); throw error; } @@ -65,7 +66,7 @@ const useUserStore = create((set, get) => ({ return response.data; } catch (error) { - const errorMessage = error.response?.data?.message || 'Failed to create user'; + const errorMessage = handleStoreError(error, 'Failed to create user'); set({ loading: false, error: errorMessage }); throw error; } @@ -85,23 +86,9 @@ const useUserStore = create((set, get) => ({ filters: { role: '', name: '', email: '', address: '' } }), - getFilteredUsers: () => { const { users, searchTerm, filters } = get(); - return users.filter(user => { - const matchesSearch = !searchTerm || - user.name?.toLowerCase().includes(searchTerm.toLowerCase()) || - user.email?.toLowerCase().includes(searchTerm.toLowerCase()) || - user.address?.toLowerCase().includes(searchTerm.toLowerCase()); - - const matchesFilters = - (!filters.role || user.role === filters.role) && - (!filters.name || user.name?.toLowerCase().includes(filters.name.toLowerCase())) && - (!filters.email || user.email?.toLowerCase().includes(filters.email.toLowerCase())) && - (!filters.address || user.address?.toLowerCase().includes(filters.address.toLowerCase())); - - return matchesSearch && matchesFilters; - }); + return applyFilters(users, searchTerm, filters, ['name', 'email', 'address']); }, diff --git a/frontend/src/utils/storeHelpers.js b/frontend/src/utils/storeHelpers.js new file mode 100644 index 0000000..7fe9e33 --- /dev/null +++ b/frontend/src/utils/storeHelpers.js @@ -0,0 +1,48 @@ +/** + * Common store state management utilities + */ + +// Set loading and error state +export const setLoading = (set, loading, error = null) => { + set({ loading, error }); +}; + +// Handle error with message extraction +export const handleStoreError = (error, defaultMessage) => { + return error.response?.data?.message || defaultMessage; +}; + +// Create a generic fetch handler +export const createFetchHandler = async (set, fetchFn, errorMessage) => { + set({ loading: true, error: null }); + try { + const result = await fetchFn(); + set({ loading: false, error: null }); + return result; + } catch (error) { + const errorMsg = handleStoreError(error, errorMessage); + set({ loading: false, error: errorMsg }); + throw error; + } +}; + +// Common filter logic for search and filters +export const applyFilters = (items, searchTerm, filters, searchFields) => { + return items.filter(item => { + // Apply search across specified fields + const matchesSearch = !searchTerm || searchFields.some(field => + item[field]?.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + // Apply filters + const matchesFilters = Object.entries(filters).every(([key, value]) => { + if (!value) return true; + if (typeof value === 'string') { + return item[key]?.toLowerCase().includes(value.toLowerCase()); + } + return item[key] === value; + }); + + return matchesSearch && matchesFilters; + }); +}; From 2b253db29c8e4b8eccb2e011c5bf2fb0c20d3c62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 09:00:32 +0000 Subject: [PATCH 3/3] Fix spelling typos in error messages Co-authored-by: Xsidz <146343711+Xsidz@users.noreply.github.com> --- backend/src/controllers/auth.controller.js | 4 ++-- backend/src/controllers/store.controller.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/controllers/auth.controller.js b/backend/src/controllers/auth.controller.js index 6d7d340..07161fc 100644 --- a/backend/src/controllers/auth.controller.js +++ b/backend/src/controllers/auth.controller.js @@ -69,11 +69,11 @@ export const logIn = async (req, res) => { console.log(row); const user = row[0]; if (!user) { - return res.status(400).json({ message: "Inavlid Credentials" }); + return res.status(400).json({ message: "Invalid Credentials" }); } const isPassCorrect = await comparePassword(password, user.password); if (!isPassCorrect) { - return res.status(400).json({ message: "Inavlid Credentials" }); + return res.status(400).json({ message: "Invalid Credentials" }); } gennToken(user.id, res); diff --git a/backend/src/controllers/store.controller.js b/backend/src/controllers/store.controller.js index bec8f32..99c0771 100644 --- a/backend/src/controllers/store.controller.js +++ b/backend/src/controllers/store.controller.js @@ -12,7 +12,7 @@ export const addStore = async (req, res) => { const newStore = await storeModel.addStore({ name, email, address, owner_id }); console.log(newStore); - res.status(201).json({ message: "New Store added Successfuly !!" }); + res.status(201).json({ message: "New Store added Successfully !!" }); } catch (error) { return handleError(res, error, "addStore controller"); }