Skip to content

Commit 7f69812

Browse files
authored
Merge pull request #2216 from Northeastern-Electric-Racing/#2132-user-schedule-settings
#2132: Schedule Settings Section
2 parents c6eb0f0 + b833a19 commit 7f69812

16 files changed

Lines changed: 428 additions & 53 deletions

File tree

src/backend/src/services/users.services.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { User_Settings, User as PrismaUser, Schedule_Settings } from '@prisma/client';
1+
import { User_Settings, User as PrismaUser } from '@prisma/client';
22
import { OAuth2Client } from 'google-auth-library/build/src/auth/oauth2client';
33
import {
44
AuthenticatedUser,
@@ -353,7 +353,7 @@ export default class UsersService {
353353
personalGmail: string,
354354
personalZoomLink: string,
355355
availability: number[]
356-
): Promise<Schedule_Settings> {
356+
): Promise<UserScheduleSettings> {
357357
const existingUser = await prisma.schedule_Settings.findFirst({
358358
where: { personalGmail, userId: { not: user.userId } } // excludes the current user from check
359359
});
@@ -376,6 +376,6 @@ export default class UsersService {
376376
availability
377377
}
378378
});
379-
return newUserScheduleSettings;
379+
return userScheduleSettingsTransformer(newUserScheduleSettings);
380380
}
381381
}

src/backend/tests/users.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ describe('Users', () => {
173173
vi.spyOn(prisma.schedule_Settings, 'upsert').mockResolvedValue(batmanScheduleSettings);
174174
const res = await UsersService.setUserScheduleSettings(batman, 'batman@gmail.com', 'https://zoom.com', [1, 2]);
175175

176-
expect(res).toBe(batmanScheduleSettings);
176+
expect(res).toStrictEqual(batmanUserScheduleSettings);
177177
});
178178

179179
test('setting same email does not work', async () => {

src/frontend/src/apis/users.api.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import axios from '../utils/axios';
7-
import { Project, User, UserSecureSettings } from 'shared';
7+
import { Project, User, UserScheduleSettings, UserSecureSettings } from 'shared';
88
import { apiUrls } from '../utils/urls';
99
import { authUserTransformer, userTransformer } from './transformers/users.transformers';
1010
import { AuthenticatedUser, UserSettings } from 'shared';
@@ -93,6 +93,16 @@ export const getUserSecureSettings = (id: number) => {
9393
return axios.get<UserSecureSettings>(apiUrls.userSecureSettings(`${id}`));
9494
};
9595

96+
/**
97+
* Fetch a user's schedule settings
98+
*
99+
* @param userId User ID of the requested user's schedule settings
100+
* @returns the schedule settings
101+
*/
102+
export const getUserScheduleSettings = (userId: number) => {
103+
return axios.get<UserScheduleSettings>(apiUrls.userScheduleSettings(`${userId}`));
104+
};
105+
96106
/**
97107
* Update the given user's settings by UserId
98108
*/
@@ -107,6 +117,13 @@ export const updateUserSecureSettings = (settings: UserSecureSettings) => {
107117
return axios.post<{ message: string }>(apiUrls.userSecureSettingsSet(), settings);
108118
};
109119

120+
/**
121+
* Update the given user's schedule settings by UserId
122+
*/
123+
export const updateUserScheduleSettings = (settings: UserScheduleSettings) => {
124+
return axios.post<UserScheduleSettings>(apiUrls.userScheduleSettingsSet(), settings);
125+
};
126+
110127
export const updateUserRole = (id: number, role: string) => {
111128
return axios.post<{ message: string }>(apiUrls.userRoleByUserId(`${id}`), { role });
112129
};

src/frontend/src/pages/CalendarPage/SchedulingComponents/TimeSlot.tsx renamed to src/frontend/src/components/TimeSlot.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const TimeSlot: React.FC<TimeSlotProps> = ({
5151
height: small ? '25px' : '4.7vh',
5252
width: small ? '81px' : '12.2%',
5353
backgroundColor,
54-
cursor: 'pointer',
54+
cursor: onMouseEnter ? 'pointer' : undefined,
5555
borderStyle: 'solid',
5656
borderColor: 'gray',
5757
borderWidth: '0.1px',

src/frontend/src/hooks/users.hooks.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@ import {
1515
getUsersFavoriteProjects,
1616
updateUserSecureSettings,
1717
getCurrentUserSecureSettings,
18-
getUserSecureSettings
18+
getUserSecureSettings,
19+
getUserScheduleSettings,
20+
updateUserScheduleSettings
1921
} from '../apis/users.api';
20-
import { User, AuthenticatedUser, UserSettings, UpdateUserRolePayload, Project, UserSecureSettings } from 'shared';
22+
import {
23+
User,
24+
AuthenticatedUser,
25+
UserSettings,
26+
UpdateUserRolePayload,
27+
Project,
28+
UserSecureSettings,
29+
UserScheduleSettings
30+
} from 'shared';
2131
import { useAuth } from './auth.hooks';
2232
import { useContext } from 'react';
2333
import { UserContext } from '../app/AppContextUser';
@@ -112,6 +122,23 @@ export const useUserSecureSettings = (id: number) => {
112122
});
113123
};
114124

125+
/**
126+
* Custom React Hook to supply a single user's schedule settings
127+
*
128+
* @param id User ID of the requested user's schedule settings
129+
* @returns the user's schedule settings
130+
*/
131+
export const useUserScheduleSettings = (id: number) => {
132+
return useQuery<UserScheduleSettings, Error>(['users', id, 'schedule-settings'], async () => {
133+
try {
134+
const { data } = await getUserScheduleSettings(id);
135+
return data;
136+
} catch (error: unknown) {
137+
return { drScheduleSettingsId: '', personalGmail: '', personalZoomLink: '', availability: [] };
138+
}
139+
});
140+
};
141+
115142
/**
116143
* Custom React Hook to supply a single user's settings.
117144
*
@@ -162,6 +189,28 @@ export const useUpdateUserSecureSettings = () => {
162189
);
163190
};
164191

192+
/**
193+
* Custom Hook to update a user's schedule settings
194+
*
195+
* @returns The mutation to update a user's schedule settings
196+
*/
197+
export const useUpdateUserScheduleSettings = () => {
198+
const user = useCurrentUser();
199+
const queryClient = useQueryClient();
200+
return useMutation<UserScheduleSettings, Error, UserScheduleSettings>(
201+
['users', 'schedule-settings', 'update'],
202+
async (settings: UserScheduleSettings) => {
203+
const { data } = await updateUserScheduleSettings(settings);
204+
return data;
205+
},
206+
{
207+
onSuccess: () => {
208+
queryClient.invalidateQueries(['users', user.userId, 'schedule-settings']);
209+
}
210+
}
211+
);
212+
};
213+
165214
/**
166215
* Custom React Hook to update a user's role.
167216
*/

src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityScheduleView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
HeatmapColors,
99
getBackgroundColor
1010
} from '../../../utils/design-review.utils';
11-
import TimeSlot from '../SchedulingComponents/TimeSlot';
11+
import TimeSlot from '../../../components/TimeSlot';
1212

1313
interface AvailabilityScheduleViewProps {
1414
availableUsers: Map<number, User[]>;

src/frontend/src/pages/CalendarPage/SchedulingComponents/AvailabilityEditModal.tsx

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/frontend/src/pages/SettingsPage/Settings.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import ErrorPage from '../ErrorPage';
1717
import UserSecureSettings from './UserSecureSettings/UserSecureSettings';
1818
import { useAllTeams } from '../../hooks/teams.hooks';
1919
import { displayEnum } from '../../utils/pipes';
20+
import UserScheduleSettings from './UserScheduleSettings/UserScheduleSettings';
2021

2122
const NERSwitch = styled((props: SwitchProps) => (
2223
<Switch focusVisibleClassName=".Mui-focusVisible" disableRipple {...props} />
@@ -112,7 +113,7 @@ const Settings: React.FC = () => {
112113

113114
return (
114115
<PageLayout title="Settings">
115-
{showAlert && <Alert severity="info">Haha {auth.user?.firstName} bye bye!</Alert>}
116+
{showAlert && <Alert severity="info">Haha {user.firstName} bye bye!</Alert>}
116117
<PageBlock title={'Organization Settings'}>
117118
<Grid container>
118119
<Grid item xs={6} md={12}>
@@ -162,6 +163,7 @@ const Settings: React.FC = () => {
162163
</PageBlock>
163164
<UserSettings currentSettings={userSettingsData} />
164165
<UserSecureSettings currentSettings={userSecureSettings} />
166+
<UserScheduleSettings user={user} />
165167
</PageLayout>
166168
);
167169
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import NERModal from '../../../../components/NERModal';
2+
import EditAvailability from './EditAvailability';
3+
4+
interface DRCEditModalProps {
5+
open: boolean;
6+
header: string;
7+
availabilites: number[];
8+
setAvailabilities: (availabilities: number[]) => void;
9+
onHide: () => void;
10+
}
11+
12+
const AvailabilityEditModal: React.FC<DRCEditModalProps> = ({ open, onHide, header, availabilites, setAvailabilities }) => {
13+
const existingMeetingData = new Map<number, string>();
14+
15+
return (
16+
<NERModal open={open} onHide={onHide} title={header} onSubmit={onHide} submitText="Save">
17+
<EditAvailability
18+
selectedTimes={availabilites}
19+
setSelectedTimes={setAvailabilities}
20+
existingMeetingData={existingMeetingData}
21+
/>
22+
</NERModal>
23+
);
24+
};
25+
26+
export default AvailabilityEditModal;

src/frontend/src/pages/CalendarPage/SchedulingComponents/EditAvailability.tsx renamed to src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/EditAvailability.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Grid } from '@mui/material';
22
import { useState } from 'react';
3-
import { HeatmapColors, EnumToArray, DAY_NAMES, REVIEW_TIMES } from '../../../utils/design-review.utils';
4-
import TimeSlot from './TimeSlot';
3+
import { HeatmapColors, EnumToArray, DAY_NAMES, REVIEW_TIMES } from '../../../../utils/design-review.utils';
4+
import TimeSlot from '../../../../components/TimeSlot';
55

66
interface EditAvailabilityProps {
77
selectedTimes: number[];

0 commit comments

Comments
 (0)