diff --git a/package-lock.json b/package-lock.json
index 5b6dfa2..176bf91 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"d3": "^7.9.0",
+ "driver.js": "^1.4.0",
"html-to-image": "^1.11.13",
"react": "^19.2.0",
"react-dom": "^19.2.0",
@@ -2672,6 +2673,12 @@
"robust-predicates": "^3.0.2"
}
},
+ "node_modules/driver.js": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/driver.js/-/driver.js-1.4.0.tgz",
+ "integrity": "sha512-Gm64jm6PmcU+si21sQhBrTAM1JvUrR0QhNmjkprNLxohOBzul9+pNHXgQaT9lW84gwg9GMLB3NZGuGolsz5uew==",
+ "license": "MIT"
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.267",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
diff --git a/package.json b/package.json
index 831eb55..cda3bb2 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
},
"dependencies": {
"d3": "^7.9.0",
+ "driver.js": "^1.4.0",
"html-to-image": "^1.11.13",
"react": "^19.2.0",
"react-dom": "^19.2.0",
diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx
index 0fa1453..9347269 100644
--- a/src/components/App/App.tsx
+++ b/src/components/App/App.tsx
@@ -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() {
{showWelcome && }
+ {showTourPrompt && (
+
+ )}
);
}
diff --git a/src/components/FilePanel/FilePanel.tsx b/src/components/FilePanel/FilePanel.tsx
index f55d04a..99a841b 100644
--- a/src/components/FilePanel/FilePanel.tsx
+++ b/src/components/FilePanel/FilePanel.tsx
@@ -125,7 +125,7 @@ export function FilePanel() {
}, [createNewPedigree]);
return (
-
+
File Operations
@@ -163,7 +163,7 @@ export function FilePanel() {
Export
-
+