Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssayzhang committed May 4, 2024
1 parent 08b48d2 commit fe429d5
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
52 changes: 52 additions & 0 deletions backend/src/API/coffeeChatAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import CoffeeChatDao from '../dao/CoffeeChatDao';
import isEqual from 'lodash.isequal';

Check failure on line 2 in backend/src/API/coffeeChatAPI.ts

View workflow job for this annotation

GitHub Actions / check

`lodash.isequal` import should occur before import of `../dao/CoffeeChatDao`
import PermissionsManager from '../utils/permissionsManager';
import { PermissionError } from '../utils/errors';

const coffeeChatDao = new CoffeeChatDao();

//get all coffee chat instances

Check failure on line 8 in backend/src/API/coffeeChatAPI.ts

View workflow job for this annotation

GitHub Actions / check

Expected exception block, space or tab after '//' in comment
export const getAllCoffeeChats = (): Promise<CoffeeChat[]> => coffeeChatDao.getAllCoffeeChats();

//get coffee chat instances for user

Check failure on line 11 in backend/src/API/coffeeChatAPI.ts

View workflow job for this annotation

GitHub Actions / check

Expected exception block, space or tab after '//' in comment
export const getCoffeeChatsByUser = async (user: IdolMember): Promise<CoffeeChat[]> =>
coffeeChatDao.getCoffeeChatsByUser(user);

// create new coffee chat instance
export const createCoffeeChat = async (coffeeChat: CoffeeChat): Promise<CoffeeChat> => {
const [member1, member2] = coffeeChat.members;

if (isEqual(member1, member2)) {
throw new Error('Cannot create coffee chat with yourself.');
}
const prevChats1 = await coffeeChatDao.getCoffeeChatsByUser(member1);
const prevChats2 = await coffeeChatDao.getCoffeeChatsByUser(member2);
const prevChats = [...prevChats1, ...prevChats2];
if (
prevChats.some(
(c) => isEqual(c.members, [member1, member2]) || isEqual(c.members, [member2, member1])
)
) {
throw new Error(
'Cannot create coffee chat with member. Previous coffee chats from previous semesters exist.'
);
}
await coffeeChatDao.createCoffeeChat(coffeeChat);
return coffeeChat;
};

// update coffee chat instance
export const updateCoffeeChat = async (coffeeChat: CoffeeChat): Promise<CoffeeChat> => {
await coffeeChatDao.updateCoffeeChat(coffeeChat);
return coffeeChat;
};

//delete all coffee chats

Check failure on line 44 in backend/src/API/coffeeChatAPI.ts

View workflow job for this annotation

GitHub Actions / check

Expected exception block, space or tab after '//' in comment
export const clearAllCoffeeChats = async (user: IdolMember): Promise<void> => {
const isLeadOrAdmin = await PermissionsManager.isLeadOrAdmin(user);
if (!isLeadOrAdmin)
throw new PermissionError(
'User with email ${user.email} does not have sufficient permissions to delete all coffee chats.'

Check warning on line 49 in backend/src/API/coffeeChatAPI.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected template string expression
);
await CoffeeChatDao.deleteAllCoffeeChat();
};
6 changes: 6 additions & 0 deletions backend/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import {
regradeSubmissions,
updateSubmissions
} from './API/devPortfolioAPI';
import { getAllCoffeeChats } from './API/coffeeChatAPI';
import DPSubmissionRequestLogDao from './dao/DPSubmissionRequestLogDao';
import AdminsDao from './dao/AdminsDao';
import { sendMail } from './API/mailAPI';
Expand Down Expand Up @@ -345,6 +346,11 @@ loginCheckedGet('/event-proof-image/:name(*)', async (req, user) => ({
url: await getEventProofImage(req.params.name, user)
}));

// Coffee Chat
loginCheckedGet('/coffee-chat', async () => ({
coffeeChats: await getAllCoffeeChats()
}));

// TODO: Modify this endpoint to /event-proof-image/* to be more RESTful
loginCheckedGet('/event-proof-image-signed-url/:name(*)', async (req, user) => ({
url: await setEventProofImage(req.params.name, user)
Expand Down
101 changes: 101 additions & 0 deletions backend/src/dao/CoffeeChatDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { v4 as uuidv4 } from 'uuid';
import { db, memberCollection, coffeeChatsCollection } from '../firebase';
import { DBCoffeeChat } from '../types/DataTypes';
import { getMemberFromDocumentReference } from '../utils/memberUtil';
import BaseDao from './BaseDao';
import { deleteCollection } from '../utils/firebase-utils';

async function materializeCoffeeChat(dbCoffeeChat: DBCoffeeChat): Promise<CoffeeChat> {
const member1 = await getMemberFromDocumentReference(dbCoffeeChat.members[0]);
const member2 = await getMemberFromDocumentReference(dbCoffeeChat.members[1]);

return {
...dbCoffeeChat,
members: [member1, member2]
};
}

async function serializeCoffeeChat(coffeeChat: CoffeeChat): Promise<DBCoffeeChat> {
const member1Data = await memberCollection.doc(coffeeChat.members[0].email);
const member2Data = await memberCollection.doc(coffeeChat.members[1].email);

return {
...coffeeChat,
members: [member1Data, member2Data]
};
}

export default class CoffeeChatDao extends BaseDao<CoffeeChat, DBCoffeeChat> {
constructor() {
super(coffeeChatsCollection, materializeCoffeeChat, serializeCoffeeChat);
}

/**
* Creates a new coffee chat for member
* @param coffeeChat - Newly created CoffeeChat object.
* If provided, the object uuid will be used. If not, a new one will be generated.
* The pending field will be set to true by default.
* A member can not create a coffee chat the same person from previous semesters
*/

async createCoffeeChat(coffeeChat: CoffeeChat): Promise<CoffeeChat> {
const coffeeChatWithUUID = {
...coffeeChat,
status: 'pending' as Status,
uuid: coffeeChat.uuid ? coffeeChat.uuid : uuidv4()
};
return this.createDocument(coffeeChatWithUUID.uuid, coffeeChatWithUUID);
}

/**
* Gets the coffee chats
* @param uuid - DB uuid of coffee chat
*/
async getCoffeeChat(uuid: string): Promise<CoffeeChat | null> {
return this.getDocument(uuid);
}

/**
* Gets all coffee chats
*/
async getAllCoffeeChats(): Promise<CoffeeChat[]> {
return this.getDocuments();
}

/**
* Updates a coffee chat
* @param coffeeChat - updated Coffee Chat object
*/
async updateCoffeeChat(coffeeChat: CoffeeChat): Promise<CoffeeChat> {
return this.updateDocument(coffeeChat.uuid, coffeeChat);
}

/**
* Gets all coffee chat for a user
* @param user - user whose coffee chats should be fetched
*/
async getCoffeeChatsByUser(user: IdolMember): Promise<CoffeeChat[]> {
return this.getDocuments([
{
field: 'member',
comparisonOperator: '==',
value: memberCollection.doc(user.email)
}
]);
}

/**
* Deletes a coffee chat
* @param uuid - DB uuid of CoffeeChat
*/
async deleteCoffeeChat(uuisd: string): Promise<void> {
await this.getDocuments();
}

/**
* Deletes all coffee chats for all users
*/
static async deleteAllCoffeeChat(): Promise<void> {
await deleteCollection(db, 'coffee-chats', 500);
}
}
1 change: 0 additions & 1 deletion frontend/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
Expand Down

0 comments on commit fe429d5

Please sign in to comment.