From 257c9c6d137ed6e384f262538479b210963633ab Mon Sep 17 00:00:00 2001 From: Sxnny-s Date: Mon, 6 Jan 2025 14:10:28 -0500 Subject: [PATCH 01/14] #18 getting started on the favorites section --- server/controllers/user.js | 10 ++++++++++ server/routes/favorites.js | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 server/routes/favorites.js diff --git a/server/controllers/user.js b/server/controllers/user.js index e69de29..c40fb01 100644 --- a/server/controllers/user.js +++ b/server/controllers/user.js @@ -0,0 +1,10 @@ +const userController = { + addUser: (req, res) => { + + }, + addFavoriteCompany: (req, res) => { + + } + } + + export default userController; \ No newline at end of file diff --git a/server/routes/favorites.js b/server/routes/favorites.js new file mode 100644 index 0000000..e853290 --- /dev/null +++ b/server/routes/favorites.js @@ -0,0 +1,13 @@ +const express = require("express"); +const userController = require("../controllers/favo") +const favoritesRouter = express.Router(); + + + + + + + + + +export default favoritesRouter; \ No newline at end of file From 85af4f92f8857ad021f537e1221b2951bc4db27c Mon Sep 17 00:00:00 2001 From: Sxnny-s Date: Tue, 7 Jan 2025 12:02:31 -0500 Subject: [PATCH 02/14] #18 started favorites controller and routes --- server/routes/favorites.js | 13 ------------- server/routes/user.js | 1 + 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 server/routes/favorites.js diff --git a/server/routes/favorites.js b/server/routes/favorites.js deleted file mode 100644 index e853290..0000000 --- a/server/routes/favorites.js +++ /dev/null @@ -1,13 +0,0 @@ -const express = require("express"); -const userController = require("../controllers/favo") -const favoritesRouter = express.Router(); - - - - - - - - - -export default favoritesRouter; \ No newline at end of file diff --git a/server/routes/user.js b/server/routes/user.js index adca475..c4221fc 100644 --- a/server/routes/user.js +++ b/server/routes/user.js @@ -5,6 +5,7 @@ const userRouter = express.Router() userRouter.post('/', userController.addUser); userRouter.get('/', userController.getAllUsers); +userRouter.get('/' ) export default userRouter From 4e84741efc46d8b0faa6a2e7cf56852a2c8dd56e Mon Sep 17 00:00:00 2001 From: Sxnny-s Date: Tue, 7 Jan 2025 12:08:22 -0500 Subject: [PATCH 03/14] upadated user controller --- server/controllers/user.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server/controllers/user.js b/server/controllers/user.js index 76845ee..5567671 100644 --- a/server/controllers/user.js +++ b/server/controllers/user.js @@ -1,15 +1,3 @@ -<<<<<<< HEAD -const userController = { - addUser: (req, res) => { - - }, - addFavoriteCompany: (req, res) => { - - } - } - - export default userController; -======= import { clerkClient } from '@clerk/express' import User from '../models/User.js' @@ -48,4 +36,3 @@ const userController = { } export default userController ->>>>>>> 9720463ea6c04301b27af29611db85cab5fa2f8c From fee7e587a0839bb0bd751127d68486d6eeb91819 Mon Sep 17 00:00:00 2001 From: Sxnny-s Date: Tue, 7 Jan 2025 12:16:33 -0500 Subject: [PATCH 04/14] #18 started favorites controller and routes --- server/controllers/user.js | 15 +++++++++++++++ server/routes/user.js | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/server/controllers/user.js b/server/controllers/user.js index 5567671..a24e871 100644 --- a/server/controllers/user.js +++ b/server/controllers/user.js @@ -32,7 +32,22 @@ const userController = { } catch (error) { next(error) } + }, + addFavoriteCompany: async (req, res, next) => { + try { + + } catch (error) { + next(error) + } + }, + getFavoritesCompanies: async (req, res, next) => { + try { + const favorites = await User.find({ clerkId: req.auth.userId }).select('favoriteCompanies') + } catch (error) { + next(error) + } } + } export default userController diff --git a/server/routes/user.js b/server/routes/user.js index c4221fc..1c27b51 100644 --- a/server/routes/user.js +++ b/server/routes/user.js @@ -5,7 +5,7 @@ const userRouter = express.Router() userRouter.post('/', userController.addUser); userRouter.get('/', userController.getAllUsers); -userRouter.get('/' ) - +userRouter.get('/favorites', userController.getFavoritesCompanies) +userRouter.post('/favorites', userController.addFavoriteCompany) export default userRouter From 0804563893a491fa6de2aca91c95969d24f4f916 Mon Sep 17 00:00:00 2001 From: Nagiyd Date: Mon, 6 Jan 2025 17:13:29 -0500 Subject: [PATCH 05/14] "#46 initial commit to personal branch" --- server/controllers/company.js | 89 +++++++++++++++++++++++++++++++++++ server/routes/company.js | 5 +- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/server/controllers/company.js b/server/controllers/company.js index 0b1facf..ff3a45e 100644 --- a/server/controllers/company.js +++ b/server/controllers/company.js @@ -1,6 +1,7 @@ import Company from '../models/Company.js' const companyController = { + //fetches all companies: getAllCompanies: async (req, res, next) => { try { const companies = await Company.find({}) @@ -10,6 +11,94 @@ const companyController = { next(error) } }, + + //fetches a specfic company (and all of its data): + getCompany: async (req, res, next) => { + try { + const { id } = req.params // Get the company ID from the route parameters + const company = await Company.findById(id).populate('reviews') // Fetch company and populate reviews + + if (!company) { + return res.status(404).json({ message: 'Company not found' }) + } + + res.status(200).json(company) + } catch (error) { + next(error) + } + }, + + // fetches top 5 companies from DB with the highest review scores: + getBestCompanies: async (req, res, next) => { + try { + const companies = await Company.aggregate([ + { + //Joins the reviews collection with the Company collection + stores the matching documents in the 'reviewsData' array. + + $lookup: { + from: 'reviews', // Collection that we want data to join + localField: 'reviews', //first field in the current collection + foreignField: '_id', // Other field in the other collection + as: 'reviewsData', // New array field that is storing the joined data + }, + }, + { + $addFields: { + averageRating: { $avg: '$reviewsData.companyCulture' }, // Calculate the average rating + }, + }, + { + $sort: { averageRating: -1 }, // Sort by averageRating in descending order + }, + { + $limit: 5, // Limits to top 5 companies + }, + ]) + + res.status(200).json(companies) + } catch (error) { + next(error) + } + }, + + //Fetches 5 worst companies, sorted in ascending order + getWorstCompanies: async (req, res, next) => { + try { + const companies = await Company.aggregate([ + { + //Joins the reviews collection with the Company collection + stores the matching documents in the 'reviewsData' array. + + $lookup: { + from: 'reviews', // Collection that we want data to join + localField: 'reviews', //first field in the current collection + foreignField: '_id', // Other field in the other collection + as: 'reviewsData', // New array field that is storing the joined data + }, + }, + { + $addFields: { + averageRating: { $avg: '$reviewsData.companyCulture' }, // Calculate the average rating + }, + }, + { + $sort: { averageRating: 1 }, // Sort by averageRating in ascending order + }, + { + $limit: 5, // Limit to bottom 5 companies + }, + ]) + + res.status(200).json(companies) + } catch (error) { + next(error) + } + }, } export default companyController + +// considerations: + +// do we want to add the ability to limit the number of results that return when a user searches for all companies? + +// Should we add query params so that we can filter through specfic companies returned based on specific atributes? diff --git a/server/routes/company.js b/server/routes/company.js index 6b7533f..bab0b65 100644 --- a/server/routes/company.js +++ b/server/routes/company.js @@ -2,6 +2,9 @@ import express from 'express' const companyRouter = express.Router() import companyController from '../controllers/company.js' -companyRouter.get('/', companyController.getAllCompanies) +companyRouter.get('/', companyController.getAllCompanies) // GET /company +companyRouter.get('/:id', companyController.getCompany) // GET /company/:id +companyRouter.get('/best', companyController.getBestCompanies) // GET /company/best +companyRouter.get('/worst', companyController.getWorstCompanies) // GET /company/worst export default companyRouter From 6688356d30b7d28a5c9f09cdf22b1f44bad553da Mon Sep 17 00:00:00 2001 From: Nagiyd Date: Tue, 7 Jan 2025 12:43:31 -0500 Subject: [PATCH 06/14] #46 updates to company controller and routes --- README.md | 26 ++++++++++++++++++++++++++ server/config/database.js | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/README.md b/README.md index d3057f2..cba6d50 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,16 @@ +<<<<<<< HEAD # Kinfolx ## An app that allows you rate companies based on their diversity & company culture. +======= +Kinfolx: An app that allows you rate companies based on their diversity & company culture. + +Make sure to use npm install to install all Dependencies. +>>>>>>> 3ddd9d9 (company controller updates) View our app live : https://kinfolx-production.up.railway.app/ +<<<<<<< HEAD ## Instructions to run the code locally Make sure to use `npm install` to install all Dependencies. @@ -32,6 +39,25 @@ npm run dev The backend server is loading from `http://localhost:3000` ### Environment Variables +======= +1. Start the backend server: + +```bash +cd server +npm i +npm run dev +``` + +2. Start the frontend server: + +```bash +npm i +npm run dev +``` + +3. Open your browser and go to `http://localhost:5173` + The backend server is loading from `http://localhost:3000` +>>>>>>> 3ddd9d9 (company controller updates) One ENV goes inside of the config file inside the server and the other ENV is in the root diff --git a/server/config/database.js b/server/config/database.js index b7c6669..558fc2a 100644 --- a/server/config/database.js +++ b/server/config/database.js @@ -10,4 +10,8 @@ const connectDB = async () => { process.exit(1) } } +<<<<<<< HEAD export default connectDB +======= +export default connectDB +>>>>>>> 4d73f27 (#46) From 4df3765efb6bb3254bc0d90e4d3d2d952af49532 Mon Sep 17 00:00:00 2001 From: AOA19 Date: Tue, 7 Jan 2025 13:51:41 -0500 Subject: [PATCH 07/14] #40 - Commented out the add company input, added a position dropdown to Review component. Added a fetch request inside the handleSubmit listener so the data from the review form can be sent to the server. Co-authored-by: Abdiladif Gurhan Co-authored-by: Angel Morris Co-authored-by: Waskar Paulino Co-authored-by: Yonatan Mateo Aviv Co-authored-by: Mikal Muwakkil Co-authored-by: Gabrielle --- src/components/ReviewList/ReviewList.jsx | 211 ++++++++++++++--------- src/pages/Review/Review.jsx | 49 ++++-- 2 files changed, 164 insertions(+), 96 deletions(-) diff --git a/src/components/ReviewList/ReviewList.jsx b/src/components/ReviewList/ReviewList.jsx index 90fbf8a..295ed5c 100644 --- a/src/components/ReviewList/ReviewList.jsx +++ b/src/components/ReviewList/ReviewList.jsx @@ -4,97 +4,142 @@ import './reviewList.css'; const categories = [ "accountability", "representation", - "work-life-balance", - "career-growth", - "diversity-scale", - "company-culture", + "workLifeBalance", + "careerGrowth", + "diversityScale", + "companyCulture", "salaries", ]; -const ReviewList = (props) => { - const [ratings, setRatings] = useState({}); - const [comment, setComment] = useState(""); - const [newCompany, setNewCompany] = useState(""); - - const handleMouseOver = (category, value) => { - setRatings((prev) => ({ - ...prev, - [`${category}-hover`]: value, - })); - }; - - const handleMouseLeave = (category) => { - setRatings((prev) => ({ - ...prev, - [`${category}-hover`]: undefined, - })); - }; - - const handleClick = (category, value) => { - setRatings((prev) => ({ - ...prev, - [category]: value, - })); - }; - - const handleSubmit = () => { - const companyName = props.company; - - if (!companyName) { - alert("Please select or add a company name."); - return; + +const ReviewList = (props) => { + const [ratings, setRatings] = useState({}) + const [comment, setComment] = useState('') + // const [newCompany, setNewCompany] = useState(""); + + console.log(ratings) + + const handleMouseOver = (category, value) => { + setRatings((prev) => ({ + ...prev, + [`${category}-hover`]: value, + })) + } + + const handleMouseLeave = (category) => { + setRatings((prev) => ({ + ...prev, + [`${category}-hover`]: undefined, + })) } - if (categories.some((category) => !ratings[category])) { - alert("Please rate all categories before submitting."); - return; + const handleClick = (category, value) => { + setRatings((prev) => ({ + ...prev, + [category]: value, + })) + } + + const handleSubmit = async () => { + const companyName = props.company + const position = props.position + let newRatings = {} + for(let rating in ratings){ + if(ratings[rating] !== undefined){ + newRatings[rating] = ratings[rating] + + } + } + console.log(newRatings) + + const reviewData = { + companyName, + position, + newRatings, + comment, + }; + + try { + // Send POST request to the backend API + const response = await fetch(`/api/review/${companyName}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(reviewData), + }); + if (!response.ok) { + console.log({reviewData}) + throw new Error (`Response status: ${response.status}`) + } + const responseData = await response.json() + console.log(`Response received: ${responseData}`); + } catch (error) { + console.log(error) + } + + + + if (!companyName || !position) { + alert('Please select or add a company name and role.') + return + } + + if (categories.some((category) => !ratings[category])) { + alert('Please rate all categories before submitting.') + return + } + + console.log({reviewData}) + alert('Review submitted successfully!') } - console.log({ companyName, ratings, comment }); - alert("Review submitted successfully!"); - }; - - - return ( -
-
- {categories.map((category) => ( -
- -
- {[1, 2, 3, 4, 5].map((value) => ( - star handleMouseOver(category, value)} - onMouseLeave={() => handleMouseLeave(category)} - onClick={() => handleClick(category, value)} - /> - ))} + return ( +
+
+ {categories.map((category) => ( +
+ +
+ {[1, 2, 3, 4, 5].map((value) => ( + star + handleMouseOver(category, value) + } + onMouseLeave={() => + handleMouseLeave(category) + } + onClick={() => handleClick(category, value)} + /> + ))} +
+
+ ))}
-
- ))} -
- -