Skip to content

Commit

Permalink
Merge pull request #3090 from Northeastern-Electric-Racing/#2816-Conf…
Browse files Browse the repository at this point in the history
…irmOnboardingChecklist-modal

#2816 confirm onboarding checklist modal
  • Loading branch information
Peyton-McKee authored Jan 3, 2025
2 parents 25fe8b6 + ecc8c8c commit 63ef38d
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/backend/src/controllers/users.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default class UsersController {

static async toggleCompletedOnboarding(req: Request, res: Response, next: NextFunction) {
try {
const { userId } = req.params;
const { userId } = req.currentUser;

await UsersService.toggleCompletedOnboarding(userId, req.organization);

Expand Down
2 changes: 1 addition & 1 deletion src/backend/src/routes/users.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ userRouter.post(
UsersController.updateUserSettings
);
userRouter.post('/:userId/change-role', isRole(body('role')), validateInputs, UsersController.updateUserRole);
userRouter.post('/:userId/toggle-completed-onboarding', UsersController.toggleCompletedOnboarding);
userRouter.post('/toggle-completed-onboarding', UsersController.toggleCompletedOnboarding);
userRouter.post('/auth/login', UsersController.logUserIn);
userRouter.post('/auth/login/dev', UsersController.logUserInDev);
userRouter.post(
Expand Down
18 changes: 17 additions & 1 deletion src/backend/src/services/users.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ export default class UsersService {
}

/**
* Toggles the completed onboarding status of a user
* Toggles the completed onboarding status of a user and elevates role to member if user completed onboarding
* @param user the user who's onboarding status is being toggled
* @returns the updated user
*/
Expand All @@ -409,8 +409,24 @@ export default class UsersService {
...getUserQueryArgs(organization.organizationId)
});

if (updatedUser.completedOnboarding) {
const currentRole = updatedUser.roles.find((role) => role.organizationId === organization.organizationId);

if (currentRole && currentRole.roleType !== RoleEnum.MEMBER) {
await prisma.role.update({
where: {
uniqueRole: { userId, organizationId: organization.organizationId }
},
data: {
roleType: RoleEnum.MEMBER
}
});
}
}

return userTransformer(updatedUser);
}

/**
* Gets a user's secure settings
* @param userId the id of user who's secure settings are being returned
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/src/apis/users.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ export const updateUserScheduleSettings = (settings: SetUserScheduleSettingsPayl
export const updateUserRole = (id: string, role: string) => {
return axios.post<{ message: string }>(apiUrls.userRoleByUserId(id), { role });
};

export const toggleCompletedOnboarding = () => {
return axios.post<{ message: string }>(apiUrls.toggleCompletedOnboarding());
};
22 changes: 21 additions & 1 deletion src/frontend/src/hooks/users.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
getCurrentUserSecureSettings,
getUserSecureSettings,
getUserScheduleSettings,
updateUserScheduleSettings
updateUserScheduleSettings,
toggleCompletedOnboarding
} from '../apis/users.api';
import {
User,
Expand Down Expand Up @@ -233,3 +234,22 @@ export const useUpdateUserRole = () => {
}
);
};

/**
* Custom React Hook to toggle the current user's completed onboarding status.
*/
export const useToggleCompletedOnboarding = () => {
const queryClient = useQueryClient();
return useMutation<{ message: string }, Error>(
['users', 'toggle-onboarding'],
async () => {
const { data } = await toggleCompletedOnboarding();
return data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(['users']);
}
}
);
};
69 changes: 41 additions & 28 deletions src/frontend/src/pages/HomePage/OnboardingHomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import React, { useEffect } from 'react';
import { Box, Grid, Typography, useTheme } from '@mui/material';
import { Box, Grid, Typography } from '@mui/material';
import PageLayout from '../../components/PageLayout';
import { useCurrentOrganization } from '../../hooks/organizations.hooks';
import React, { useEffect, useState } from 'react';
import LoadingIndicator from '../../components/LoadingIndicator';
import ErrorPage from '../ErrorPage';
import { useHomePageContext } from '../../app/HomePageContext';
import ChecklistSection from './components/ChecklistSection';
import OnboardingInfoSection from './components/OnboardingInfoSection';
import OnboardingProgressBar from '../../components/OnboardingProgressBar';
import ConfirmOnboardingChecklistModal from './components/ConfirmOnboardingChecklistModal';
import { NERButton } from '../../components/NERButton';
import { useToggleCompletedOnboarding } from '../../hooks/users.hooks';
import { useToast } from '../../hooks/toasts.hooks';

const OnboardingHomePage = () => {
const { data: organization, isError, error, isLoading } = useCurrentOrganization();
const { setCurrentHomePage } = useHomePageContext();
const theme = useTheme();
const [isModalOpen, setModalOpen] = useState(false);

const toast = useToast();

const toggleCompletedOnboarding = useToggleCompletedOnboarding();

useEffect(() => {
setCurrentHomePage('onboarding');
Expand All @@ -22,13 +28,31 @@ const OnboardingHomePage = () => {
if (!organization || isLoading) return <LoadingIndicator />;
if (isError) return <ErrorPage message={error?.message} />;

const handleOpenModal = () => {
setModalOpen(true);
};

const handleCloseModal = () => {
setModalOpen(false);
};

const handleConfirmModal = async () => {
await toggleCompletedOnboarding.mutateAsync();
toast.success('Role updated successfully!');
setModalOpen(false);
};

return (
<PageLayout title="Home" hidePageTitle>
<Grid container display="flex" alignItems="center" justifyContent={'space-between'} padding={1} marginTop={4}>
<Grid container display={'flex'} alignItems={'center'} marginLeft={2} marginTop={4}>
<Grid item xs={12} md={7}>
<Typography sx={{ fontSize: '2.5em' }}>Welcome to the {organization.name} Team</Typography>
</Grid>
<NERButton variant="contained">Finished?</NERButton>
<Grid item xs={12} md={5} sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<NERButton variant="contained" onClick={handleOpenModal}>
Finished?
</NERButton>
</Grid>
</Grid>
<Grid
container
Expand All @@ -38,29 +62,10 @@ const OnboardingHomePage = () => {
flexDirection: 'column'
}}
>
<Box display="flex" justifyContent="center">
<Box
sx={{
backgroundColor: theme.palette.background.paper,
borderRadius: 5,
p: 3.5,
flexGrow: 1,
width: '100%',
mt: 5,
ml: 4,
display: 'flex',
alignItems: 'center'
}}
>
<OnboardingProgressBar
value={50}
text={'Complete'}
typographySx={{ fontSize: '1.2em' }}
progressBarSx={{ height: '3vh' }}
/>
</Box>
<Box display={'flex'} justifyContent={'center'}>
<Typography sx={{ fontSize: '2em', mt: 4, ml: 2 }}>Progress Bar</Typography>
</Box>
<Grid container display="flex">
<Grid container display={'flex'}>
<Grid
item
xs={12}
Expand All @@ -82,6 +87,14 @@ const OnboardingHomePage = () => {
</Grid>
</Grid>
</Grid>
{isModalOpen && (
<ConfirmOnboardingChecklistModal
open={isModalOpen}
onHide={handleCloseModal}
onConfirm={handleConfirmModal}
title="Confirm Onboarding Checklist"
/>
)}
</PageLayout>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { Typography, Box } from '@mui/material';
import NERModal from '../../../components/NERModal';

interface ConfirmOnboardingChecklistModalProps {
open: boolean;
onHide: () => void;
onConfirm: () => void;
title?: string;
message?: string;
}

const ConfirmOnboardingChecklistModal: React.FC<ConfirmOnboardingChecklistModalProps> = ({
open,
onHide,
onConfirm,
title = 'Confirm Action'
}) => {
return (
<NERModal open={open} onHide={onHide} title={title} onSubmit={onConfirm}>
<Box
sx={{
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
alignItems: 'center'
}}
>
<Typography sx={{ marginBottom: '1rem', fontSize: '1.2rem', fontWeight: 'bold' }}>
Looks like you completed everything on the onboarding checklist!
</Typography>

<Typography sx={{ marginBottom: '1rem', fontSize: '1.2rem', fontWeight: 'bold' }}>
You sure you want to submit?
</Typography>

<Typography sx={{ marginBottom: '1.5rem', fontSize: '0.9rem', color: 'darkgray', fontStyle: 'italic' }}>
(After you submit, you will be officially onboarded into NER!)
</Typography>
</Box>
</NERModal>
);
};

export default ConfirmOnboardingChecklistModal;
2 changes: 2 additions & 0 deletions src/frontend/src/utils/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const userFavoriteProjects = (id: string) => `${usersById(id)}/favorite-projects
const userSecureSettings = (id: string) => `${usersById(id)}/secure-settings`;
const userScheduleSettings = (id: string) => `${usersById(id)}/schedule-settings`;
const userScheduleSettingsSet = () => `${users()}/schedule-settings/set`;
const toggleCompletedOnboarding = () => `${users()}/toggle-completed-onboarding`;

/**************** Projects Endpoints ****************/
const projects = () => `${API_URL}/projects`;
Expand Down Expand Up @@ -221,6 +222,7 @@ export const apiUrls = {
userSecureSettings,
userScheduleSettings,
userScheduleSettingsSet,
toggleCompletedOnboarding,

projects,
allProjects,
Expand Down

0 comments on commit 63ef38d

Please sign in to comment.