Add guided tour feature with Driver.js
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled

- Install driver.js package for lightweight product tours
- Create GuidedTour component with bilingual tour steps (Chinese/English)
- Create TourPromptModal to ask users if they want a tour after welcome
- Add data-tour attributes to Toolbar, FilePanel, PedigreeCanvas, PropertyPanel
- Tour covers: file operations, adding persons, canvas usage, relationships,
  editing properties, and exporting

Tour flow:
1. First visit: Welcome Modal → Tour Prompt Modal → Start tour or skip
2. Subsequent visits: No modals shown

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gbanyan
2025-12-22 21:33:26 +08:00
parent fb0be3964f
commit ed492c1874
11 changed files with 383 additions and 6 deletions

View File

@@ -11,10 +11,13 @@ import { PropertyPanel } from '../PropertyPanel/PropertyPanel';
import { RelationshipPanel } from '../RelationshipPanel/RelationshipPanel';
import { FilePanel } from '../FilePanel/FilePanel';
import { WelcomeModal } from '../WelcomeModal/WelcomeModal';
import { TourPromptModal } from '../TourPromptModal/TourPromptModal';
import { useGuidedTour } from '../GuidedTour/useGuidedTour';
import { usePedigreeStore, useTemporalStore } from '@/store/pedigreeStore';
import styles from './App.module.css';
const WELCOME_DISMISSED_KEY = 'pedigree-draw-welcome-dismissed';
const TOUR_COMPLETED_KEY = 'pedigree-draw-tour-completed';
export function App() {
const {
@@ -26,13 +29,36 @@ export function App() {
} = usePedigreeStore();
const temporal = useTemporalStore();
// Guided tour hook
const { startTour } = useGuidedTour();
// Welcome modal state - check localStorage on init
const [showWelcome, setShowWelcome] = useState(() => {
return localStorage.getItem(WELCOME_DISMISSED_KEY) !== 'true';
});
// Tour prompt modal state - show after welcome if tour not completed
const [showTourPrompt, setShowTourPrompt] = useState(false);
const handleCloseWelcome = () => {
setShowWelcome(false);
// Show tour prompt if tour hasn't been completed yet
if (localStorage.getItem(TOUR_COMPLETED_KEY) !== 'true') {
setShowTourPrompt(true);
}
};
const handleStartTour = () => {
setShowTourPrompt(false);
// Small delay to let modal close before tour starts
setTimeout(() => {
startTour();
}, 100);
};
const handleSkipTour = () => {
setShowTourPrompt(false);
localStorage.setItem(TOUR_COMPLETED_KEY, 'true');
};
// Keyboard shortcuts
@@ -99,6 +125,9 @@ export function App() {
</footer>
{showWelcome && <WelcomeModal onClose={handleCloseWelcome} />}
{showTourPrompt && (
<TourPromptModal onStartTour={handleStartTour} onSkip={handleSkipTour} />
)}
</div>
);
}