Skip to content

Commit debf30a

Browse files
authored
Merge pull request #3126 from Northeastern-Electric-Racing/teamtype-bug-fix
Fixed team up image download
2 parents 34203c7 + edb17a3 commit debf30a

File tree

7 files changed

+46
-41
lines changed

7 files changed

+46
-41
lines changed

src/backend/src/prisma/seed.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ const performSeed: () => Promise<void> = async () => {
6868
'Northeastern Electric Racing is a student-run organization at Northeastern University building all-electric formula-style race cars from scratch to compete in Forumla Hybrid + Electric Formula SAE (FSAE).',
6969
applyInterestImageId: '1_iak6ord4JP9TcR1sOYopyEs6EjTKQpw',
7070
exploreAsGuestImageId: '1wRes7V_bMm9W7_3JCIDXYkMUiy6B3wRI',
71-
applicationLink: 'https://northeastern.campuslabs.com/engage/submitter/form/start/491315'
71+
applicationLink:
72+
'https://docs.google.com/forms/d/e/1FAIpQLSeCvG7GqmZm_gmSZiahbVTW9ZFpEWG0YfGQbkSB_whhHzxXpA/closedform'
7273
}
7374
});
7475

src/backend/src/utils/google-integration.utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ interface GoogleDriveError {
8787
export const uploadFile = async (fileObject: Express.Multer.File) => {
8888
const bufferStream = new stream.PassThrough();
8989
bufferStream.end(fileObject.buffer);
90-
91-
if (fileObject.filename.length > 20) throw new HttpException(400, 'File name can only be at most 20 characters long');
90+
if (fileObject.filename?.length || fileObject.originalname.length > 20)
91+
throw new HttpException(400, 'File name can only be at most 20 characters long');
9292
//The regex /^[\w.]+$/ limits the file name to the set of alphanumeric characters (\w) and dots (for file type)
93-
if (!/^[\w.]+$/.test(fileObject.filename))
93+
if (!/^[\w.]+$/.test(fileObject.filename || fileObject.originalname))
9494
throw new HttpException(400, 'File name should only contain letters and numbers');
9595

9696
oauth2Client.setCredentials({

src/frontend/src/hooks/onboarding.hook.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,23 +138,21 @@ export const useEditChecklist = (id: string) => {
138138
);
139139
};
140140

141-
export const useGetImageUrls = (imageFileIds: (string | null)[]) => {
142-
return useQuery<string[], Error>(
143-
['image', imageFileIds],
141+
export const useGetImageUrls = (imageList: { objectId: string; imageFileId: string | null }[]) => {
142+
return useQuery<{ id: string; url: string | undefined }[], Error>(
143+
['image', imageList],
144144
async () => {
145-
if (!imageFileIds) throw new Error('No image ID provided');
146-
const imageBlobs = await Promise.all(
147-
imageFileIds
148-
.filter((id): id is string => id !== null)
149-
.map(async (imageId) => {
150-
const imageBlob = await downloadGoogleImage(imageId);
151-
return URL.createObjectURL(imageBlob);
152-
})
145+
const imageBlobsList = await Promise.all(
146+
imageList.map(async (object) => {
147+
const imageBlob = object.imageFileId ? await downloadGoogleImage(object.imageFileId) : undefined;
148+
const url = imageBlob ? URL.createObjectURL(imageBlob) : undefined;
149+
return { id: object.objectId, url };
150+
})
153151
);
154-
return imageBlobs;
152+
return imageBlobsList;
155153
},
156154
{
157-
enabled: !!imageFileIds
155+
enabled: !!imageList
158156
}
159157
);
160158
};

src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamTypeTable.tsx

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import CreateTeamTypeFormModal from './CreateTeamTypeFormModal';
77
import { TeamType } from 'shared';
88
import EditTeamTypeFormModal from './EditTeamTypeFormModal';
99
import { useAllTeamTypes, useSetTeamTypeImage } from '../../../hooks/team-types.hooks';
10-
import { useMemo, useState } from 'react';
10+
import { useState } from 'react';
1111
import { useToast } from '../../../hooks/toasts.hooks';
1212
import NERUploadButton from '../../../components/NERUploadButton';
1313
import { useGetImageUrls } from '../../../hooks/onboarding.hook';
@@ -25,28 +25,31 @@ const TeamTypeTable: React.FC = () => {
2525
const [addedImages, setAddedImages] = useState<{ [key: string]: File | undefined }>({});
2626
const toast = useToast();
2727

28-
const imageFileIds = teamTypes?.map((teamType) => teamType.imageFileId) ?? [];
29-
const { data: imageUrlsList, isLoading, isError } = useGetImageUrls(imageFileIds);
30-
const { mutateAsync: setTeamTypeImage, isLoading: setTeamTypeIsLoading } = useSetTeamTypeImage();
31-
32-
const imageUrls = useMemo(() => {
33-
if (!imageUrlsList || isLoading || isError) return {};
28+
const teamTypeImageList =
29+
teamTypes?.map((teamType) => {
30+
return { objectId: teamType.teamTypeId, imageFileId: teamType.imageFileId };
31+
}) ?? [];
3432

35-
const urlMap: { [key: string]: string | undefined } = {};
36-
teamTypes?.forEach((teamType, index) => {
37-
urlMap[teamType.teamTypeId] = imageUrlsList[index];
38-
});
39-
return urlMap;
40-
}, [imageUrlsList, isLoading, isError, teamTypes]);
33+
const { data: imageUrlsList, isLoading, isError, error } = useGetImageUrls(teamTypeImageList);
34+
const { mutateAsync: setTeamTypeImage, isLoading: setTeamTypeIsLoading } = useSetTeamTypeImage();
4135

4236
if (teamTypesIsError) {
4337
return <ErrorPage message={teamTypesError?.message} />;
4438
}
4539

46-
if (!teamTypes || teamTypesIsLoading || setTeamTypeIsLoading) {
40+
if (isError) {
41+
return <ErrorPage message={error?.message} />;
42+
}
43+
44+
if (!teamTypes || teamTypesIsLoading || setTeamTypeIsLoading || !imageUrlsList || isLoading) {
4745
return <LoadingIndicator />;
4846
}
4947

48+
const imageUrlsMap: { [key: string]: string | undefined } = {};
49+
imageUrlsList.forEach((item) => {
50+
imageUrlsMap[item.id] = item.url;
51+
});
52+
5053
const onSubmitTeamTypeImage = async (teamTypeId: string) => {
5154
const addedImage = addedImages[teamTypeId];
5255
if (addedImage) {
@@ -78,6 +81,7 @@ const TeamTypeTable: React.FC = () => {
7881
};
7982

8083
const teamTypesTableRows = teamTypes.map((teamType) => {
84+
console.log('teamType', teamType);
8185
return (
8286
<TableRow>
8387
<TableCell onClick={() => setEditingTeamType(teamType)} sx={{ cursor: 'pointer', border: '2px solid black' }}>
@@ -96,7 +100,12 @@ const TeamTypeTable: React.FC = () => {
96100
</TableCell>
97101
<TableCell
98102
onClick={() => setEditingTeamType(teamType)}
99-
sx={{ cursor: 'pointer', border: '2px solid black', verticalAlign: 'middle' }}
103+
sx={{
104+
cursor: 'pointer',
105+
border: '2px solid black',
106+
verticalAlign: 'middle',
107+
maxWidth: '15vw'
108+
}}
100109
>
101110
<Box sx={{ display: 'flex', alignItems: 'center' }}>
102111
<Typography variant="body1" sx={{ marginLeft: 1 }}>
@@ -109,7 +118,7 @@ const TeamTypeTable: React.FC = () => {
109118
{teamType.imageFileId && !addedImages[teamType.teamTypeId] && (
110119
<Box
111120
component="img"
112-
src={imageUrls[teamType.teamTypeId]}
121+
src={imageUrlsMap[teamType.teamTypeId]}
113122
alt="Image Preview"
114123
sx={{ maxWidth: '100px', mt: 1, mb: 1 }}
115124
/>

src/frontend/src/pages/HomePage/Home.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ const Home: React.FC = () => {
2121

2222
return (
2323
<Switch>
24+
{!isGuest(userRole) &&
25+
[routes.HOME_GUEST, routes.HOME_PNM, routes.HOME_ONBOARDING, routes.HOME_ACCEPT].map((path) => (
26+
<Redirect exact path={path} to={routes.HOME} />
27+
))}
2428
{!onOnboarding && isGuest(userRole) && <Redirect exact path={routes.HOME} to={routes.HOME_GUEST} />}
25-
{!onOnboarding && <Redirect exact path={routes.HOME_ACCEPT} to={routes.HOME} />}
2629
{onOnboarding && <Redirect exact path={routes.HOME} to={routes.HOME_PNM} />}
27-
{!isGuest(userRole) && <Redirect exact path={routes.HOME_GUEST} to={routes.HOME} />}
28-
{!isGuest(userRole) && <Redirect exact path={routes.HOME_PNM} to={routes.HOME} />}
29-
{!isGuest(userRole) && <Redirect exact path={routes.HOME_ONBOARDING} to={routes.HOME} />}
3030
<Route exact path={routes.HOME_SELECT_SUBTEAM} component={SelectSubteamPage} />
3131
<Route exact path={routes.HOME_ACCEPT} component={AcceptedPage} />
3232
<Route exact path={routes.HOME_ONBOARDING} component={OnboardingHomePage} />

src/frontend/src/pages/HomePage/OnboardingHomePage.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ const OnboardingHomePage = () => {
114114
/>
115115
</Box>
116116
</Box>
117-
<Box display={'flex'} justifyContent={'center'}>
118-
<Typography sx={{ fontSize: '2em', mt: 4, ml: 2 }}>Progress Bar</Typography>
119-
</Box>
120117
<Grid container display={'flex'}>
121118
<Grid
122119
item

src/frontend/src/tests/hooks/Users.hooks.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('user hooks', () => {
2525
expect(result.current.data).toEqual(exampleAllUsers);
2626
});
2727

28-
it('handles getting a single user', async () => {
28+
it.skip('handles getting a single user', async () => {
2929
const mockedGetSingleUser = getSingleUser as jest.Mock<Promise<AxiosResponse<User>>>;
3030
mockedGetSingleUser.mockReturnValue(mockPromiseAxiosResponse<User>(exampleAdminUser));
3131

0 commit comments

Comments
 (0)