From f4fd23af65f9d7fe4226cfc5319d488f63845f2a Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 23 Aug 2021 14:39:20 -0700 Subject: [PATCH 1/5] Rudimentary onboarding components --- src/components/Onboarding/AdminOnboarding.tsx | 24 +++++++++++++++++++ src/components/Onboarding/OnboardingModal.tsx | 21 ++++++++++++++++ src/components/atomic/StepTracker.tsx | 23 ++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/components/Onboarding/AdminOnboarding.tsx create mode 100644 src/components/Onboarding/OnboardingModal.tsx create mode 100644 src/components/atomic/StepTracker.tsx diff --git a/src/components/Onboarding/AdminOnboarding.tsx b/src/components/Onboarding/AdminOnboarding.tsx new file mode 100644 index 00000000..6ce399e0 --- /dev/null +++ b/src/components/Onboarding/AdminOnboarding.tsx @@ -0,0 +1,24 @@ +import { useState } from "react"; +import { Button, Checkbox } from "../atomic"; +import StepTracker from "../atomic/StepTracker"; + +const AdminOnboarding = () => { + const [dontShowAgain, setDontShowAgain] = useState(false); + const [currentStep, setCurrentStep] = useState(1); + return ( +
+ +
+ setDontShowAgain(true)} + label="Do not show this popup again for this program." + /> +
+ + +
+
+
+ ); +}; diff --git a/src/components/Onboarding/OnboardingModal.tsx b/src/components/Onboarding/OnboardingModal.tsx new file mode 100644 index 00000000..fe6cf4ad --- /dev/null +++ b/src/components/Onboarding/OnboardingModal.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { Modal, Text } from "../atomic"; + +type OnboardingModalProps = { + isOpen: boolean; + onClose: () => void; +}; + +const OnboardingModal = ({ isOpen, onClose }: OnboardingModalProps) => { + return ( + +
+ + Let's get started with Mentor Center! + +
+
+ ); +}; + +export default OnboardingModal; diff --git a/src/components/atomic/StepTracker.tsx b/src/components/atomic/StepTracker.tsx new file mode 100644 index 00000000..6d835e61 --- /dev/null +++ b/src/components/atomic/StepTracker.tsx @@ -0,0 +1,23 @@ +import { range } from "lodash"; +import React, { HTMLAttributes } from "react"; + +type StepTrackerProps = HTMLAttributes & { + steps: number; + currentStep: number; +}; + +const StepTracker = ({ steps, currentStep }: StepTrackerProps) => ( +
+ {range(1, steps).map((i: number) => { + return ( +
+ ); + })} +
+); + +export default StepTracker; From f391d5bb66b3c57b4859da6920a1a66ce42b39c2 Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 23 Aug 2021 20:16:35 -0700 Subject: [PATCH 2/5] Added carousel with onboarding --- src/components/Onboarding/AdminOnboarding.tsx | 119 +++++++++++++++--- src/components/Onboarding/OnboardingModal.tsx | 23 ++-- src/components/TabFooterMenu.tsx | 2 +- src/components/atomic/StepTracker.tsx | 4 +- src/graphql/queries/getMyUser.graphql | 1 + src/layouts/PageContainer.tsx | 2 +- src/layouts/TabLayout/TabLayout.tsx | 47 ++++++- .../program/[slug]/[profileRoute]/index.tsx | 2 +- 8 files changed, 167 insertions(+), 33 deletions(-) diff --git a/src/components/Onboarding/AdminOnboarding.tsx b/src/components/Onboarding/AdminOnboarding.tsx index 6ce399e0..9d5e9594 100644 --- a/src/components/Onboarding/AdminOnboarding.tsx +++ b/src/components/Onboarding/AdminOnboarding.tsx @@ -1,24 +1,113 @@ -import { useState } from "react"; -import { Button, Checkbox } from "../atomic"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; +import { Button, Text } from "../atomic"; import StepTracker from "../atomic/StepTracker"; -const AdminOnboarding = () => { - const [dontShowAgain, setDontShowAgain] = useState(false); +type AdminOnboardingProps = { + onClose: () => void; +}; + +const ADMIN_STEPS = 6; + +const AdminOnboarding = ({ onClose }: AdminOnboardingProps) => { const [currentStep, setCurrentStep] = useState(1); + const router = useRouter(); + + const baseRoute = `/program/${router.query.slug}/${router.query.profileRoute}/`; + useEffect(() => { + if (currentStep === 1 && router.asPath !== baseRoute) { + router.push(baseRoute); + } + }, []); + + const getCurrentStep = () => { + switch (currentStep) { + case 1: + return "Set up your program homepage"; + case 2: + return "Edit your mentor applications"; + case 3: + return "Edit your mentee applications"; + case 4: + return "Edit your mentor profile structure"; + case 5: + return "Edit your mentee profile structure"; + case 6: + return "All Done!"; + } + }; + + const getStepRoute = (step: number) => { + switch (step) { + case 2: + return baseRoute + "applications/edit-mentor-app"; + case 3: + return baseRoute + "applications/edit-mentee-app"; + case 4: + return baseRoute + "mentors/edit-profile"; + case 5: + return baseRoute + "mentees/edit-profile"; + } + return baseRoute; + }; + return ( -
- -
- setDontShowAgain(true)} - label="Do not show this popup again for this program." - /> -
- - +
+ + {currentStep}) {getCurrentStep()} + + +
+ +
+ +
+
); }; + +export default AdminOnboarding; diff --git a/src/components/Onboarding/OnboardingModal.tsx b/src/components/Onboarding/OnboardingModal.tsx index fe6cf4ad..157b9c82 100644 --- a/src/components/Onboarding/OnboardingModal.tsx +++ b/src/components/Onboarding/OnboardingModal.tsx @@ -1,21 +1,22 @@ import React from "react"; -import { Modal, Text } from "../atomic"; +import { Card, Text } from "../atomic"; +import AdminOnboarding from "./AdminOnboarding"; -type OnboardingModalProps = { - isOpen: boolean; +type OnboardingProps = { onClose: () => void; }; -const OnboardingModal = ({ isOpen, onClose }: OnboardingModalProps) => { +const OnboardingScreen = ({ onClose }: OnboardingProps) => { return ( - -
- - Let's get started with Mentor Center! +
+ + + Welcome to your new program! -
- + + +
); }; -export default OnboardingModal; +export default OnboardingScreen; diff --git a/src/components/TabFooterMenu.tsx b/src/components/TabFooterMenu.tsx index 0be9c636..9ff15cd1 100644 --- a/src/components/TabFooterMenu.tsx +++ b/src/components/TabFooterMenu.tsx @@ -17,7 +17,7 @@ const TabFooterMenu = () => { const myData = data.getMyUser; return ( -
+
diff --git a/src/components/atomic/StepTracker.tsx b/src/components/atomic/StepTracker.tsx index 6d835e61..63a195c3 100644 --- a/src/components/atomic/StepTracker.tsx +++ b/src/components/atomic/StepTracker.tsx @@ -11,8 +11,8 @@ const StepTracker = ({ steps, currentStep }: StepTrackerProps) => ( {range(1, steps).map((i: number) => { return (
); diff --git a/src/graphql/queries/getMyUser.graphql b/src/graphql/queries/getMyUser.graphql index 763f1709..d79a013a 100644 --- a/src/graphql/queries/getMyUser.graphql +++ b/src/graphql/queries/getMyUser.graphql @@ -12,6 +12,7 @@ query getMyUser { profileJson tagsJson bio + showOnboarding program { programId name diff --git a/src/layouts/PageContainer.tsx b/src/layouts/PageContainer.tsx index bd16d7b3..4fcf0d4f 100644 --- a/src/layouts/PageContainer.tsx +++ b/src/layouts/PageContainer.tsx @@ -3,7 +3,7 @@ import { HTMLAttributes } from "react"; const PageContainer = ({ children }: HTMLAttributes) => { // TODO: Add responsiveness return ( -
+
{children}
); diff --git a/src/layouts/TabLayout/TabLayout.tsx b/src/layouts/TabLayout/TabLayout.tsx index fa3b4a60..e27790be 100644 --- a/src/layouts/TabLayout/TabLayout.tsx +++ b/src/layouts/TabLayout/TabLayout.tsx @@ -3,7 +3,13 @@ import Link from "next/link"; import { useRouter } from "next/router"; import React, { ReactNode, useEffect, useState } from "react"; import { Text } from "../../components/atomic"; +import OnboardingScreen from "../../components/Onboarding/OnboardingModal"; import TabFooterMenu from "../../components/TabFooterMenu"; +import { + UpdateProfileInput, + useUpdateProfileMutation, +} from "../../generated/graphql"; +import { useCurrentProfile } from "../../hooks"; import LocalStorage from "../../utils/localstorage"; import ProgramDropdown from "./ProgramDropdown"; @@ -76,15 +82,52 @@ const TabLayout: React.FC & { Icon: React.FC>; }>; } = ({ children, currentPageChildren }) => { + const currentProfile = useCurrentProfile(); + const [updateProfileMutation] = useUpdateProfileMutation({ + refetchQueries: ["getMyUser"], + }); + + const tabLayoutStyles = classNames({ + "flex flex-col flex-grow h-screen bg-white shadow-lg relative box-border": + true, + "pointer-events-none bg-black opacity-25": + currentProfile.currentProfile?.showOnboarding, + }); + return (
-
+
{children}
-
{currentPageChildren}
+
+
+ {currentPageChildren} +
+ {currentProfile.currentProfile?.showOnboarding && ( + { + const updateProfileInput: UpdateProfileInput = { + ...currentProfile.currentProfile, + showOnboarding: false, + }; + updateProfileMutation({ + variables: { + profileId: currentProfile.currentProfile.profileId, + data: updateProfileInput, + }, + }).catch((err) => console.log(err)); + currentProfile.refetchCurrentProfile(); + }} + /> + )} +
); }; diff --git a/src/pages/program/[slug]/[profileRoute]/index.tsx b/src/pages/program/[slug]/[profileRoute]/index.tsx index 21579d0f..d1a48d1a 100644 --- a/src/pages/program/[slug]/[profileRoute]/index.tsx +++ b/src/pages/program/[slug]/[profileRoute]/index.tsx @@ -124,7 +124,7 @@ const AdminHome = ({ {name} -
+
From 86aa0b255c49a71b913debb3aa27c42fb5227b5f Mon Sep 17 00:00:00 2001 From: Ashley Date: Sun, 29 Aug 2021 12:55:03 -0700 Subject: [PATCH 3/5] Abstracted onboarding component --- src/components/Onboarding/AdminOnboarding.tsx | 91 +++++------- src/components/Onboarding/Onboarding.tsx | 28 ++++ .../Onboarding/OnboardingContext.tsx | 132 ++++++++++++++++++ src/components/Onboarding/OnboardingModal.tsx | 22 --- src/components/atomic/StepTracker.tsx | 2 +- src/layouts/TabLayout/TabLayout.tsx | 36 +---- src/pages/_app.tsx | 7 +- tailwind.config.js | 25 +++- 8 files changed, 227 insertions(+), 116 deletions(-) create mode 100644 src/components/Onboarding/Onboarding.tsx create mode 100644 src/components/Onboarding/OnboardingContext.tsx delete mode 100644 src/components/Onboarding/OnboardingModal.tsx diff --git a/src/components/Onboarding/AdminOnboarding.tsx b/src/components/Onboarding/AdminOnboarding.tsx index 9d5e9594..bad53f63 100644 --- a/src/components/Onboarding/AdminOnboarding.tsx +++ b/src/components/Onboarding/AdminOnboarding.tsx @@ -1,25 +1,17 @@ import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; import { Button, Text } from "../atomic"; import StepTracker from "../atomic/StepTracker"; +import { OnboardingProps } from "./OnboardingContext"; -type AdminOnboardingProps = { - onClose: () => void; -}; - -const ADMIN_STEPS = 6; - -const AdminOnboarding = ({ onClose }: AdminOnboardingProps) => { - const [currentStep, setCurrentStep] = useState(1); +const AdminOnboarding = ({ + onFinish, + currentStep, + setCurrentStep, + MAX_STEPS, + baseRoute, +}: OnboardingProps) => { const router = useRouter(); - const baseRoute = `/program/${router.query.slug}/${router.query.profileRoute}/`; - useEffect(() => { - if (currentStep === 1 && router.asPath !== baseRoute) { - router.push(baseRoute); - } - }, []); - const getCurrentStep = () => { switch (currentStep) { case 1: @@ -56,55 +48,40 @@ const AdminOnboarding = ({ onClose }: AdminOnboardingProps) => { {currentStep}) {getCurrentStep()} - -
+
+
+
+ +
-
- -
- -
+ .push(getStepRoute(nextStep)) + .then(() => setCurrentStep(nextStep)); + } else { + onFinish(); + } + }} + > + {currentStep !== MAX_STEPS - 1 ? "Next" : "Finish"} +
); diff --git a/src/components/Onboarding/Onboarding.tsx b/src/components/Onboarding/Onboarding.tsx new file mode 100644 index 00000000..5181aede --- /dev/null +++ b/src/components/Onboarding/Onboarding.tsx @@ -0,0 +1,28 @@ +import React, { ReactNode } from "react"; +import { Card, Text } from "../atomic"; +import { useOnboarding } from "./OnboardingContext"; + +type OnboardingLayoutProps = { + currentPageChildren: ReactNode; +}; + +const OnboardingLayout = ({ currentPageChildren }: OnboardingLayoutProps) => { + const { OnboardingComponent } = useOnboarding(); + + return ( +
+
{currentPageChildren}
+ +
+ + + Welcome to your new program! + + {OnboardingComponent} + +
+
+ ); +}; + +export default OnboardingLayout; diff --git a/src/components/Onboarding/OnboardingContext.tsx b/src/components/Onboarding/OnboardingContext.tsx new file mode 100644 index 00000000..143b9870 --- /dev/null +++ b/src/components/Onboarding/OnboardingContext.tsx @@ -0,0 +1,132 @@ +import { useRouter } from "next/router"; +import { createContext, useContext, useEffect, useState } from "react"; +import { + UpdateProfileInput, + useUpdateProfileMutation, +} from "../../generated/graphql"; +import { + AuthorizationLevel, + useAuthorizationLevel, + useCurrentProfile, +} from "../../hooks"; +import AdminOnboarding from "./AdminOnboarding"; +import LocalStorage from "../../utils/localstorage"; + +export interface OnboardingProps { + currentStep: number; + setCurrentStep: (num: number) => void; + MAX_STEPS: number; + baseRoute: string; + onFinish: () => void; +} + +interface OnboardingContextProps { + OnboardingComponent: JSX.Element; +} + +const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => { + switch (authLevel) { + case AuthorizationLevel.Admin: + return 5; + case AuthorizationLevel.Mentor: + return 2; + case AuthorizationLevel.Mentee: + return 2; + default: + return 0; + } +}; + +const OnboardingContext = createContext( + undefined +); + +const useOnboardingProvider = () => { + const currentProfile = useCurrentProfile(); + const [updateProfileMutation] = useUpdateProfileMutation({ + refetchQueries: ["getMyUser"], + }); + + const authorizationLevel = useAuthorizationLevel(); + const [currentStep, setCurrentStep] = useState(1); + const router = useRouter(); + + const MAX_STEPS = authorizationLevelToMaxSteps(authorizationLevel); + const baseRoute = `/program/${router.query.slug}/${router.query.profileRoute}/`; + + const onFinish = () => { + const updateProfileInput: UpdateProfileInput = { + ...currentProfile.currentProfile, + showOnboarding: false, + }; + updateProfileMutation({ + variables: { + profileId: currentProfile.currentProfile!.profileId, + data: updateProfileInput, + }, + }) + .catch((err) => console.log(err)) + .then(() => { + console.log("finished"); + }); + currentProfile.refetchCurrentProfile!(); + LocalStorage.delete("Onboarding Step"); + }; + + useEffect(() => { + const onboardingStep = LocalStorage.get("Onboarding Step"); + if (onboardingStep && typeof onboardingStep == "number") + setCurrentStep(onboardingStep); + }, []); + + const props = { + currentStep, + setCurrentStep: (num: number) => { + setCurrentStep(num); + LocalStorage.set("Onboarding Step", num); + }, + MAX_STEPS, + baseRoute, + onFinish, + }; + + const getOnboardingFromAuthorizationLevel = () => { + switch (authorizationLevel) { + case AuthorizationLevel.Admin: + return ; + case AuthorizationLevel.Mentor: + return <>; + case AuthorizationLevel.Mentee: + return <>; + default: + return <>; + } + }; + + const OnboardingComponent = getOnboardingFromAuthorizationLevel(); + + return { + OnboardingComponent, + }; +}; + +export const OnboardingProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + const value = useOnboardingProvider(); + return ( + + {children} + + ); +}; + +export const useOnboarding = () => { + const context = useContext(OnboardingContext); + if (context === undefined) { + throw new Error("useOnboarding() must be within OnboardingProvider"); + } + return context; +}; diff --git a/src/components/Onboarding/OnboardingModal.tsx b/src/components/Onboarding/OnboardingModal.tsx deleted file mode 100644 index 157b9c82..00000000 --- a/src/components/Onboarding/OnboardingModal.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import { Card, Text } from "../atomic"; -import AdminOnboarding from "./AdminOnboarding"; - -type OnboardingProps = { - onClose: () => void; -}; - -const OnboardingScreen = ({ onClose }: OnboardingProps) => { - return ( -
- - - Welcome to your new program! - - - -
- ); -}; - -export default OnboardingScreen; diff --git a/src/components/atomic/StepTracker.tsx b/src/components/atomic/StepTracker.tsx index 63a195c3..b83419c9 100644 --- a/src/components/atomic/StepTracker.tsx +++ b/src/components/atomic/StepTracker.tsx @@ -8,7 +8,7 @@ type StepTrackerProps = HTMLAttributes & { const StepTracker = ({ steps, currentStep }: StepTrackerProps) => (
- {range(1, steps).map((i: number) => { + {range(1, steps + 1).map((i: number) => { return (
& { }>; } = ({ children, currentPageChildren }) => { const currentProfile = useCurrentProfile(); - const [updateProfileMutation] = useUpdateProfileMutation({ - refetchQueries: ["getMyUser"], - }); const tabLayoutStyles = classNames({ "flex flex-col flex-grow h-screen bg-white shadow-lg relative box-border": @@ -103,29 +96,10 @@ const TabLayout: React.FC & {
-
- {currentPageChildren} -
- {currentProfile.currentProfile?.showOnboarding && ( - { - const updateProfileInput: UpdateProfileInput = { - ...currentProfile.currentProfile, - showOnboarding: false, - }; - updateProfileMutation({ - variables: { - profileId: currentProfile.currentProfile.profileId, - data: updateProfileInput, - }, - }).catch((err) => console.log(err)); - currentProfile.refetchCurrentProfile(); - }} - /> + {currentProfile.currentProfile?.showOnboarding ? ( + + ) : ( + currentPageChildren )}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index f84ad570..fbcce0c8 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -11,10 +11,11 @@ import { AppProps } from "next/app"; import { ReactElement } from "react"; import "tailwindcss/tailwind.css"; import AuthLoadingScreen from "../layouts/AuthLoadingScreen"; +import { AuthProvider } from "../utils/firebase/auth"; +import { OnboardingProvider } from "../components/Onboarding/OnboardingContext"; import { SnackbarProvider } from "../notifications/SnackbarContext"; import "../styles/globals.css"; import Page from "../types/Page"; -import { AuthProvider } from "../utils/firebase/auth"; import firebase from "../utils/firebase/firebase"; const uploadLink = createUploadLink({ uri: process.env.NEXT_PUBLIC_API_URL }); @@ -68,7 +69,9 @@ function MyApp({ Component, pageProps }: CustomAppProps) { - {getLayout(, pageProps)} + + {getLayout(, pageProps)} + diff --git a/tailwind.config.js b/tailwind.config.js index 131a67ea..f677fb6a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -34,6 +34,9 @@ module.exports = { bold: 700, }, extend: { + animation: { + "border-pulse": "border-pulse 1s ease-in-out infinite", + }, borderWidth: { 1.5: "1.5px", 3: "3px", @@ -48,10 +51,26 @@ module.exports = { "se-resize": "se-resize", "sw-resize": "sw-resize", }, + fill: { + none: "none", + }, height: { "3/4-screen": "75vh", "9/10": "90%", }, + keyframes: { + "border-pulse": { + "0%": { + "-webkit-box-shadow": "0 0 4px 3px rgba(0,0,0, 0.3)", + }, + "50%": { + "-webkit-box-shadow": "0 0 4px 6px rgba(0,0,0, 0.9)", + }, + "100%": { + "-webkit-box-shadow": "0 0 4px 3px rgba(0,0,0, 0.3)", + }, + }, + }, maxHeight: { "3/4": "75%", }, @@ -68,6 +87,9 @@ module.exports = { 300: "75rem", 400: "100rem", }, + transitionDuration: { + 3000: "3000ms", + }, transitionProperty: { background: "background-color", }, @@ -82,9 +104,6 @@ module.exports = { stroke: (theme) => ({ white: theme("colors.white"), }), - fill: { - none: "none", - }, }, }, variants: { From 0c4e302050cc05d62d458b7c17146c1cd334db63 Mon Sep 17 00:00:00 2001 From: Ashley Date: Sun, 5 Sep 2021 11:38:16 -0700 Subject: [PATCH 4/5] Added redirection of onboarding to force user through the process Added localhost storage of step to preserve progress Removed flash from redirection of onboarding --- src/components/Onboarding/AdminOnboarding.tsx | 90 ------------ src/components/Onboarding/Onboarding.tsx | 4 +- .../Onboarding/OnboardingComponent.tsx | 68 +++++++++ .../Onboarding/OnboardingContext.tsx | 139 +++++++++++++----- .../RichTextEditing/PublishButton.tsx | 2 +- src/components/atomic/StepTracker.tsx | 1 + .../[slug]/[profileRoute]/edit-profile.tsx | 4 +- .../mentees/edit-profile/index.tsx | 6 +- 8 files changed, 179 insertions(+), 135 deletions(-) delete mode 100644 src/components/Onboarding/AdminOnboarding.tsx create mode 100644 src/components/Onboarding/OnboardingComponent.tsx diff --git a/src/components/Onboarding/AdminOnboarding.tsx b/src/components/Onboarding/AdminOnboarding.tsx deleted file mode 100644 index bad53f63..00000000 --- a/src/components/Onboarding/AdminOnboarding.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useRouter } from "next/router"; -import { Button, Text } from "../atomic"; -import StepTracker from "../atomic/StepTracker"; -import { OnboardingProps } from "./OnboardingContext"; - -const AdminOnboarding = ({ - onFinish, - currentStep, - setCurrentStep, - MAX_STEPS, - baseRoute, -}: OnboardingProps) => { - const router = useRouter(); - - const getCurrentStep = () => { - switch (currentStep) { - case 1: - return "Set up your program homepage"; - case 2: - return "Edit your mentor applications"; - case 3: - return "Edit your mentee applications"; - case 4: - return "Edit your mentor profile structure"; - case 5: - return "Edit your mentee profile structure"; - case 6: - return "All Done!"; - } - }; - - const getStepRoute = (step: number) => { - switch (step) { - case 2: - return baseRoute + "applications/edit-mentor-app"; - case 3: - return baseRoute + "applications/edit-mentee-app"; - case 4: - return baseRoute + "mentors/edit-profile"; - case 5: - return baseRoute + "mentees/edit-profile"; - } - return baseRoute; - }; - - return ( -
- - {currentStep}) {getCurrentStep()} - -
-
-
- -
- -
- -
-
- ); -}; - -export default AdminOnboarding; diff --git a/src/components/Onboarding/Onboarding.tsx b/src/components/Onboarding/Onboarding.tsx index 5181aede..a632e7ff 100644 --- a/src/components/Onboarding/Onboarding.tsx +++ b/src/components/Onboarding/Onboarding.tsx @@ -7,7 +7,9 @@ type OnboardingLayoutProps = { }; const OnboardingLayout = ({ currentPageChildren }: OnboardingLayoutProps) => { - const { OnboardingComponent } = useOnboarding(); + const { switchingRoutes, OnboardingComponent } = useOnboarding(); + + if (switchingRoutes) return <>; return (
diff --git a/src/components/Onboarding/OnboardingComponent.tsx b/src/components/Onboarding/OnboardingComponent.tsx new file mode 100644 index 00000000..bae8a6c5 --- /dev/null +++ b/src/components/Onboarding/OnboardingComponent.tsx @@ -0,0 +1,68 @@ +import { useRouter } from "next/router"; +import { Button, Text } from "../atomic"; +import StepTracker from "../atomic/StepTracker"; +import { OnboardingProps } from "./OnboardingContext"; + +const Onboarding = ({ + onFinish, + currentStep, + setCurrentStep, + loading, + setLoading, + onboardingText, + MAX_STEPS, +}: OnboardingProps) => { + const router = useRouter(); + + return ( +
+ + {currentStep}) {onboardingText[currentStep]["step"]} + +
+
+
+ +
+ +
+ +
+
+ ); +}; + +export default Onboarding; diff --git a/src/components/Onboarding/OnboardingContext.tsx b/src/components/Onboarding/OnboardingContext.tsx index 143b9870..bc6c06cf 100644 --- a/src/components/Onboarding/OnboardingContext.tsx +++ b/src/components/Onboarding/OnboardingContext.tsx @@ -1,5 +1,5 @@ import { useRouter } from "next/router"; -import { createContext, useContext, useEffect, useState } from "react"; +import React, { createContext, useContext, useEffect, useState } from "react"; import { UpdateProfileInput, useUpdateProfileMutation, @@ -9,21 +9,23 @@ import { useAuthorizationLevel, useCurrentProfile, } from "../../hooks"; -import AdminOnboarding from "./AdminOnboarding"; +import OnboardingComponent from "./OnboardingComponent"; import LocalStorage from "../../utils/localstorage"; +interface OnboardingText { + [key: number]: { step: string; route: string }; +} + export interface OnboardingProps { currentStep: number; setCurrentStep: (num: number) => void; + loading: boolean; + setLoading: (bool: boolean) => void; + onboardingText: OnboardingText; MAX_STEPS: number; - baseRoute: string; onFinish: () => void; } -interface OnboardingContextProps { - OnboardingComponent: JSX.Element; -} - const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => { switch (authLevel) { case AuthorizationLevel.Admin: @@ -37,17 +39,79 @@ const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => { } }; -const OnboardingContext = createContext( +const AdminOnboardingText = (baseRoute: string) => ({ + 1: { + step: "Set up your program homepage", + route: baseRoute, + }, + 2: { + step: "Edit your mentor applications", + route: baseRoute + "applications/edit-mentor-app", + }, + 3: { + step: "Edit your mentee applications", + route: baseRoute + "applications/edit-mentee-app", + }, + 4: { + step: "Edit your mentor profile structure", + route: baseRoute + "mentors/edit-profile", + }, + 5: { + step: "Edit your mentee profile structure", + route: baseRoute + "mentees/edit-profile", + }, +}); + +const MentorOnboardingText = (baseRoute: string) => ({ + 1: { + step: "Fill out your profile", + route: baseRoute + "edit-profile", + }, + 2: { + step: "Set your availability", + route: baseRoute + "availability", + }, +}); + +const MenteeOnboardingText = (baseRoute: string) => ({ + 1: { + step: "Fill out your profile", + route: baseRoute + "edit-profile", + }, + 2: { + step: "Browse through available mentors", + route: baseRoute + "mentors", + }, +}); + +const authLevelToText = (authLevel: AuthorizationLevel) => { + switch (authLevel) { + case AuthorizationLevel.Admin: + return AdminOnboardingText; + case AuthorizationLevel.Mentor: + return MentorOnboardingText; + default: + return MenteeOnboardingText; + } +}; + +interface OnboardingContextType { + switchingRoutes: boolean; + OnboardingComponent: JSX.Element; +} + +const OnboardingContext = createContext( undefined ); const useOnboardingProvider = () => { const currentProfile = useCurrentProfile(); - const [updateProfileMutation] = useUpdateProfileMutation({ + const [updateProfile] = useUpdateProfileMutation({ refetchQueries: ["getMyUser"], }); const authorizationLevel = useAuthorizationLevel(); + const [loading, setLoading] = useState(false); const [currentStep, setCurrentStep] = useState(1); const router = useRouter(); @@ -59,54 +123,55 @@ const useOnboardingProvider = () => { ...currentProfile.currentProfile, showOnboarding: false, }; - updateProfileMutation({ + updateProfile({ variables: { profileId: currentProfile.currentProfile!.profileId, data: updateProfileInput, }, }) - .catch((err) => console.log(err)) .then(() => { - console.log("finished"); - }); - currentProfile.refetchCurrentProfile!(); - LocalStorage.delete("Onboarding Step"); + currentProfile.refetchCurrentProfile!(); + LocalStorage.delete("Onboarding Step"); + }) + .catch((err) => console.error(err)); }; - useEffect(() => { - const onboardingStep = LocalStorage.get("Onboarding Step"); - if (onboardingStep && typeof onboardingStep == "number") - setCurrentStep(onboardingStep); - }, []); - - const props = { + const props: OnboardingProps = { currentStep, setCurrentStep: (num: number) => { - setCurrentStep(num); LocalStorage.set("Onboarding Step", num); + setCurrentStep(num); }, + loading, + setLoading, + onboardingText: authLevelToText(authorizationLevel)(baseRoute), MAX_STEPS, - baseRoute, onFinish, }; - const getOnboardingFromAuthorizationLevel = () => { - switch (authorizationLevel) { - case AuthorizationLevel.Admin: - return ; - case AuthorizationLevel.Mentor: - return <>; - case AuthorizationLevel.Mentee: - return <>; - default: - return <>; + const onboardingStep = LocalStorage.get("Onboarding Step"); + useEffect(() => { + if (onboardingStep && typeof onboardingStep == "number") { + setCurrentStep(onboardingStep); } - }; + }, []); - const OnboardingComponent = getOnboardingFromAuthorizationLevel(); + if ( + authorizationLevel !== AuthorizationLevel.Admin && + router.asPath !== props.onboardingText[currentStep]["route"] && + onboardingStep && + typeof onboardingStep == "number" + ) { + router.push(props.onboardingText[onboardingStep]["route"]); + return { + switchingRoutes: true, + OnboardingComponent: , + }; + } return { - OnboardingComponent, + switchingRoutes: false, + OnboardingComponent: , }; }; diff --git a/src/components/RichTextEditing/PublishButton.tsx b/src/components/RichTextEditing/PublishButton.tsx index 88d49ef4..f3ae16b7 100644 --- a/src/components/RichTextEditing/PublishButton.tsx +++ b/src/components/RichTextEditing/PublishButton.tsx @@ -28,7 +28,7 @@ const PublishButton = ({ programId, ...props }: PublishButtonProps) => { setSnackbarMessage({ text: "Homepage saved!" }); }) .catch((err) => { - console.log("Fail: ", err); + console.error("Fail: ", err); setLoading(false); }); }; diff --git a/src/components/atomic/StepTracker.tsx b/src/components/atomic/StepTracker.tsx index b83419c9..68ac7bc0 100644 --- a/src/components/atomic/StepTracker.tsx +++ b/src/components/atomic/StepTracker.tsx @@ -11,6 +11,7 @@ const StepTracker = ({ steps, currentStep }: StepTrackerProps) => ( {range(1, steps + 1).map((i: number) => { return (
{ setBio(currentProfile.bio || ""); setProfileJson(getResponsesFromJson(currentProfile.profileJson)); setSelectedTagIds(currentProfile.profileTags.map((t) => t.profileTagId)); - - return () => {}; - }, [currentProfile]); + }, []); if (!currentProgram || !currentProfile || !myUserData || !programTagsData) return
404
; diff --git a/src/pages/program/[slug]/[profileRoute]/mentees/edit-profile/index.tsx b/src/pages/program/[slug]/[profileRoute]/mentees/edit-profile/index.tsx index 88cfe7f1..b2007df5 100644 --- a/src/pages/program/[slug]/[profileRoute]/mentees/edit-profile/index.tsx +++ b/src/pages/program/[slug]/[profileRoute]/mentees/edit-profile/index.tsx @@ -26,7 +26,7 @@ const EditMenteeProfilePage: Page = (_) => { const [modified, setModified] = useState(false); const [isSavingProfile, setIsSavingProfile] = useState(false); const { setSnackbarMessage } = useSnackbar(); - isSavingProfile; // TODO: If is saving, set loading state of button to true. + // TODO: If is saving, set loading state of button to true. useEffect(() => { if (!currentProgram) return; @@ -69,7 +69,7 @@ const EditMenteeProfilePage: Page = (_) => {
); From e83a798e6cf3ea005241209e45723e83c96c4118 Mon Sep 17 00:00:00 2001 From: Ashley Date: Sun, 19 Sep 2021 11:00:22 -0700 Subject: [PATCH 5/5] Restructured onboarding to be a component instead of context --- src/components/Onboarding/Onboarding.tsx | 25 ++- .../Onboarding/OnboardingComponent.tsx | 68 ------ .../Onboarding/OnboardingContent.tsx | 198 ++++++++++++++++++ .../Onboarding/OnboardingContext.tsx | 197 ----------------- src/graphql/queries/getMyUser.graphql | 2 +- src/layouts/ChooseTabLayout.tsx | 31 ++- src/layouts/TabLayout/AdminTabLayout.tsx | 3 +- src/layouts/TabLayout/MenteeTabLayout.tsx | 3 +- src/layouts/TabLayout/MentorTabLayout.tsx | 3 +- .../TabLayout/NoMatchingProfileTabLayout.tsx | 2 +- src/layouts/TabLayout/NoProgramTabLayout.tsx | 2 +- src/layouts/TabLayout/TabLayout.tsx | 17 +- src/pages/_app.tsx | 5 +- src/pages/index.tsx | 2 +- .../program/[slug]/[profileRoute]/index.tsx | 2 +- 15 files changed, 256 insertions(+), 304 deletions(-) delete mode 100644 src/components/Onboarding/OnboardingComponent.tsx create mode 100644 src/components/Onboarding/OnboardingContent.tsx delete mode 100644 src/components/Onboarding/OnboardingContext.tsx diff --git a/src/components/Onboarding/Onboarding.tsx b/src/components/Onboarding/Onboarding.tsx index a632e7ff..916c62ce 100644 --- a/src/components/Onboarding/Onboarding.tsx +++ b/src/components/Onboarding/Onboarding.tsx @@ -1,18 +1,22 @@ -import React, { ReactNode } from "react"; +import classNames from "classnames"; +import React, { ReactNode, useState } from "react"; import { Card, Text } from "../atomic"; -import { useOnboarding } from "./OnboardingContext"; +import OnboardingContent from "./OnboardingContent"; -type OnboardingLayoutProps = { +type OnboardingProps = { currentPageChildren: ReactNode; }; -const OnboardingLayout = ({ currentPageChildren }: OnboardingLayoutProps) => { - const { switchingRoutes, OnboardingComponent } = useOnboarding(); +const OnboardingComponent = ({ currentPageChildren }: OnboardingProps) => { + const [switchingRoutes, setSwitchingRoutes] = useState(false); - if (switchingRoutes) return <>; + const onboardingStyles = classNames({ + "flex flex-col h-full w-full bg-tertiary": true, + hidden: switchingRoutes, + }); return ( -
+
{currentPageChildren}
@@ -20,11 +24,14 @@ const OnboardingLayout = ({ currentPageChildren }: OnboardingLayoutProps) => { Welcome to your new program! - {OnboardingComponent} +
); }; -export default OnboardingLayout; +export default OnboardingComponent; diff --git a/src/components/Onboarding/OnboardingComponent.tsx b/src/components/Onboarding/OnboardingComponent.tsx deleted file mode 100644 index bae8a6c5..00000000 --- a/src/components/Onboarding/OnboardingComponent.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useRouter } from "next/router"; -import { Button, Text } from "../atomic"; -import StepTracker from "../atomic/StepTracker"; -import { OnboardingProps } from "./OnboardingContext"; - -const Onboarding = ({ - onFinish, - currentStep, - setCurrentStep, - loading, - setLoading, - onboardingText, - MAX_STEPS, -}: OnboardingProps) => { - const router = useRouter(); - - return ( -
- - {currentStep}) {onboardingText[currentStep]["step"]} - -
-
-
- -
- -
- -
-
- ); -}; - -export default Onboarding; diff --git a/src/components/Onboarding/OnboardingContent.tsx b/src/components/Onboarding/OnboardingContent.tsx new file mode 100644 index 00000000..1b6f5c24 --- /dev/null +++ b/src/components/Onboarding/OnboardingContent.tsx @@ -0,0 +1,198 @@ +import Link from "next/link"; +import { useRouter } from "next/router"; +import React from "react"; +import { + UpdateProfileInput, + useUpdateProfileMutation, +} from "../../generated/graphql"; +import { + AuthorizationLevel, + useAuthorizationLevel, + useCurrentProfile, +} from "../../hooks"; +import LocalStorage from "../../utils/localstorage"; +import { Button, Text } from "../atomic"; +import StepTracker from "../atomic/StepTracker"; + +const ONBOARDING_STEP = "Onboarding Step"; + +type OnboardingText = (baseRoute: string) => { + [key: number]: { step: string; route: string }; +}; + +const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => { + switch (authLevel) { + case AuthorizationLevel.Admin: + return 5; + case AuthorizationLevel.Mentor: + return 2; + case AuthorizationLevel.Mentee: + return 2; + default: + return 0; + } +}; + +const AdminOnboardingText: OnboardingText = (baseRoute: string) => ({ + 1: { + step: "Set up your program homepage", + route: baseRoute, + }, + 2: { + step: "Edit your mentor applications", + route: baseRoute + "/applications/edit-mentor-app", + }, + 3: { + step: "Edit your mentee applications", + route: baseRoute + "/applications/edit-mentee-app", + }, + 4: { + step: "Edit your mentor profile structure", + route: baseRoute + "/mentors/edit-profile", + }, + 5: { + step: "Edit your mentee profile structure", + route: baseRoute + "/mentees/edit-profile", + }, +}); + +const MentorOnboardingText: OnboardingText = (baseRoute: string) => ({ + 1: { + step: "Fill out your profile", + route: baseRoute + "/edit-profile", + }, + 2: { + step: "Set your availability", + route: baseRoute + "/availability", + }, +}); + +const MenteeOnboardingText: OnboardingText = (baseRoute: string) => ({ + 1: { + step: "Fill out your profile", + route: baseRoute + "/edit-profile", + }, + 2: { + step: "Browse through available mentors", + route: baseRoute + "/mentors", + }, +}); + +const authLevelToText = (authLevel: AuthorizationLevel) => { + switch (authLevel) { + case AuthorizationLevel.Admin: + return AdminOnboardingText; + case AuthorizationLevel.Mentor: + return MentorOnboardingText; + default: + return MenteeOnboardingText; + } +}; + +type OnboardingProps = { + switchingRoutes: boolean; + setSwitchingRoutes: (bool: boolean) => void; +}; + +const OnboardingContent = ({ + switchingRoutes, + setSwitchingRoutes, +}: OnboardingProps) => { + const currentProfile = useCurrentProfile(); + const [updateProfile] = useUpdateProfileMutation({ + refetchQueries: ["getMyUser"], + }); + + const authorizationLevel = useAuthorizationLevel(); + const router = useRouter(); + + const MAX_STEPS = authorizationLevelToMaxSteps(authorizationLevel); + const baseRoute = `/program/${router.query.slug}/${router.query.profileRoute}`; + const onboardingText = authLevelToText(authorizationLevel)(baseRoute); + + const onFinish = () => { + const updateProfileInput: UpdateProfileInput = { + onboarded: true, + }; + updateProfile({ + variables: { + profileId: currentProfile.currentProfile!.profileId, + data: updateProfileInput, + }, + }) + .then(() => { + currentProfile.refetchCurrentProfile!(); + LocalStorage.delete(ONBOARDING_STEP); + }) + .catch((err) => console.error(err)); + }; + + const storedStep = LocalStorage.get(ONBOARDING_STEP); + const currentStep = + storedStep && typeof storedStep == "number" ? storedStep : 1; + + //If the user tries to navigate to another route or if they land on a page that isn't the first step + //Return them to the actual page of the current step + if ( + router.asPath !== onboardingText[currentStep]["route"] && + !switchingRoutes + ) { + //Hide content if switching routes + setSwitchingRoutes(true); + router + .push(onboardingText[currentStep]["route"]) + .then(() => setSwitchingRoutes(false)); + } + + const prevStep = Math.max(currentStep - 1, 1); + const nextStep = Math.min(currentStep + 1, MAX_STEPS); + + //Use Links to switch between tabs so that you don't have to wait for router.push + return ( +
+ + {currentStep}) {onboardingText[currentStep]["step"]} + +
+
+
+ +
+ + +
+ +
+
+ ); +}; + +export default OnboardingContent; diff --git a/src/components/Onboarding/OnboardingContext.tsx b/src/components/Onboarding/OnboardingContext.tsx deleted file mode 100644 index bc6c06cf..00000000 --- a/src/components/Onboarding/OnboardingContext.tsx +++ /dev/null @@ -1,197 +0,0 @@ -import { useRouter } from "next/router"; -import React, { createContext, useContext, useEffect, useState } from "react"; -import { - UpdateProfileInput, - useUpdateProfileMutation, -} from "../../generated/graphql"; -import { - AuthorizationLevel, - useAuthorizationLevel, - useCurrentProfile, -} from "../../hooks"; -import OnboardingComponent from "./OnboardingComponent"; -import LocalStorage from "../../utils/localstorage"; - -interface OnboardingText { - [key: number]: { step: string; route: string }; -} - -export interface OnboardingProps { - currentStep: number; - setCurrentStep: (num: number) => void; - loading: boolean; - setLoading: (bool: boolean) => void; - onboardingText: OnboardingText; - MAX_STEPS: number; - onFinish: () => void; -} - -const authorizationLevelToMaxSteps = (authLevel: AuthorizationLevel) => { - switch (authLevel) { - case AuthorizationLevel.Admin: - return 5; - case AuthorizationLevel.Mentor: - return 2; - case AuthorizationLevel.Mentee: - return 2; - default: - return 0; - } -}; - -const AdminOnboardingText = (baseRoute: string) => ({ - 1: { - step: "Set up your program homepage", - route: baseRoute, - }, - 2: { - step: "Edit your mentor applications", - route: baseRoute + "applications/edit-mentor-app", - }, - 3: { - step: "Edit your mentee applications", - route: baseRoute + "applications/edit-mentee-app", - }, - 4: { - step: "Edit your mentor profile structure", - route: baseRoute + "mentors/edit-profile", - }, - 5: { - step: "Edit your mentee profile structure", - route: baseRoute + "mentees/edit-profile", - }, -}); - -const MentorOnboardingText = (baseRoute: string) => ({ - 1: { - step: "Fill out your profile", - route: baseRoute + "edit-profile", - }, - 2: { - step: "Set your availability", - route: baseRoute + "availability", - }, -}); - -const MenteeOnboardingText = (baseRoute: string) => ({ - 1: { - step: "Fill out your profile", - route: baseRoute + "edit-profile", - }, - 2: { - step: "Browse through available mentors", - route: baseRoute + "mentors", - }, -}); - -const authLevelToText = (authLevel: AuthorizationLevel) => { - switch (authLevel) { - case AuthorizationLevel.Admin: - return AdminOnboardingText; - case AuthorizationLevel.Mentor: - return MentorOnboardingText; - default: - return MenteeOnboardingText; - } -}; - -interface OnboardingContextType { - switchingRoutes: boolean; - OnboardingComponent: JSX.Element; -} - -const OnboardingContext = createContext( - undefined -); - -const useOnboardingProvider = () => { - const currentProfile = useCurrentProfile(); - const [updateProfile] = useUpdateProfileMutation({ - refetchQueries: ["getMyUser"], - }); - - const authorizationLevel = useAuthorizationLevel(); - const [loading, setLoading] = useState(false); - const [currentStep, setCurrentStep] = useState(1); - const router = useRouter(); - - const MAX_STEPS = authorizationLevelToMaxSteps(authorizationLevel); - const baseRoute = `/program/${router.query.slug}/${router.query.profileRoute}/`; - - const onFinish = () => { - const updateProfileInput: UpdateProfileInput = { - ...currentProfile.currentProfile, - showOnboarding: false, - }; - updateProfile({ - variables: { - profileId: currentProfile.currentProfile!.profileId, - data: updateProfileInput, - }, - }) - .then(() => { - currentProfile.refetchCurrentProfile!(); - LocalStorage.delete("Onboarding Step"); - }) - .catch((err) => console.error(err)); - }; - - const props: OnboardingProps = { - currentStep, - setCurrentStep: (num: number) => { - LocalStorage.set("Onboarding Step", num); - setCurrentStep(num); - }, - loading, - setLoading, - onboardingText: authLevelToText(authorizationLevel)(baseRoute), - MAX_STEPS, - onFinish, - }; - - const onboardingStep = LocalStorage.get("Onboarding Step"); - useEffect(() => { - if (onboardingStep && typeof onboardingStep == "number") { - setCurrentStep(onboardingStep); - } - }, []); - - if ( - authorizationLevel !== AuthorizationLevel.Admin && - router.asPath !== props.onboardingText[currentStep]["route"] && - onboardingStep && - typeof onboardingStep == "number" - ) { - router.push(props.onboardingText[onboardingStep]["route"]); - return { - switchingRoutes: true, - OnboardingComponent: , - }; - } - - return { - switchingRoutes: false, - OnboardingComponent: , - }; -}; - -export const OnboardingProvider = ({ - children, -}: { - children: React.ReactNode; -}) => { - const value = useOnboardingProvider(); - return ( - - {children} - - ); -}; - -export const useOnboarding = () => { - const context = useContext(OnboardingContext); - if (context === undefined) { - throw new Error("useOnboarding() must be within OnboardingProvider"); - } - return context; -}; diff --git a/src/graphql/queries/getMyUser.graphql b/src/graphql/queries/getMyUser.graphql index d79a013a..38b63fea 100644 --- a/src/graphql/queries/getMyUser.graphql +++ b/src/graphql/queries/getMyUser.graphql @@ -12,7 +12,7 @@ query getMyUser { profileJson tagsJson bio - showOnboarding + onboarded program { programId name diff --git a/src/layouts/ChooseTabLayout.tsx b/src/layouts/ChooseTabLayout.tsx index 53a004b7..73039a85 100644 --- a/src/layouts/ChooseTabLayout.tsx +++ b/src/layouts/ChooseTabLayout.tsx @@ -1,11 +1,16 @@ import { useRouter } from "next/router"; import React, { Fragment } from "react"; -import { AuthorizationLevel, useAuthorizationLevel } from "../hooks"; +import { + AuthorizationLevel, + useAuthorizationLevel, + useCurrentProfile, +} from "../hooks"; import { parseParam } from "../utils"; import { MAP_PROFILETYPE_TO_ROUTE } from "../utils/constants"; import { AdminTabLayout, MenteeTabLayout, MentorTabLayout } from "./TabLayout"; import NoMatchingProfileLayout from "./TabLayout/NoMatchingProfileTabLayout"; import { BaseTabLayoutProps } from "./TabLayout/TabLayout"; +import OnboardingComponent from "../components/Onboarding/Onboarding"; const NotInProgramTabLayout: React.FC = ({ children, @@ -25,10 +30,11 @@ function getTabLayout( return MenteeTabLayout; case AuthorizationLevel.Admin: return AdminTabLayout; - case AuthorizationLevel.NoMatchingProfile: - return NoMatchingProfileLayout; - default: + case AuthorizationLevel.Unauthenticated: + case AuthorizationLevel.Unverified: return NotInProgramTabLayout; + default: + return NoMatchingProfileLayout; } } @@ -49,16 +55,29 @@ interface ChooseTabLayoutProps { const ChooseTabLayout = ({ children }: ChooseTabLayoutProps) => { const router = useRouter(); const slug = parseParam(router.query.slug); + const currentProfile = useCurrentProfile(); const authorizationLevel = useAuthorizationLevel(); const TabLayout = getTabLayout(authorizationLevel); - return ( - {children} + {/* If the user is in a program right now as a mentor, mentee, or admin, + Check for onboarding */} + {currentProfile.currentProfile?.onboarded !== undefined && + !currentProfile.currentProfile.onboarded && + getAuthRoute(authorizationLevel) ? ( + + ) : ( + children + )} ); }; diff --git a/src/layouts/TabLayout/AdminTabLayout.tsx b/src/layouts/TabLayout/AdminTabLayout.tsx index f84de9f6..58498899 100644 --- a/src/layouts/TabLayout/AdminTabLayout.tsx +++ b/src/layouts/TabLayout/AdminTabLayout.tsx @@ -12,10 +12,11 @@ const { PageItem, Dropdown, Separator } = TabLayout; const AdminTabLayout: React.FC = ({ children, + onboarded, basePath, }) => { return ( - + = ({ children, + onboarded, basePath, }) => { return ( - + = ({ children, + onboarded, basePath, }) => { return ( - + = ({ }); return ( - +
{ diff --git a/src/layouts/TabLayout/NoProgramTabLayout.tsx b/src/layouts/TabLayout/NoProgramTabLayout.tsx index 28c49fe2..bca6961d 100644 --- a/src/layouts/TabLayout/NoProgramTabLayout.tsx +++ b/src/layouts/TabLayout/NoProgramTabLayout.tsx @@ -18,7 +18,7 @@ const NoProgramTabLayout: React.FC = ({ children }) => { } return ( - + ); diff --git a/src/layouts/TabLayout/TabLayout.tsx b/src/layouts/TabLayout/TabLayout.tsx index 29c05ce5..70fdc475 100644 --- a/src/layouts/TabLayout/TabLayout.tsx +++ b/src/layouts/TabLayout/TabLayout.tsx @@ -3,9 +3,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import React, { ReactNode, useEffect, useState } from "react"; import { Text } from "../../components/atomic"; -import OnboardingScreen from "../../components/Onboarding/Onboarding"; import TabFooterMenu from "../../components/TabFooterMenu"; -import { useCurrentProfile } from "../../hooks"; import LocalStorage from "../../utils/localstorage"; import ProgramDropdown from "./ProgramDropdown"; @@ -48,6 +46,7 @@ const Arrow: React.FC = ({ down }) => { export interface BaseTabLayoutProps { children: React.ReactNode; + onboarded: boolean; basePath: string; } @@ -66,6 +65,7 @@ export function joinPath(...args: string[]): string { } interface TabLayoutProps { + onboarded: boolean; currentPageChildren: ReactNode; footerChildren?: ReactNode; } @@ -77,14 +77,11 @@ const TabLayout: React.FC & { label: string; Icon: React.FC>; }>; -} = ({ children, currentPageChildren }) => { - const currentProfile = useCurrentProfile(); - +} = ({ children, onboarded, currentPageChildren }) => { const tabLayoutStyles = classNames({ "flex flex-col flex-grow h-screen bg-white shadow-lg relative box-border": true, - "pointer-events-none bg-black opacity-25": - currentProfile.currentProfile?.showOnboarding, + "pointer-events-none bg-black opacity-25": !onboarded, }); return ( @@ -96,11 +93,7 @@ const TabLayout: React.FC & {
- {currentProfile.currentProfile?.showOnboarding ? ( - - ) : ( - currentPageChildren - )} + {currentPageChildren}
); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index fbcce0c8..67490ef6 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -12,7 +12,6 @@ import { ReactElement } from "react"; import "tailwindcss/tailwind.css"; import AuthLoadingScreen from "../layouts/AuthLoadingScreen"; import { AuthProvider } from "../utils/firebase/auth"; -import { OnboardingProvider } from "../components/Onboarding/OnboardingContext"; import { SnackbarProvider } from "../notifications/SnackbarContext"; import "../styles/globals.css"; import Page from "../types/Page"; @@ -69,9 +68,7 @@ function MyApp({ Component, pageProps }: CustomAppProps) { - - {getLayout(, pageProps)} - + {getLayout(, pageProps)} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 4b640ceb..6f5e338c 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -337,7 +337,7 @@ const NoMentorshipHome: Page = () => { } return ( - +
diff --git a/src/pages/program/[slug]/[profileRoute]/index.tsx b/src/pages/program/[slug]/[profileRoute]/index.tsx index d1a48d1a..21579d0f 100644 --- a/src/pages/program/[slug]/[profileRoute]/index.tsx +++ b/src/pages/program/[slug]/[profileRoute]/index.tsx @@ -124,7 +124,7 @@ const AdminHome = ({ {name} -
+