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] ); }