diff --git a/pages/api/matching/editPosting.ts b/pages/api/matching/editPosting.ts new file mode 100644 index 00000000..49549501 --- /dev/null +++ b/pages/api/matching/editPosting.ts @@ -0,0 +1,79 @@ +import { firestore } from 'firebase-admin'; +import { NextApiRequest, NextApiResponse } from 'next'; +import initializeApi from '../../../lib/admin/init'; +import { userIsAuthorized } from '../../../lib/authorization/check-authorization'; + +initializeApi(); +const db = firestore(); +const POSTINGS_COLLECTION = '/postings'; + +interface PostingData { + postingId: string; + numberOfPeopleWanted: number; + skillSet: string; +} + +// Define the function to edit a posting, which is asynchronous and takes a Next.js API request and response. +async function editPosting(req: NextApiRequest, res: NextApiResponse) { + // Destructure and extract postingId, numberOfPeopleWanted, and skillSet from the request body. + const { postingId, numberOfPeopleWanted, skillSet }: PostingData = req.body; + + // Validate the request body to ensure that postingId, numberOfPeopleWanted, and skillSet are provided. + if (!postingId || numberOfPeopleWanted === undefined || !skillSet) { + // If any required fields are missing, return a 400 status code and an error message. + return res.status(400).json({ msg: 'Missing required fields' }); + } + + try { + // Reference the specific posting document in the Firestore database using the postingId. + const postingRef = db.collection(POSTINGS_COLLECTION).doc(postingId); + // Attempt to retrieve the document from Firestore. + const postingDoc = await postingRef.get(); + + // Check if the document exists. If not, return a 404 status code and an error message. + if (!postingDoc.exists) { + return res.status(404).json({ msg: 'Posting not found' }); + } + + // If the document exists, update it with the new numberOfPeopleWanted and skillSet values. + await postingRef.update({ + numberOfPeopleWanted, + skillSet, + }); + + return res.status(200).json({ + msg: 'Posting updated successfully', + posting: { ...postingDoc.data(), numberOfPeopleWanted, skillSet }, + }); + } catch (error) { + // If an error occurs during the process, log the error and return a 500 status code with an error message. + console.error('Error updating posting:', error); + return res.status(500).json({ msg: 'Internal server error' }); + } +} + +async function handlePostRequest(req: NextApiRequest, res: NextApiResponse) { + const userToken = req.headers['authorization'] as string; + const isAuthorized = await userIsAuthorized(userToken, ['hacker']); + if (!isAuthorized) { + return res.status(403).json({ + msg: 'Request is not allowed to perform hacker functionality', + }); + } + + return editPosting(req, res); +} + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + const { method } = req; + switch (method) { + case 'POST': { + return handlePostRequest(req, res); + } + default: { + return res.status(404).json({ + msg: 'Route not found', + }); + } + } +} diff --git a/pages/api/matching/getInterests.ts b/pages/api/matching/getInterests.ts new file mode 100644 index 00000000..c31bd08e --- /dev/null +++ b/pages/api/matching/getInterests.ts @@ -0,0 +1,72 @@ +import { firestore } from 'firebase-admin'; +import { NextApiRequest, NextApiResponse } from 'next'; +import initializeApi from '../../../lib/admin/init'; +import { userIsAuthorized } from '../../../lib/authorization/check-authorization'; + +initializeApi(); +const db = firestore(); + +// Enhanced function to get all users interested in a specific posting +async function getInterestedUsers(req: NextApiRequest, res: NextApiResponse) { + try { + // Validate the input: ensure a postingId is provided + const postingId = req.query.postingId as string; + if (!postingId) { + return res.status(400).json({ error: 'Posting ID must be provided.' }); + } + + // Reference to the interestedPeople sub-collection for the given postingId + const interestedRef = db.collection('postings').doc(postingId).collection('interestedPeople'); + + // Fetch the documents from the sub-collection + const snapshot = await interestedRef.get(); + + // If there are no interested users, return an empty array with a message + if (snapshot.empty) { + return res + .status(404) + .json({ message: 'No interested users found for this posting.', interestedUsers: [] }); + } + + // Map over the documents to extract the data + const interestedUsers = snapshot.docs.map((doc) => { + const userData = doc.data(); + return { + name: userData.name, + email: userData.email, + }; + }); + + // Return the list of interested users + return res.status(200).json(interestedUsers); + } catch (error) { + console.error('Failed to retrieve interested users:', error); + // Return a generic error message + return res.status(500).json({ error: 'An error occurred while fetching interested users.' }); + } +} + +async function handleGetRequest(req: NextApiRequest, res: NextApiResponse) { + const userToken = req.headers['authorization'] as string; + const isAuthorized = await userIsAuthorized(userToken, ['hacker']); + if (!isAuthorized) { + return res.status(403).json({ + msg: 'Request is not allowed to perform this functionality', + }); + } + return getInterestedUsers(req, res); +} + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + const { method } = req; + switch (method) { + case 'GET': { + return handleGetRequest(req, res); + } + default: { + return res.status(404).json({ + msg: 'Route not found', + }); + } + } +} diff --git a/pages/api/matching/getPostings.ts b/pages/api/matching/getPostings.ts new file mode 100644 index 00000000..8fa1dc25 --- /dev/null +++ b/pages/api/matching/getPostings.ts @@ -0,0 +1,60 @@ +import { firestore } from 'firebase-admin'; +import { NextApiRequest, NextApiResponse } from 'next'; +import initializeApi from '../../../lib/admin/init'; +import { userIsAuthorized } from '../../../lib/authorization/check-authorization'; + +initializeApi(); +const db = firestore(); +const POSTINGS_COLLECTION = '/postings'; + +interface PostingData { + postingId: string; +} + +// Define an asynchronous function to retrieve all postings from the database. +async function getAllPostings(req: NextApiRequest, res: NextApiResponse) { + try { + // Attempt to get all documents from the 'POSTINGS_COLLECTION' in Firestore. + const postingsSnapshot = await db.collection(POSTINGS_COLLECTION).get(); + + // Transform the documents snapshot into an array of objects. Each object contains + // the document ID and the document's data (fields like numberOfPeopleWanted, skillSet, etc.). + const postings = postingsSnapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() })); + + // Return a 200 OK status with the array of postings as JSON. This response + // includes all postings currently in the 'POSTINGS_COLLECTION'. + return res.status(200).json(postings); + } catch (error) { + // If an error occurs during the process of retrieving or processing the postings, + // log the error to the console for debugging purposes and return a 500 Internal Server + // Error status with an error message. + console.error('Error retrieving postings:', error); + return res.status(500).json({ msg: 'Internal server error' }); + } +} + +async function handleRequest(req: NextApiRequest, res: NextApiResponse) { + const userToken = req.headers['authorization'] as string; + const isAuthorized = await userIsAuthorized(userToken, ['hacker']); + if (!isAuthorized) { + return res.status(403).json({ + msg: 'Request is not allowed to perform this functionality', + }); + } + + return getAllPostings(req, res); +} + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + const { method } = req; + switch (method) { + case 'GET': { + return handleRequest(req, res); + } + default: { + return res.status(404).json({ + msg: 'Route not found', + }); + } + } +}