/** * VoiceTutorial - First-time user onboarding for the voice assistant. * * Presents a multi-step tutorial with: * - Welcome and overview of voice capabilities * - Interactive sample commands to try * - Tips on language support and advanced features * - Remembers completion state via localStorage */ import { useState, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { MicrophoneIcon, ChatBubbleLeftRightIcon, LanguageIcon, SparklesIcon, ChevronRightIcon, ChevronLeftIcon, XMarkIcon, } from "@heroicons/react/24/outline"; import PropTypes from "prop-types"; import { markTutorialShown } from "@services/voiceService"; import { LANGUAGES } from "@utils/constants"; // --------------------------------------------------------------------------- // Tutorial Steps // --------------------------------------------------------------------------- const STEPS = [ { icon: MicrophoneIcon, title: { [LANGUAGES.EN]: "Voice Commands", [LANGUAGES.HI]: "वॉयस कमांड", }, description: { [LANGUAGES.EN]: "Tap the microphone button and speak a command. FarmHelp will recognize your voice and navigate to the right page.", [LANGUAGES.HI]: "माइक्रोफ़ोन बटन दबाएं और कमांड बोलें। FarmHelp आपकी आवाज़ पहचानकर सही पेज पर ले जाएगा।", }, tryCommands: { [LANGUAGES.EN]: ["weather", "show prices", "detect disease"], [LANGUAGES.HI]: ["मौसम बताओ", "भाव बताओ", "रोग पहचानो"], }, color: "primary", }, { icon: ChatBubbleLeftRightIcon, title: { [LANGUAGES.EN]: "Smart Conversations", [LANGUAGES.HI]: "स्मार्ट बातचीत", }, description: { [LANGUAGES.EN]: "Open the chat panel for multi-turn conversations. Ask about specific crops, locations, or diseases and the assistant will remember context.", [LANGUAGES.HI]: "चैट पैनल खोलें बहु-चरण बातचीत के लिए। विशिष्ट फसलों, स्थानों या रोगों के बारे में पूछें और सहायक संदर्भ याद रखेगा।", }, tryCommands: { [LANGUAGES.EN]: [ "show wheat prices", "weather tomorrow", "how to treat paddy blast", ], [LANGUAGES.HI]: [ "गेहूं का भाव", "कल का मौसम", "धान ब्लास्ट का इलाज", ], }, color: "accent", }, { icon: LanguageIcon, title: { [LANGUAGES.EN]: "Hindi and English", [LANGUAGES.HI]: "हिंदी और अंग्रेजी", }, description: { [LANGUAGES.EN]: "Speak in English or Hindi. The assistant understands both languages and will respond in your preferred language.", [LANGUAGES.HI]: "अंग्रेजी या हिंदी में बोलें। सहायक दोनों भाषाएं समझता है और आपकी पसंदीदा भाषा में जवाब देगा।", }, tryCommands: { [LANGUAGES.EN]: ["help", "मदद"], [LANGUAGES.HI]: ["help", "मदद"], }, color: "secondary", }, { icon: SparklesIcon, title: { [LANGUAGES.EN]: "Customize Settings", [LANGUAGES.HI]: "सेटिंग्स बदलें", }, description: { [LANGUAGES.EN]: "In the chat panel, tap the gear icon to adjust speech rate, voice preference, and auto-speak settings.", [LANGUAGES.HI]: "चैट पैनल में, गियर आइकन दबाकर बोलने की गति, आवाज़ की पसंद और स्वतः बोलने की सेटिंग्स बदलें।", }, tryCommands: null, color: "primary", }, ]; const COLOR_MAP = { primary: { bg: "bg-primary-50", icon: "text-primary-600 bg-primary-100", badge: "bg-primary-100 text-primary-700", dot: "bg-primary-600", button: "bg-primary-600 hover:bg-primary-700", }, accent: { bg: "bg-accent-50", icon: "text-accent-600 bg-accent-100", badge: "bg-accent-100 text-accent-700", dot: "bg-accent-600", button: "bg-accent-600 hover:bg-accent-700", }, secondary: { bg: "bg-secondary-50", icon: "text-secondary-600 bg-secondary-100", badge: "bg-secondary-100 text-secondary-700", dot: "bg-secondary-600", button: "bg-secondary-600 hover:bg-secondary-700", }, }; // --------------------------------------------------------------------------- // Animation Variants // --------------------------------------------------------------------------- const STEP_VARIANTS = { enter: (direction) => ({ x: direction > 0 ? 80 : -80, opacity: 0, }), center: { x: 0, opacity: 1, }, exit: (direction) => ({ x: direction > 0 ? -80 : 80, opacity: 0, }), }; // --------------------------------------------------------------------------- // Component // --------------------------------------------------------------------------- function VoiceTutorial({ isOpen, onClose, language }) { const [currentStep, setCurrentStep] = useState(0); const [direction, setDirection] = useState(1); const lang = language || LANGUAGES.EN; const totalSteps = STEPS.length; const step = STEPS[currentStep]; const colors = COLOR_MAP[step.color] || COLOR_MAP.primary; const IconComponent = step.icon; const isLastStep = currentStep === totalSteps - 1; const handleNext = useCallback(() => { if (isLastStep) { markTutorialShown(); onClose(); return; } setDirection(1); setCurrentStep((prev) => prev + 1); }, [isLastStep, onClose]); const handlePrev = useCallback(() => { if (currentStep > 0) { setDirection(-1); setCurrentStep((prev) => prev - 1); } }, [currentStep]); const handleSkip = useCallback(() => { markTutorialShown(); onClose(); }, [onClose]); if (!isOpen) return null; return (
{step.description[lang] || step.description[LANGUAGES.EN]}
{/* Try commands */} {step.tryCommands && ({lang === LANGUAGES.HI ? "यह बोलकर देखें:" : "Try saying:"}