Skip to content

Commit 76bbd0d

Browse files
committed
refactor(frontend): improve onboarding tour state management
- Update `onboardingTourAtom` type to include `isCompleted` flag - Modify tour completion logic to use atom state instead of localStorage - Add `canTourBeStarted` check to control tour initialization - Refactor tour restart mechanism in profile settings page
1 parent 96aa6cb commit 76bbd0d

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed

apps/frontend/app/lib/state/general.tsx

+16-9
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,24 @@ export enum OnboardingTourStepTargets {
6565
}
6666

6767
const onboardingTourAtom = atomWithStorage<
68+
| undefined
6869
| {
6970
isLoading?: true;
71+
isCompleted?: true;
7072
currentStepIndex: number;
7173
}
72-
| undefined
7374
>("OnboardingTour", undefined);
7475

75-
export const OnboardingTourCompletedKey = "OnboardingTourCompleted";
76-
7776
export const useOnboardingTour = () => {
7877
const [tourState, setTourState] = useAtom(onboardingTourAtom);
7978
const { setOpenedSidebarLinks } = useOpenedSidebarLinks();
8079
const isTourStarted = isNumber(tourState?.currentStepIndex);
8180
const theme = useMantineTheme();
8281
const isMobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
82+
8383
const isTourLoading = tourState?.isLoading;
84+
const canTourBeStarted =
85+
typeof tourState === "undefined" || tourState.isCompleted;
8486

8587
const deployBackgroundJobMutation = useMutation({
8688
mutationFn: async () => {
@@ -96,8 +98,11 @@ export const useOnboardingTour = () => {
9698
};
9799

98100
const completeTour = () => {
99-
setTourState(undefined);
100-
localStorage.setItem(OnboardingTourCompletedKey, "true");
101+
setTourState(
102+
produce(tourState, (draft) => {
103+
if (draft) draft.isCompleted = true;
104+
}),
105+
);
101106
window.location.href = "/";
102107
};
103108

@@ -250,20 +255,22 @@ export const useOnboardingTour = () => {
250255
content: <StepWrapper>{step.content}</StepWrapper>,
251256
}));
252257
const isOnLastTourStep =
253-
tourState?.currentStepIndex === onboardingTourSteps.length;
258+
tourState?.currentStepIndex === onboardingTourSteps.length &&
259+
!tourState?.isCompleted;
254260

255261
useEffect(() => {
256262
if (typeof isMobile === "undefined" || isMobile) return;
257263

258-
const completed = localStorage.getItem(OnboardingTourCompletedKey);
259-
if (!completed && !isTourStarted) startTour();
260-
}, [isMobile]);
264+
if (canTourBeStarted && !isTourStarted) startTour();
265+
}, [isMobile, canTourBeStarted]);
261266

262267
return {
268+
startTour,
263269
completeTour,
264270
isTourStarted,
265271
advanceTourStep,
266272
isOnLastTourStep,
273+
canTourBeStarted,
267274
onboardingTourSteps,
268275
currentTourStepIndex: tourState?.currentStepIndex,
269276
};

apps/frontend/app/routes/_dashboard.settings.profile-and-sharing.tsx

+20-17
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import {
6262
useDashboardLayoutData,
6363
useUserDetails,
6464
} from "~/lib/hooks";
65-
import { OnboardingTourCompletedKey } from "~/lib/state/general";
65+
import { useOnboardingTour } from "~/lib/state/general";
6666
import {
6767
createToastHeaders,
6868
getDecodedJwt,
@@ -177,6 +177,7 @@ export default function Page() {
177177
createAccessLinkModalOpened,
178178
{ open: openCreateAccessLinkModal, close: closeCreateAccessLinkModal },
179179
] = useDisclosure(false);
180+
const { canTourBeStarted, startTour } = useOnboardingTour();
180181

181182
const isEditDisabled = dashboardData.isDemoInstance;
182183
const defaultAccountLink = loaderData.userAccessLinks.find(
@@ -251,22 +252,24 @@ export default function Page() {
251252
</Button>
252253
</Stack>
253254
</Form>
254-
<ClientOnly>
255-
{() => (
256-
<>
257-
<Divider />
258-
<Button
259-
variant="default"
260-
onClick={() => {
261-
localStorage.removeItem(OnboardingTourCompletedKey);
262-
window.location.href = "/";
263-
}}
264-
>
265-
Restart onboarding
266-
</Button>
267-
</>
268-
)}
269-
</ClientOnly>
255+
{canTourBeStarted ? (
256+
<ClientOnly>
257+
{() => (
258+
<>
259+
<Divider />
260+
<Button
261+
variant="default"
262+
onClick={() => {
263+
startTour();
264+
window.location.href = "/";
265+
}}
266+
>
267+
Restart onboarding
268+
</Button>
269+
</>
270+
)}
271+
</ClientOnly>
272+
) : null}
270273
</Stack>
271274
</Tabs.Panel>
272275
<Tabs.Panel value="sharing">

0 commit comments

Comments
 (0)