From bd7e6240abe849c7239f04e8d7edd2dd70ecc00e Mon Sep 17 00:00:00 2001 From: Chanel Date: Wed, 24 Jul 2024 23:45:11 +1000 Subject: [PATCH] finish APIs for getCurrentActivity and findAllFriends - #842 --- client/src/api/getFriends.ts | 89 ++++++++++++++++++++++++++++++++ client/src/interfaces/Friends.ts | 16 ++++++ 2 files changed, 105 insertions(+) create mode 100644 client/src/api/getFriends.ts create mode 100644 client/src/interfaces/Friends.ts diff --git a/client/src/api/getFriends.ts b/client/src/api/getFriends.ts new file mode 100644 index 000000000..e676a4831 --- /dev/null +++ b/client/src/api/getFriends.ts @@ -0,0 +1,89 @@ +import { CurrentActivity, Friend, FriendsList } from '../interfaces/Friends'; +import NetworkError from '../interfaces/NetworkError'; +import { CourseCode, CourseData, EventPeriod } from '../interfaces/Periods'; +import timeoutPromise from '../utils/timeoutPromise'; +import { API_URL } from './config'; +import getCourseInfo from './getCourseInfo'; + +const getCurrentActivity = async (userId: string): Promise => { + // get the user's timetable data + const baseURL = `${API_URL.server}/user/timetable/${userId}`; + try { + const data = await timeoutPromise(1000, fetch(baseURL)); + const json = await data.json(); + if (data.status === 400) { + throw new NetworkError('Internal server error'); + } + + const selectedCourses = json.selectedCourses; + + // TODO: find helpers for these - for now hardcoded + const year = '2024'; + const term = 'T2'; + const isConvertToLocalTimezone = true; + + const courseInfos = await Promise.all( + selectedCourses.map((courseCode: string) => + getCourseInfo(year, term, courseCode as CourseCode, isConvertToLocalTimezone) + ) + ); + + const now = new Date(); + return findCurrentActivity(courseInfos, json.createdEvents, now); + } catch (error) { + throw new NetworkError('Could not connect to server'); + } +}; + + +const findCurrentActivity = (courseInfos: CourseData[], events: EventPeriod[], now: Date): CurrentActivity | null => { + for (const courseInfo of courseInfos) { + for (const courseClass of Object.values(courseInfo.activities)) { + for (const classData of courseClass) { + for (const period of classData.periods) { + const classStart = new Date(period.time.start); + const classEnd = new Date(period.time.end); + + if (classStart <= now && now <= classEnd) { + return { ...courseClass, type: 'class', start: classStart, end: classEnd } as CurrentActivity; + } + } + } + } + } + + for (const event of events) { + const eventStart = new Date(event.time.start); + const eventEnd = new Date(event.time.end); + + if (eventStart <= now && now <= eventEnd) { + return { ...event, type: 'event', start: eventStart, end: eventEnd } as CurrentActivity; + } + } + + return null; +} + + +const getAllFriends = async (userId: string): Promise => { + const baseURL = `${API_URL.server}/friend/findAllFriends/${userId}`; + try { + const data = await timeoutPromise(1000, fetch(baseURL)); + const json = await data.json(); + if (data.status === 400) { + throw new NetworkError('Internal server error'); + } + + const friends: FriendsList = await Promise.all(json.data.map(async (friend: any) => ({ + name: friend.name, + userId: friend.userId, + currentActivity: await getCurrentActivity(friend.userId) + }))); + + return friends; + } catch (error) { + throw new NetworkError('Could not connect to server'); + } +}; + +export default getCurrentActivity; \ No newline at end of file diff --git a/client/src/interfaces/Friends.ts b/client/src/interfaces/Friends.ts new file mode 100644 index 000000000..103ea552d --- /dev/null +++ b/client/src/interfaces/Friends.ts @@ -0,0 +1,16 @@ +import { SelectedClasses, CreatedEvents } from "./Periods"; + +export interface Friend { + name: string; + userId: string; + // show next event within the hour + currentActivity: CurrentActivity | null; +} + +export type FriendsList = Friend[]; + +export type CurrentActivity = { + type: 'class' | 'event'; + start: Date; + end: Date; +}