diff --git a/.prettierrc b/.prettierrc index 0930e3a..635543c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,7 +3,7 @@ "singleQuote": true, "tabWidth": 2, "useTabs": true, - "printWidth": 120, + "printWidth": 150, "trailingComma": "none", "bracketSpacing": true, "arrowParens": "always", diff --git a/client/README.md b/client/README.md index 7f741a6..7bf3ec9 100644 --- a/client/README.md +++ b/client/README.md @@ -33,21 +33,19 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d **Note: this is a one-way operation. Once you `eject`, you can't go back!** -If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will -remove the single build dependency from your project. +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build +dependency from your project. -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right -into your project so you have full control over them. All of the commands except `eject` will still work, but they will -point to the copied scripts so you can tweak them. At this point you're on your own. +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have +full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this +point you're on your own. -You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you -shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't -customize it when you are ready for it. +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this +feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. ## Learn More -You can learn more in the -[Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). diff --git a/client/src/components/AuthForms/AuthenticationForm.jsx b/client/src/components/AuthForms/AuthenticationForm.jsx index 9551fda..21a88f1 100644 --- a/client/src/components/AuthForms/AuthenticationForm.jsx +++ b/client/src/components/AuthForms/AuthenticationForm.jsx @@ -58,14 +58,11 @@ const AuthenticationForm = () => { }; const handleSuccess = (isSignIn, res) => { - toast.success( - , - { - autoClose: 4000, - closeOnClick: true, - pauseOnHover: true - } - ); + toast.success(, { + autoClose: 4000, + closeOnClick: true, + pauseOnHover: true + }); if (isSignIn) { localStorage.setItem('token', res.data.data.token); navigate('/'); @@ -75,14 +72,11 @@ const AuthenticationForm = () => { }; const handleError = (isSignIn, err) => { - toast.error( - , - { - autoClose: 4000, - closeOnClick: true, - pauseOnHover: true - } - ); + toast.error(, { + autoClose: 4000, + closeOnClick: true, + pauseOnHover: true + }); }; const handleEmailChange = (e) => { @@ -115,24 +109,14 @@ const AuthenticationForm = () => {
- + @student.nitw.ac.in
- setPassword(e.target.value)} - value={password} - /> + setPassword(e.target.value)} value={password} /> @@ -198,40 +182,16 @@ const AuthenticationForm = () => { }} step="0.01" /> - setPgPercentage(e.target.value)} - disabled - /> + setPgPercentage(e.target.value)} disabled />
- setUgCgpa(e.target.value)} - value={ugCgpa} - step="0.01" - /> - setUgPercentage(e.target.value)} - value={ugPercentage} - step="0.01" - /> + setUgCgpa(e.target.value)} value={ugCgpa} step="0.01" /> + setUgPercentage(e.target.value)} value={ugPercentage} step="0.01" />
- setHscCgpa(e.target.value)} - value={hscCgpa} - step="0.01" - /> + setHscCgpa(e.target.value)} value={hscCgpa} step="0.01" /> {
- setSscCgpa(e.target.value)} - value={sscCgpa} - step="0.01" - /> + setSscCgpa(e.target.value)} value={sscCgpa} step="0.01" /> { onChange={(e) => setTotalGapInAcademics(e.target.value)} /> - setBacklogs(e.target.value)} - /> + setBacklogs(e.target.value)} />
diff --git a/client/src/components/AuthForms/ForgetPassword.jsx b/client/src/components/AuthForms/ForgetPassword.jsx index d55cbbb..d0189c5 100644 --- a/client/src/components/AuthForms/ForgetPassword.jsx +++ b/client/src/components/AuthForms/ForgetPassword.jsx @@ -87,13 +87,7 @@ const ForgetPassword = ({ isFormOpen, onCloseAction }) => { onCloseAction(); }} onConfirm={() => onConfirmAction()} - message={ - counter === 0 - ? 'Enter your College Email ID!!' - : counter === 1 - ? 'Check your email for OTP' - : 'Enter your new password' - } + message={counter === 0 ? 'Enter your College Email ID!!' : counter === 1 ? 'Check your email for OTP' : 'Enter your new password'} buttonTitle={counter === 0 ? 'Send Email' : counter === 1 ? 'Verify OTP' : 'Reset Password'} HasInput={() => (
diff --git a/client/src/components/Company/CompanyForm.jsx b/client/src/components/Company/CompanyForm.jsx index 56c5d52..39fc86e 100644 --- a/client/src/components/Company/CompanyForm.jsx +++ b/client/src/components/Company/CompanyForm.jsx @@ -92,10 +92,7 @@ const CompanyForm = ({ actionFunc, handleFormClose, initialData, isAdd }) => { }; try { const res = isAdd ? await actionFunc(newCompany) : await actionFunc(initialData._id, newCompany); - if (res.status === 200) - toast.success( - - ); + if (res.status === 200) toast.success(); else toast.error(); handleFormClose(true); } catch (error) { @@ -122,12 +119,7 @@ const CompanyForm = ({ actionFunc, handleFormClose, initialData, isAdd }) => {
- handleChange('status', e.target.value)}> diff --git a/client/src/components/Company/CompanyTable.jsx b/client/src/components/Company/CompanyTable.jsx index 10e4c67..3ceb87c 100644 --- a/client/src/components/Company/CompanyTable.jsx +++ b/client/src/components/Company/CompanyTable.jsx @@ -15,7 +15,7 @@ const CompanyTable = () => { const [companyData, setCompanyData] = useState(null); const [isFormOpen, setIsFormOpen] = useState(false); const [isAdd, setIsAdd] = useState(false); - const userRole = getUser().role; + const user = getUser(); const [isModalOpen, setIsModalOpen] = useState(false); const [companyToDelete, setCompanyToDelete] = useState(null); const closeModal = () => setIsModalOpen(false); @@ -37,9 +37,7 @@ const CompanyTable = () => { const onConfirmDelete = async () => { try { await deleteCompany(companyToDelete.id); - toast.success( - - ); + toast.success(); setIsModalOpen(false); fetchData(); } catch (error) { @@ -54,12 +52,14 @@ const CompanyTable = () => { setIsFormOpen(true); }; - const generateColumn = (field, headerName, width, sortable = true, resizable = true) => ({ + const generateColumn = (field, headerName, width, pinned = null, sortable = true, resizable = true, cellRenderer = null) => ({ field, headerName, width, + pinned, sortable, - resizable + resizable, + cellRenderer }); const generateNestedColumn = (headerName, children) => ({ @@ -67,14 +67,6 @@ const CompanyTable = () => { children }); - const generateDateColumn = (field, headerName, width, sortable = true, resizable = true) => ({ - ...generateColumn(field, headerName, width, sortable, resizable), - valueFormatter: (params) => - params.value - ? new Date(params.value).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric' }) - : '' - }); - const formatCutoff = (cutoff) => (cutoff.cgpa ? `${cutoff.cgpa} CGPA` : `${cutoff.percentage}%`); const deleteButtonRenderer = (params) => { @@ -93,49 +85,35 @@ const CompanyTable = () => { ); }; - const actionColumn = (actionName, actionButtonRenderer) => { - return { - ...generateColumn(null, actionName, 55, false, false), - pinned: 'left', - cellRenderer: actionButtonRenderer, - initialHide: userRole !== 'admin' && userRole !== 'placementCoordinator' - }; - }; + const actionsColumn = generateNestedColumn('Actions', [ + generateColumn(null, 'Delete', 55, 'left', false, false, deleteButtonRenderer), + generateColumn(null, 'Edit', 55, 'left', false, false, editButtonRenderer) + ]); const columnDefinitions = [ - generateNestedColumn('Actions', [ - actionColumn('Del', deleteButtonRenderer), - actionColumn('Edit', editButtonRenderer) - ]), - { - ...generateColumn('name', 'Name', 150), - pinned: 'left' - }, - generateColumn('status', 'Status', 100, false), + ...(user.role === 'admin' || user.role === 'placementCoordinator' ? [actionsColumn] : []), + generateColumn('name', 'Name', 150, 'left'), + generateColumn('status', 'Status', 100, null, false), generateColumn('typeOfOffer', 'Offer', 90), generateColumn('profile', 'Profile', 150), generateColumn('profileCategory', 'Category', 100), generateColumn('interviewShortlist', 'Shortlists', 120), generateColumn('selectedStudents', 'Selects', 100), - generateDateColumn('dateOfOffer', 'Offer Date', 125), + generateColumn('dateOfOffer', 'Offer Date', 125, null, true, false, (params) => + params.value ? new Date(params.value).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric' }) : '' + ), generateColumn('locations', 'Locations', 130), generateNestedColumn('CTC (LPA)', [ - { - ...generateColumn('ctc', 'CTC', 80, true, false), - valueFormatter: (params) => params.value.toFixed(2) - }, - { - ...generateColumn('ctcBase', 'Base', 80, true, false), - valueFormatter: (params) => params.value.toFixed(2) - } + generateColumn('ctc', 'CTC', 80, null, true, false, (params) => params.value.toFixed(2)), + generateColumn('ctcBase', 'Base', 80, null, true, false, (params) => params.value.toFixed(2)) ]), generateNestedColumn('Cutoffs', [ - generateColumn('cutoff_pg', 'PG', 80, false, false), - generateColumn('cutoff_ug', 'UG', 80, false, false), - generateColumn('cutoff_12', '12', 80, false, false), - generateColumn('cutoff_10', '10', 80, false, false) + generateColumn('cutoff_pg', 'PG', 80, null, false, false), + generateColumn('cutoff_ug', 'UG', 80, null, false, false), + generateColumn('cutoff_12', '12', 80, null, false, false), + generateColumn('cutoff_10', '10', 80, null, false, false) ]), - generateColumn('bond', 'Bond', 60, false, false) + generateColumn('bond', 'Bond', 60, null, false, false) ]; const mapCompanyData = (company) => ({ @@ -165,21 +143,18 @@ const CompanyTable = () => { const renderCompanyForm = () => { if (!isFormOpen) return null; return ReactDOM.createPortal( - , + , document.getElementById('form-root') ); }; return ( <> - + {(user.role === 'admin' || user.role === 'placementCoordinator') && ( + + )} {renderCompanyForm()} {
{navItems.map((item) => ( - (isActive ? classes.active : undefined)} - aria-label={item.label} - key={item.to} - > + (isActive ? classes.active : undefined)} aria-label={item.label} key={item.to}> {item.icon} ))} diff --git a/client/src/components/Student/StudentTable.jsx b/client/src/components/Student/StudentTable.jsx index d3d5aaf..b569256 100644 --- a/client/src/components/Student/StudentTable.jsx +++ b/client/src/components/Student/StudentTable.jsx @@ -68,10 +68,7 @@ const StudentTable = () => { const verifyButtonRenderer = (params) => { return ( - ); @@ -101,40 +98,34 @@ const StudentTable = () => { }; const modelRenderer = (isModalOpen, closeModal, onConfirm, message, buttonTitle) => { - return ( - closeModal()} - onConfirm={onConfirm} - message={message} - buttonTitle={buttonTitle} - /> - ); + return closeModal()} onConfirm={onConfirm} message={message} buttonTitle={buttonTitle} />; }; const fetchData = useCallback(async () => { try { const response = await getStudents(); response.data.users.forEach((student) => { - if (student.role === 'student') student.role = 'Student'; - else if (student.role === 'placementCoordinator') student.role = 'PC'; - else if (student.role === 'admin') student.role = 'Admin'; + if (student.placed === true) { + student.placed = student.placedAt.company; + student.ctc = student.placedAt.ctc; + student.ctcBase = student.placedAt.ctcBreakup.base; + student.location = student.placedAt.location; + } else if (student.placed === false) { + student.placed = 'Not Placed'; + student.ctc = 0; + student.ctcBase = 0; + student.location = 'N/A'; + } + student.id = student._id; }); + response.data.users.sort((a, b) => a.rollNo.localeCompare(b.rollNo)); setStudents(response.data.users); } catch (error) { console.error('Error fetching students:', error); } }, []); - const generateColumn = ( - field, - headerName, - width, - pinned = null, - sortable = true, - resizable = true, - cellRenderer = null - ) => ({ + const generateColumn = (field, headerName, width, pinned = null, sortable = true, resizable = true, cellRenderer = null) => ({ field, headerName, width, @@ -156,22 +147,45 @@ const StudentTable = () => { const academicColumn = [ generateNestedColumn('Grades', [ - generateNestedColumn('PG', [generateColumn('pg.cgpa', 'CGPA', 85), generateColumn('pg.percentage', '%', 85)]), - generateNestedColumn('UG', [generateColumn('ug.cgpa', 'CGPA', 85), generateColumn('ug.percentage', '%', 85)]), - generateNestedColumn('HSC', [generateColumn('hsc.cgpa', 'CGPA', 85), generateColumn('hsc.percentage', '%', 85)]), - generateNestedColumn('SSC', [generateColumn('ssc.cgpa', 'CGPA', 85), generateColumn('ssc.percentage', '%', 85)]) + generateNestedColumn('PG', [ + generateColumn('pg.cgpa', 'CGPA', 85, null, true, true, (params) => params.value.toFixed(2)), + generateColumn('pg.percentage', '%', 85, null, true, true, (params) => params.value.toFixed(2)) + ]), + generateNestedColumn('UG', [ + generateColumn('ug.cgpa', 'CGPA', 85, null, true, true, (params) => params.value.toFixed(2)), + generateColumn('ug.percentage', '%', 85, null, true, true, (params) => params.value.toFixed(2)) + ]), + generateNestedColumn('HSC', [ + generateColumn('hsc.cgpa', 'CGPA', 85, null, true, true, (params) => params.value.toFixed(2)), + generateColumn('hsc.percentage', '%', 85, null, true, true, (params) => params.value.toFixed(2)) + ]), + generateNestedColumn('SSC', [ + generateColumn('ssc.cgpa', 'CGPA', 85, null, true, true, (params) => params.value.toFixed(2)), + generateColumn('ssc.percentage', '%', 85, null, true, true, (params) => params.value.toFixed(2)) + ]) ]), generateColumn('totalGapInAcademics', 'Gap', 75), generateColumn('backlogs', 'Backlogs', 85) ]; + const roleFormatter = (params) => { + return params.value === 'student' ? 'Student' : params.value === 'placementCoordinator' ? 'PC' : 'Admin'; + }; + const columnDefinitions = [ ...(user.role === 'admin' || user.role === 'placementCoordinator' ? [actionsColumn] : []), - generateColumn('role', 'Role', 100, 'left', false, false, user.role === 'admin' ? roleDropdownRenderer : null), - generateColumn('rollNo', 'Roll No', 100, 'left'), + generateColumn('role', 'Role', 100, 'left', false, false, user.role === 'admin' ? roleDropdownRenderer : roleFormatter), generateColumn('name', 'Name', 130, 'left'), - generateColumn('email', 'Email', 250), - generateColumn('placed', 'Placed?', 80), + generateColumn('rollNo', 'Roll No', 100), + generateColumn('email', 'Email', 225), + generateNestedColumn('Placement Details', [ + generateColumn('placed', 'Company', 100, null, true, true), + generateNestedColumn('CTC (LPA)', [ + generateColumn('ctc', 'CTC', 80, null, true, false, (params) => params.value.toFixed(2)), + generateColumn('ctcBase', 'Base', 80, null, true, false, (params) => params.value.toFixed(2)) + ]), + generateColumn('location', 'location', 100, null, true, true) + ]), ...(user.role === 'admin' || user.role === 'placementCoordinator' ? academicColumn : []) ]; @@ -187,13 +201,7 @@ const StudentTable = () => { selectedStudent.isVerified ? 'Unverify' : 'Verify' )} {selectedStudentDelete && - modelRenderer( - isModalOpen, - closeModal, - onConfirmDeleteStudent, - `Are you sure you want to delete ${selectedStudentDelete.name}?`, - 'Delete' - )} + modelRenderer(isModalOpen, closeModal, onConfirmDeleteStudent, `Are you sure you want to delete ${selectedStudentDelete.name}?`, 'Delete')} ); }; diff --git a/client/src/pages/Stats/Stats.jsx b/client/src/pages/Stats/Stats.jsx index f771121..6176e23 100644 --- a/client/src/pages/Stats/Stats.jsx +++ b/client/src/pages/Stats/Stats.jsx @@ -23,11 +23,7 @@ const Stats = () => { const fetchData = useCallback(async () => { try { - const [ctcResponse, companyResponse, studentResponse] = await Promise.all([ - getCtcStats(), - getCompanyStats(), - getStudentStats() - ]); + const [ctcResponse, companyResponse, studentResponse] = await Promise.all([getCtcStats(), getCompanyStats(), getStudentStats()]); const ctcData = ctcResponse.data; ctcData.highestCTCOffered = ctcData.highestCTCOffered.toFixed(2); @@ -36,10 +32,7 @@ const Stats = () => { ctcData.totalPlacedStudentsCTC = ctcData.totalPlacedStudentsCTC.toFixed(2); const studentData = studentResponse.data; - studentData.placementPercentage = ( - (studentData.totalPlacedStudents * 100) / - studentData.totalEligibleStudents - ).toFixed(2); + studentData.placementPercentage = ((studentData.totalPlacedStudents * 100) / studentData.totalEligibleStudents).toFixed(2); setCtcStats(ctcData); setCompanyStats(companyResponse.data); @@ -85,10 +78,7 @@ const Stats = () => { } /> - {ctcStats.totalPlacedStudentsCTC} Lakhs} - /> + {ctcStats.totalPlacedStudentsCTC} Lakhs} /> {

Company Stats

- + @@ -121,10 +108,7 @@ const Stats = () => { - {studentStats.placementPercentage} %} - /> + {studentStats.placementPercentage} %} /> diff --git a/server/controllers/authController.js b/server/controllers/authController.js index 5b6a241..43465dd 100644 --- a/server/controllers/authController.js +++ b/server/controllers/authController.js @@ -24,9 +24,7 @@ exports.postSignup = async (req, res) => { logger.info(`New user created: ${user.email}`); res.status(201).json({ - messages: [ - 'Reach out to the admin to verify your account. You will be able to login once your account is verified.' - ] + messages: ['Reach out to the admin to verify your account. You will be able to login once your account is verified.'] }); } catch (error) { logger.error(error); @@ -39,13 +37,11 @@ exports.getLogin = async (req, res) => { const { email, password } = req.body; if (!email || !password) return res.status(400).json({ status: false, errors: ['Email and Password required'] }); - if (!email.endsWith('@student.nitw.ac.in')) - return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); + if (!email.endsWith('@student.nitw.ac.in')) return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); const user = await User.findOne({ email }); if (!user) return res.status(401).json({ status: false, errors: ['User Not Found'] }); - if (!user.isVerified) - return res.status(401).json({ status: false, errors: ['User Not Verified!! Please Contact Admin!!'] }); + if (!user.isVerified) return res.status(401).json({ status: false, errors: ['User Not Verified!! Please Contact Admin!!'] }); const passwordMatch = await bcrypt.compare(password, user.password); if (!passwordMatch) return res.status(401).json({ status: false, errors: ['Incorrect Password'] }); @@ -85,8 +81,7 @@ exports.postVerifyEmail = async (req, res) => { // Rest of the code remains unchanged if (!email) return res.status(400).json({ status: false, errors: ['Email required'] }); - if (!email.endsWith('@student.nitw.ac.in')) - return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); + if (!email.endsWith('@student.nitw.ac.in')) return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); const user = await User.findOne({ email }); if (!user) return res.status(401).json({ status: false, errors: ['User Not Found'] }); @@ -136,8 +131,7 @@ exports.postVerifyOTP = async (req, res) => { const { email, otp } = req.body; if (!email || !otp) return res.status(400).json({ status: false, errors: ['Email and OTP required'] }); - if (!email.endsWith('@student.nitw.ac.in')) - return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); + if (!email.endsWith('@student.nitw.ac.in')) return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); const user = await User.findOne({ email }); const existingOtp = await Otp.findOne({ email }); @@ -169,8 +163,7 @@ exports.postResetPassword = async (req, res) => { try { const { email, otp, newPassword } = req.body; if (!email || !newPassword) return res.status(400).json({ status: false, errors: ['Email and Password required'] }); - if (!email.endsWith('@student.nitw.ac.in')) - return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); + if (!email.endsWith('@student.nitw.ac.in')) return res.status(400).json({ status: false, errors: ['Enter a valid NITW email'] }); const user = await User.findOne({ email }); if (!user) return res.status(401).json({ status: false, errors: ['User Not Found'] }); @@ -183,9 +176,7 @@ exports.postResetPassword = async (req, res) => { if (newPassword.length < 6 || !/[a-z]/.test(newPassword) || !/[A-Z]/.test(newPassword) || !/\d/.test(newPassword)) return res.status(401).json({ status: false, - errors: [ - 'Password must be atleast 6 characters long and contain atleast one uppercase, one lowercase and one numeric character.' - ] + errors: ['Password must be atleast 6 characters long and contain atleast one uppercase, one lowercase and one numeric character.'] }); // Check OTP expiry diff --git a/server/controllers/statsController.js b/server/controllers/statsController.js index 69f5f14..aa96d32 100644 --- a/server/controllers/statsController.js +++ b/server/controllers/statsController.js @@ -4,38 +4,26 @@ const User = require('../models/User'); const filterValidCompanies = (companies) => companies.filter((company) => company.status !== 'cancelled'); -const getTotalCompaniesByStatus = (companies, status) => - companies.filter((company) => company.status === status).length; +const getTotalCompaniesByStatus = (companies, status) => companies.filter((company) => company.status === status).length; const getTotalCompaniesByProfileCategory = (companies, profileCategory) => companies.filter((company) => company.profileCategory === profileCategory).length; const calculateTotalPlacedStudents = (companies) => - companies.reduce( - (acc, company) => (company.selectedStudentsRollNo[0] !== '' ? acc + company.selectedStudentsRollNo.length : acc), - 0 - ); + companies.reduce((acc, company) => (company.selectedStudentsRollNo[0] !== '' ? acc + company.selectedStudentsRollNo.length : acc), 0); const calculateTotalPlacedStudentsCTC = (companies) => - companies.reduce( - (acc, company) => - company.selectedStudentsRollNo[0] !== '' ? acc + company.selectedStudentsRollNo.length * company.ctc : acc, - 0 - ); + companies.reduce((acc, company) => (company.selectedStudentsRollNo[0] !== '' ? acc + company.selectedStudentsRollNo.length * company.ctc : acc), 0); const getHighestCTC = (companies) => Math.max(...companies.map((company) => company.ctc)); -const getHighestCTCPlaced = (companies) => - Math.max(...companies.map((company) => (company.selectedStudentsRollNo[0] !== '' ? company.ctc : 0))); +const getHighestCTCPlaced = (companies) => Math.max(...companies.map((company) => (company.selectedStudentsRollNo[0] !== '' ? company.ctc : 0))); -const getHighestCTCCompany = (companies, highestCTC) => - companies.find((company) => (company.ctc === highestCTC ? company : '')); +const getHighestCTCCompany = (companies, highestCTC) => companies.find((company) => (company.ctc === highestCTC ? company : '')); const getHighestCTCStudent = (students, companies, highestCTCPlacedCompany) => students.find((student) => - companies.find( - (company) => company.name === highestCTCPlacedCompany && company.selectedStudentsRollNo.includes(student.rollNo) - ) + companies.find((company) => company.name === highestCTCPlacedCompany && company.selectedStudentsRollNo.includes(student.rollNo)) ); exports.getCTCStats = async (req, res) => { diff --git a/server/controllers/userController.js b/server/controllers/userController.js index 1316d6d..68c8f0a 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -6,13 +6,21 @@ const { isValidObjectId } = require('mongoose'); // View all users exports.viewAllUsers = async (req, res) => { try { - const users = await User.find({}); + const users = req.user.role === 'student' ? await User.find({ isVerified: true }) : await User.find(); if (!users) { return res.status(404).json({ message: 'No users found' }); } logger.info(`All users Viewed`); users.forEach((user) => { user.password = null; + if (req.user.role === 'student') { + user.pg = null; + user.ug = null; + user.hsc = null; + user.ssc = null; + user.backlogs = null; + user.totalGapInAcademics = null; + } }); res.status(200).json({ users }); } catch (error) { diff --git a/server/routes/companyRoutes.js b/server/routes/companyRoutes.js index f4e9fd6..d76be0d 100644 --- a/server/routes/companyRoutes.js +++ b/server/routes/companyRoutes.js @@ -5,46 +5,18 @@ const companyController = require('../controllers/companyController'); const limiter = require('../utils/limiter'); // Add Company -router.post( - '/add', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - companyController.postAddCompany -); +router.post('/add', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, companyController.postAddCompany); // Update Company with rate limiting -router.put( - '/update/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - companyController.putUpdateCompany -); +router.put('/update/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, companyController.putUpdateCompany); // Delete Company with rate limiting -router.delete( - '/delete/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - companyController.deleteCompany -); +router.delete('/delete/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, companyController.deleteCompany); // View All Companies without rate limiting -router.get( - '/view', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator', 'student']), - companyController.getViewCompany -); +router.get('/view', authenticateUser, checkUserRole(['admin', 'placementCoordinator', 'student']), companyController.getViewCompany); // View Company by ID without rate limiting -router.get( - '/view/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator', 'student']), - companyController.getViewCompanyById -); +router.get('/view/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator', 'student']), companyController.getViewCompanyById); module.exports = router; diff --git a/server/routes/userRoutes.js b/server/routes/userRoutes.js index 63eb004..400eaa8 100644 --- a/server/routes/userRoutes.js +++ b/server/routes/userRoutes.js @@ -5,44 +5,21 @@ const userController = require('../controllers/userController'); const limiter = require('../utils/limiter'); // View all users without rate limiting -router.get('/view', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), userController.viewAllUsers); +router.get('/view', authenticateUser, checkUserRole(['student', 'admin', 'placementCoordinator']), userController.viewAllUsers); // View a single user by ID with rate limiting -router.get( - '/view/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - userController.viewSingleUser -); +router.get('/view/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), userController.viewSingleUser); // Update a User with rate limiting -router.put( - '/update/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - userController.updateUser -); +router.put('/update/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, userController.updateUser); // Update Verification Status of a User with rate limiting -router.put( - '/verify/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - userController.verify -); +router.put('/verify/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, userController.verify); // Update Role of a User with rate limiting router.put('/role/:id', authenticateUser, checkUserRole(['admin']), limiter, userController.updateRole); // Delete a User with rate limiting -router.delete( - '/delete/:id', - authenticateUser, - checkUserRole(['admin', 'placementCoordinator']), - limiter, - userController.deleteUser -); +router.delete('/delete/:id', authenticateUser, checkUserRole(['admin', 'placementCoordinator']), limiter, userController.deleteUser); module.exports = router; diff --git a/server/utils/validateUser.js b/server/utils/validateUser.js index 957279e..e78d2b8 100644 --- a/server/utils/validateUser.js +++ b/server/utils/validateUser.js @@ -2,15 +2,8 @@ const validateFields = (user) => { const errorMessages = []; if (!user.name) errorMessages.push('Name is required.'); if (!user.email.endsWith('@student.nitw.ac.in')) errorMessages.push('Enter a valid NITW email.'); - if ( - user.password.length < 6 || - !/[a-z]/.test(user.password) || - !/[A-Z]/.test(user.password) || - !/\d/.test(user.password) - ) - errorMessages.push( - 'Password must be atleast 6 characters long and contain atleast one uppercase, one lowercase and one numeric character.' - ); + if (user.password.length < 6 || !/[a-z]/.test(user.password) || !/[A-Z]/.test(user.password) || !/\d/.test(user.password)) + errorMessages.push('Password must be atleast 6 characters long and contain atleast one uppercase, one lowercase and one numeric character.'); if (!user.rollNo.match(/^\d{2}MCF1R\d{2,}$/)) errorMessages.push('Enter a valid roll number. (Eg: 21MCF1R01)'); if ( user.pg.cgpa < 0 || @@ -46,8 +39,7 @@ const validateFields = (user) => { if (user.totalGapInAcademics < 0 || user.totalGapInAcademics == null || user.totalGapInAcademics > 10) errorMessages.push('Total gap in academics must be greater than or equal to 0.'); - if (user.backlogs < 0 || user.backlogs == null || user.backlogs > 10) - errorMessages.push('Backlogs must be greater than or equal to 0.'); + if (user.backlogs < 0 || user.backlogs == null || user.backlogs > 10) errorMessages.push('Backlogs must be greater than or equal to 0.'); return errorMessages; };