perfect-postcode/frontend/src/hooks/useTutorial.ts

91 lines
2.7 KiB
TypeScript

import { useState, useCallback, useMemo } from 'react';
import type { Step, CallBackProps } from 'react-joyride';
import { ACTIONS, EVENTS, STATUS } from 'react-joyride';
const STORAGE_KEY = 'tutorial_completed';
const STEPS: Step[] = [
{
target: '[data-tutorial="filters"]',
title: 'Filter Properties',
content:
'Use filters to narrow down to areas which contain matching properties. Filter by crime rate, number of schools around, or filter to an area with detached houses. Pin a filter with the eye icon to colour the map by that feature.',
placement: 'right',
disableBeacon: true,
},
{
target: '[data-tutorial="map"]',
title: 'Explore the Map',
content:
'Pan and zoom to explore property data across England. Click any area (hexagon or postcode boundary) to see detailed stats of historical or currently sold properties matching your filters.',
placement: 'bottom',
disableBeacon: true,
},
{
target: '[data-tutorial="search"]',
title: 'Search Locations',
content:
'Search for a place name or postcode to jump directly to that area on the map.',
placement: 'bottom',
disableBeacon: true,
},
{
target: '[data-tutorial="right-pane"]',
title: 'Area Stats & Properties',
content:
'After clicking a hexagon, view aggregated area statistics or browse individual properties in this pane.',
placement: 'left',
disableBeacon: true,
},
{
target: '[data-tutorial="poi-button"]',
title: 'Points of Interest',
content:
'Toggle points of interest like schools, shops, and transport stops to see what amenities are nearby.',
placement: 'left',
disableBeacon: true,
styles: {
tooltip: {
transform: 'translateY(-50px)',
},
},
},
];
export function useTutorial(initialLoading: boolean, isMobile: boolean) {
const [run, setRun] = useState(() => {
if (isMobile) return false;
return !localStorage.getItem(STORAGE_KEY);
});
const shouldRun = run && !initialLoading && !isMobile;
const handleCallback = useCallback((data: CallBackProps) => {
const { status, action, type } = data;
if (status === STATUS.FINISHED || status === STATUS.SKIPPED) {
localStorage.setItem(STORAGE_KEY, '1');
setRun(false);
}
// Also stop if user closes a tooltip via the X button
if (action === ACTIONS.CLOSE && type === EVENTS.STEP_AFTER) {
localStorage.setItem(STORAGE_KEY, '1');
setRun(false);
}
}, []);
const resetTutorial = useCallback(() => {
localStorage.removeItem(STORAGE_KEY);
setRun(true);
}, []);
return useMemo(
() => ({
steps: STEPS,
run: shouldRun,
handleCallback,
resetTutorial,
}),
[shouldRun, handleCallback, resetTutorial]
);
}