Skip to content

Commit 0c4e302

Browse files
committed
Added redirection of onboarding to force user through the process
Added localhost storage of step to preserve progress Removed flash from redirection of onboarding
1 parent 86aa0b2 commit 0c4e302

8 files changed

Lines changed: 179 additions & 135 deletions

File tree

src/components/Onboarding/AdminOnboarding.tsx

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

src/components/Onboarding/Onboarding.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ type OnboardingLayoutProps = {
77
};
88

99
const OnboardingLayout = ({ currentPageChildren }: OnboardingLayoutProps) => {
10-
const { OnboardingComponent } = useOnboarding();
10+
const { switchingRoutes, OnboardingComponent } = useOnboarding();
11+
12+
if (switchingRoutes) return <></>;
1113

1214
return (
1315
<div className="flex flex-col h-full w-full bg-tertiary">
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { useRouter } from "next/router";
2+
import { Button, Text } from "../atomic";
3+
import StepTracker from "../atomic/StepTracker";
4+
import { OnboardingProps } from "./OnboardingContext";
5+
6+
const Onboarding = ({
7+
onFinish,
8+
currentStep,
9+
setCurrentStep,
10+
loading,
11+
setLoading,
12+
onboardingText,
13+
MAX_STEPS,
14+
}: OnboardingProps) => {
15+
const router = useRouter();
16+
17+
return (
18+
<div className="w-full flex flex-col items-center space-y-2 z-10">
19+
<Text h3 className="w-full">
20+
{currentStep}) {onboardingText[currentStep]["step"]}
21+
</Text>
22+
<div className="h-2" />
23+
<div className="flex w-full justify-end items-center box-border">
24+
<div className="w-full">
25+
<StepTracker steps={MAX_STEPS} currentStep={currentStep} />
26+
</div>
27+
<Button
28+
size="small"
29+
variant="inverted"
30+
disabled={currentStep === 1 || loading}
31+
onClick={() => {
32+
setLoading(true);
33+
const prevStep = Math.max(currentStep - 1, 1);
34+
router.push(onboardingText[prevStep]["route"]).then(() => {
35+
setCurrentStep(prevStep);
36+
setLoading(false);
37+
});
38+
}}
39+
>
40+
Back
41+
</Button>
42+
<div className="w-4" />
43+
<Button
44+
size="small"
45+
disabled={loading}
46+
onClick={() => {
47+
if (currentStep !== MAX_STEPS) {
48+
setLoading(true);
49+
const nextStep = Math.min(currentStep + 1, MAX_STEPS);
50+
router.push(onboardingText[nextStep]["route"]).then(() => {
51+
setCurrentStep(nextStep);
52+
setLoading(false);
53+
});
54+
} else {
55+
setLoading(true);
56+
onFinish();
57+
setLoading(false);
58+
}
59+
}}
60+
>
61+
{currentStep !== MAX_STEPS ? "Next" : "Finish"}
62+
</Button>
63+
</div>
64+
</div>
65+
);
66+
};
67+
68+
export default Onboarding;

src/components/Onboarding/OnboardingContext.tsx

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useRouter } from "next/router";
2-
import { createContext, useContext, useEffect, useState } from "react";
2+
import React, { createContext, useContext, useEffect, useState } from "react";
33
import {
44
UpdateProfileInput,
55
useUpdateProfileMutation,
@@ -9,21 +9,23 @@ import {
99
useAuthorizationLevel,
1010
useCurrentProfile,
1111
} from "../../hooks";
12-
import AdminOnboarding from "./AdminOnboarding";
12+
import OnboardingComponent from "./OnboardingComponent";
1313
import LocalStorage from "../../utils/localstorage";
1414

15+
interface OnboardingText {
16+
[key: number]: { step: string; route: string };
17+
}
18+
1519
export interface OnboardingProps {
1620
currentStep: number;
1721
setCurrentStep: (num: number) => void;
22+
loading: boolean;
23+
setLoading: (bool: boolean) => void;
24+
onboardingText: OnboardingText;
1825
MAX_STEPS: number;
19-
baseRoute: string;
2026
onFinish: () => void;
2127
}
2228

23-
interface OnboardingContextProps {
24-
OnboardingComponent: JSX.Element;
25-
}
26-
2729
const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => {
2830
switch (authLevel) {
2931
case AuthorizationLevel.Admin:
@@ -37,17 +39,79 @@ const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => {
3739
}
3840
};
3941

40-
const OnboardingContext = createContext<OnboardingContextProps | undefined>(
42+
const AdminOnboardingText = (baseRoute: string) => ({
43+
1: {
44+
step: "Set up your program homepage",
45+
route: baseRoute,
46+
},
47+
2: {
48+
step: "Edit your mentor applications",
49+
route: baseRoute + "applications/edit-mentor-app",
50+
},
51+
3: {
52+
step: "Edit your mentee applications",
53+
route: baseRoute + "applications/edit-mentee-app",
54+
},
55+
4: {
56+
step: "Edit your mentor profile structure",
57+
route: baseRoute + "mentors/edit-profile",
58+
},
59+
5: {
60+
step: "Edit your mentee profile structure",
61+
route: baseRoute + "mentees/edit-profile",
62+
},
63+
});
64+
65+
const MentorOnboardingText = (baseRoute: string) => ({
66+
1: {
67+
step: "Fill out your profile",
68+
route: baseRoute + "edit-profile",
69+
},
70+
2: {
71+
step: "Set your availability",
72+
route: baseRoute + "availability",
73+
},
74+
});
75+
76+
const MenteeOnboardingText = (baseRoute: string) => ({
77+
1: {
78+
step: "Fill out your profile",
79+
route: baseRoute + "edit-profile",
80+
},
81+
2: {
82+
step: "Browse through available mentors",
83+
route: baseRoute + "mentors",
84+
},
85+
});
86+
87+
const authLevelToText = (authLevel: AuthorizationLevel) => {
88+
switch (authLevel) {
89+
case AuthorizationLevel.Admin:
90+
return AdminOnboardingText;
91+
case AuthorizationLevel.Mentor:
92+
return MentorOnboardingText;
93+
default:
94+
return MenteeOnboardingText;
95+
}
96+
};
97+
98+
interface OnboardingContextType {
99+
switchingRoutes: boolean;
100+
OnboardingComponent: JSX.Element;
101+
}
102+
103+
const OnboardingContext = createContext<OnboardingContextType | undefined>(
41104
undefined
42105
);
43106

44107
const useOnboardingProvider = () => {
45108
const currentProfile = useCurrentProfile();
46-
const [updateProfileMutation] = useUpdateProfileMutation({
109+
const [updateProfile] = useUpdateProfileMutation({
47110
refetchQueries: ["getMyUser"],
48111
});
49112

50113
const authorizationLevel = useAuthorizationLevel();
114+
const [loading, setLoading] = useState(false);
51115
const [currentStep, setCurrentStep] = useState<number>(1);
52116
const router = useRouter();
53117

@@ -59,54 +123,55 @@ const useOnboardingProvider = () => {
59123
...currentProfile.currentProfile,
60124
showOnboarding: false,
61125
};
62-
updateProfileMutation({
126+
updateProfile({
63127
variables: {
64128
profileId: currentProfile.currentProfile!.profileId,
65129
data: updateProfileInput,
66130
},
67131
})
68-
.catch((err) => console.log(err))
69132
.then(() => {
70-
console.log("finished");
71-
});
72-
currentProfile.refetchCurrentProfile!();
73-
LocalStorage.delete("Onboarding Step");
133+
currentProfile.refetchCurrentProfile!();
134+
LocalStorage.delete("Onboarding Step");
135+
})
136+
.catch((err) => console.error(err));
74137
};
75138

76-
useEffect(() => {
77-
const onboardingStep = LocalStorage.get("Onboarding Step");
78-
if (onboardingStep && typeof onboardingStep == "number")
79-
setCurrentStep(onboardingStep);
80-
}, []);
81-
82-
const props = {
139+
const props: OnboardingProps = {
83140
currentStep,
84141
setCurrentStep: (num: number) => {
85-
setCurrentStep(num);
86142
LocalStorage.set("Onboarding Step", num);
143+
setCurrentStep(num);
87144
},
145+
loading,
146+
setLoading,
147+
onboardingText: authLevelToText(authorizationLevel)(baseRoute),
88148
MAX_STEPS,
89-
baseRoute,
90149
onFinish,
91150
};
92151

93-
const getOnboardingFromAuthorizationLevel = () => {
94-
switch (authorizationLevel) {
95-
case AuthorizationLevel.Admin:
96-
return <AdminOnboarding {...props} />;
97-
case AuthorizationLevel.Mentor:
98-
return <></>;
99-
case AuthorizationLevel.Mentee:
100-
return <></>;
101-
default:
102-
return <></>;
152+
const onboardingStep = LocalStorage.get("Onboarding Step");
153+
useEffect(() => {
154+
if (onboardingStep && typeof onboardingStep == "number") {
155+
setCurrentStep(onboardingStep);
103156
}
104-
};
157+
}, []);
105158

106-
const OnboardingComponent = getOnboardingFromAuthorizationLevel();
159+
if (
160+
authorizationLevel !== AuthorizationLevel.Admin &&
161+
router.asPath !== props.onboardingText[currentStep]["route"] &&
162+
onboardingStep &&
163+
typeof onboardingStep == "number"
164+
) {
165+
router.push(props.onboardingText[onboardingStep]["route"]);
166+
return {
167+
switchingRoutes: true,
168+
OnboardingComponent: <OnboardingComponent {...props} />,
169+
};
170+
}
107171

108172
return {
109-
OnboardingComponent,
173+
switchingRoutes: false,
174+
OnboardingComponent: <OnboardingComponent {...props} />,
110175
};
111176
};
112177

src/components/RichTextEditing/PublishButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const PublishButton = ({ programId, ...props }: PublishButtonProps) => {
2828
setSnackbarMessage({ text: "Homepage saved!" });
2929
})
3030
.catch((err) => {
31-
console.log("Fail: ", err);
31+
console.error("Fail: ", err);
3232
setLoading(false);
3333
});
3434
};

src/components/atomic/StepTracker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const StepTracker = ({ steps, currentStep }: StepTrackerProps) => (
1111
{range(1, steps + 1).map((i: number) => {
1212
return (
1313
<div
14+
key={i}
1415
className={`h-4 w-4 rounded-full ${
1516
i == currentStep ? "bg-secondary" : "bg-inactive"
1617
}`}

0 commit comments

Comments
 (0)