diff --git a/client/src/pages/user/Profile.jsx b/client/src/pages/user/Profile.jsx index f5acae4..94f0eaa 100644 --- a/client/src/pages/user/Profile.jsx +++ b/client/src/pages/user/Profile.jsx @@ -5,7 +5,7 @@ import BottomBar from '../../components/constants/Bottombar'; import Navbar from '../../components/constants/Navbar'; import { useNavigate } from 'react-router-dom'; import { useGetPostsByUserQuery } from '../../redux/posts/postApi'; -import { useUpdatePasswordMutation, useUpdateFullNameMutation, useLogoutMutation } from '../../redux/apiSlice'; +import { useUpdatePasswordMutation, useUpdateFullNameMutation, useUpdateUPIMutation, useLogoutMutation } from '../../redux/apiSlice'; import { useGetMyApplicationQuery } from '../../redux/opportunities/opportunity-api'; import { setCurrentUser } from '../../redux/user/userSlice'; import InfiniteScroll from 'react-infinite-scroll-component'; @@ -16,9 +16,11 @@ const Profile = () => { const navigate = useNavigate(); const dispatch = useDispatch(); const [password, setPassword] = useState(''); + const [upi, setUpi] = useState(''); const [activeTab, setActiveTab] = useState('posts'); const [updatePassword, { isLoading: isUpdating, error: updateError }] = useUpdatePasswordMutation(); const [updateFullName, { isLoading: isUpdatingName }] = useUpdateFullNameMutation(); + const [updateUPI, { isLoading: isUpdatingUPI }] = useUpdateUPIMutation(); // Name editing state const [isEditingName, setIsEditingName] = useState(false); @@ -54,6 +56,20 @@ const Profile = () => { } }; + const handleUpdateUPI = async (e) => { + e.preventDefault(); + if (!upi) { + alert('Please enter your UPI ID'); + return; + } + try { + await updateUPI({ upi }).unwrap(); + alert('UPI updated successfully'); + } catch (error) { + alert('Failed to update UPI:', error); + } + }; + const handleLogout = async (e) => { e.preventDefault(); try { @@ -154,15 +170,24 @@ const Profile = () => { + + {/* ── Password Section ── */} setPassword(e.target.value)} /> -

NOTE: Passwords are hashed and then stored. You can change it here.

-
- - -
- {updateError &&
Error: {updateError.data?.message || 'Failed to update password.'}
} +

NOTE: Passwords are hashed and then stored. You can change it here.

+ + {updateError &&
Error: {updateError.data?.message || 'Failed to update password.'}
} + + {/* ── UPI Section ── */} + setUpi(e.target.value)} /> +

Used for receiving payments for completed opportunities.

+ + + {/* ── Logout ── */} + {/* ── Tabs ─────────────────────────────────────────────────────────── */}
diff --git a/client/src/redux/apiSlice.js b/client/src/redux/apiSlice.js index 8579f1b..9fcb241 100644 --- a/client/src/redux/apiSlice.js +++ b/client/src/redux/apiSlice.js @@ -26,10 +26,10 @@ export const authApi = createApi({ }), // UpdatePassword updatePassword: builder.mutation({ - query: (newPassword) => ({ + query: ({password}) => ({ url: `/auth/updatepassword`, method: 'POST', - body: { newPassword }, // Correctly wrapping in an object + body: { newPassword: password }, // Correctly wrapping in an object }), }), // UpdateFullName @@ -37,7 +37,15 @@ export const authApi = createApi({ query: (fullname) => ({ url: `/auth/updatefullname`, method: 'POST', - body: { fullname }, + body: { fullname }, // Correctly wrapping in an object + }), + }), + // UpdateUPI + updateUPI: builder.mutation({ + query: ({ upi }) => ({ + url: `/auth/updateupi`, + method: 'POST', + body: { upi }, }), }), logout: builder.mutation({ @@ -47,8 +55,13 @@ export const authApi = createApi({ }), }), }), - // Define the middleware to handle the response and set cookies - }); -export const { useSignUpMutation, useSignInMutation, useUpdatePasswordMutation,useUpdateFullNameMutation, useLogoutMutation } = authApi; +export const { + useSignUpMutation, + useSignInMutation, + useUpdatePasswordMutation, + useUpdateFullNameMutation, + useUpdateUPIMutation, + useLogoutMutation, +} = authApi; \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index 06a1509..7297ee9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,6 +3,9 @@ import js from "@eslint/js"; import importPlugin from "eslint-plugin-import"; export default [ + { + ignores: ["client/**","api/**"] +}, js.configs.recommended, { files: ["**/*.js", "**/*.mjs"], @@ -26,11 +29,12 @@ export default [ "globals", "@eslint/js", "eslint-plugin-import" + ] }, rules: { "no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], - "import/no-unresolved": "error", + "import/no-unresolved": ["error" , {ignore: ["uuid"]}], "import/named": "error", "import/default": "error", "import/namespace": "error", @@ -42,5 +46,6 @@ export default [ rules: { "import/no-unresolved": "off", }, - }, + } + ]; diff --git a/src/modules/auth/auth.controller.js b/src/modules/auth/auth.controller.js index 096367c..294120d 100644 --- a/src/modules/auth/auth.controller.js +++ b/src/modules/auth/auth.controller.js @@ -47,7 +47,7 @@ export const logout = asyncHandler(async (req, res) => { * POST /api/auth/updatepassword */ export const updatePassword = asyncHandler(async (req, res) => { - const result = await authService.updatePassword(req.body.newPassword); + const result = await authService.updatePassword(req.body.newPassword, req.user.id); res.status(200).json(ApiResponses.success(result, 'Password updated successfully')); }); @@ -56,7 +56,7 @@ export const updatePassword = asyncHandler(async (req, res) => { * POST /api/auth/updatefullname */ export const updateFullName = asyncHandler(async (req, res) => { - const result = await authService.updateFullName(req.body.fullname); + const result = await authService.updateFullName(req.body.fullname , req.user.id); res.status(200).json(ApiResponses.success(result, 'Full Name updated successfully')); }); @@ -65,7 +65,7 @@ export const updateFullName = asyncHandler(async (req, res) => { * POST /api/auth/updateupi */ export const updateUPI = asyncHandler(async (req, res) => { - const result = await authService.updateUPI(req.body.upi); + const result = await authService.updateUPI(req.body.upi , req.user.id); res.status(200).json(ApiResponses.success(result, 'UPI updated successfully')); }); diff --git a/src/modules/auth/auth.routes.js b/src/modules/auth/auth.routes.js index e91f630..df32c64 100644 --- a/src/modules/auth/auth.routes.js +++ b/src/modules/auth/auth.routes.js @@ -1,5 +1,5 @@ import express from 'express'; -import { validate, isAuthenticated, ipLimiter } from '../../shared/middleware/index.js'; +import { validate, isAuthenticated, ipLimiter, verifyToken } from '../../shared/middleware/index.js'; import { handleSignUp, handleSignIn, @@ -33,13 +33,13 @@ router.post('/signup', ipLimiter, validate(signUpSchema), handleSignUp); router.post('/signin', ipLimiter, validate(signInSchema), handleSignIn); // Update password - with validation -router.post('/updatepassword', validate(updatePasswordSchema), updatePassword); +router.post('/updatepassword',verifyToken, validate(updatePasswordSchema), updatePassword); // Update full name - with validation -router.post('/updatefullname', validate(updateFullNameSchema), updateFullName); +router.post('/updatefullname',verifyToken, validate(updateFullNameSchema), updateFullName); // Update UPI - with validation -router.post('/updateupi', validate(updateUPISchema), updateUPI); +router.post('/updateupi',verifyToken, validate(updateUPISchema), updateUPI); // Logout - requires authentication router.post('/logout', isAuthenticated, logout); diff --git a/src/modules/auth/auth.service.js b/src/modules/auth/auth.service.js index 5b17aba..596c210 100644 --- a/src/modules/auth/auth.service.js +++ b/src/modules/auth/auth.service.js @@ -95,9 +95,9 @@ export const authService = { * @param {string} newPassword - New password * @returns {Promise} Success message */ - async updatePassword(newPassword) { - // Find first user (this seems like a development function) - const user = await User.findOne({}); + async updatePassword(newPassword, userId) { + // Find user by ID + const user = await User.findById(userId); if (!user) { throw ApiErrors.notFound('User not found'); } @@ -115,9 +115,9 @@ export const authService = { * @param {string} fullname - New full name * @returns {Promise} Success message */ - async updateFullName(fullname) { - // Find first user (this seems like a development function) - const user = await User.findOne({}); + async updateFullName(fullname, userId) { + // Find user by ID + const user = await User.findById(userId); if (!user) { throw ApiErrors.notFound('User not found'); } @@ -133,9 +133,9 @@ export const authService = { * @param {string} upi - New UPI * @returns {Promise} Success message */ - async updateUPI(upi) { - // Find first user (this seems like a development function) - const user = await User.findOne({}); + async updateUPI(upi, userId) { + // Find user by ID + const user = await User.findById(userId); if (!user) { throw ApiErrors.notFound('User not found'); } diff --git a/src/modules/payments/payment.service.js b/src/modules/payments/payment.service.js index d241b37..9d87b57 100644 --- a/src/modules/payments/payment.service.js +++ b/src/modules/payments/payment.service.js @@ -35,7 +35,7 @@ export const paymentService = { let paymentLevel = '1'; // by default level is 1 for 1st payment - if (Boolean(plainObject.paymentStatus.firstPayment.status)) { + if ((plainObject.paymentStatus.firstPayment.status)) { paymentLevel = '2'; // if 1st payment true, then it is for second payment }