From 80f44eba59046ac1e5fbd2750dbd5be02ed185b6 Mon Sep 17 00:00:00 2001 From: Eric Lay Date: Wed, 11 Mar 2026 08:40:31 -0500 Subject: [PATCH] Add src/components/dashboard/GuidedTour.jsx --- src/components/dashboard/GuidedTour.jsx | 241 ++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 src/components/dashboard/GuidedTour.jsx diff --git a/src/components/dashboard/GuidedTour.jsx b/src/components/dashboard/GuidedTour.jsx new file mode 100644 index 0000000..a7f5aec --- /dev/null +++ b/src/components/dashboard/GuidedTour.jsx @@ -0,0 +1,241 @@ +import React, { useState, useEffect, useCallback } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { X, ChevronRight, ChevronLeft, Sparkles } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +const tourSteps = [ + { + targetId: "user-menu-btn", + title: "User Actions & Account Controls", + description: "This area contains your account actions and user controls. Access your profile, contact support, manage store information, and sign out from here.", + position: "bottom-right", + }, + { + targetId: "notifications-btn", + title: "Notifications & Alerts", + description: "This bell icon is your notification center. You'll receive important system alerts, bulletins, program updates, and action items here. Unread notifications are shown with a red badge count.", + position: "bottom-right", + }, + { + targetId: "dashboard-main", + title: "Your Performance Dashboard", + description: "This is your main dashboard — track parcels received, consolidations completed, financial earnings, and compliance events all in one place.", + position: "center", + }, + { + targetId: "sidebar", + title: "Navigation & Settings", + description: "Use the sidebar to navigate between Program Management, Communication & Support, and Member Management. Access your profile and Stripe Connect settings here.", + position: "right", + }, + { + targetId: null, + title: "Complete Your Stripe Onboarding", + description: "You're almost done! The final step is to set up your Stripe Express account so you can receive electronic program payouts from PackageHub.", + position: "center", + isFinal: true, + }, +]; + +export default function GuidedTour({ onComplete }) { + const [currentStep, setCurrentStep] = useState(0); + const [spotlightRect, setSpotlightRect] = useState(null); + const [tooltipStyle, setTooltipStyle] = useState({}); + + const calculatePosition = useCallback(() => { + const step = tourSteps[currentStep]; + if (!step.targetId) { + setSpotlightRect(null); + setTooltipStyle({ + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + }); + return; + } + + const el = document.getElementById(step.targetId); + if (!el) { + setSpotlightRect(null); + return; + } + + const rect = el.getBoundingClientRect(); + const padding = 8; + setSpotlightRect({ + top: rect.top - padding, + left: rect.left - padding, + width: rect.width + padding * 2, + height: rect.height + padding * 2, + }); + + // Calculate tooltip position + let style = {}; + if (step.position === "bottom-right") { + style = { + top: rect.bottom + 16, + right: window.innerWidth - rect.right, + }; + } else if (step.position === "right") { + style = { + top: rect.top + 60, + left: rect.right + 16, + }; + } else { + style = { + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + }; + } + setTooltipStyle(style); + }, [currentStep]); + + useEffect(() => { + calculatePosition(); + window.addEventListener("resize", calculatePosition); + return () => window.removeEventListener("resize", calculatePosition); + }, [calculatePosition]); + + const step = tourSteps[currentStep]; + const isLast = currentStep === tourSteps.length - 1; + const isFirst = currentStep === 0; + + return ( +
+ {/* Dark overlay with spotlight cutout */} + + + + + {spotlightRect && ( + + )} + + + + + + {/* Spotlight glow ring */} + {spotlightRect && ( + + )} + + {/* Tooltip */} + + +
+ {/* Step indicator row */} +
+
+ + + Step {currentStep + 1} of {tourSteps.length} + +
+ +
+ + {/* Logo */} +
+ PackageHub Business Centers +
+ + {/* Body */} +
+

{step.title}

+

{step.description}

+
+ + {/* Progress dots */} +
+ {tourSteps.map((_, i) => ( +
+ ))} +
+ + {/* Actions */} +
+
+ {!isFirst && ( + + )} + +
+
+
+ + +
+ ); +} \ No newline at end of file