'use client' import { useState, useEffect } from 'react' import { motion, AnimatePresence } from 'motion/react' import { useSession } from 'next-auth/react' import { usePathname } from 'next/navigation' import { Slash, Sparkles, History, GraduationCap, Link2, PenLine, FlipVertical, Keyboard, Lightbulb, ArrowRight, FileDown, Network, Zap, RefreshCw, X, ChevronLeft, ChevronRight, } from 'lucide-react' import { useLanguage } from '@/lib/i18n' import type { LucideIcon } from 'lucide-react' // ── Types ────────────────────────────────────────────────────────────────── interface HintDef { icon: LucideIcon color: string bg: string key: string } interface RouteHintSet { hints: HintDef[] storageKey: string } // ── Hint definitions per route ───────────────────────────────────────────── // Every item here maps to a real, verified UI element or gesture in the codebase. const ROUTE_HINTS: Record = { '/home': { storageKey: 'momento_hints_home', hints: [ { icon: PenLine, color: 'text-violet-500', bg: 'bg-violet-500/10', key: 'create_note' }, { icon: Slash, color: 'text-indigo-500', bg: 'bg-indigo-500/10', key: 'slash' }, { icon: Sparkles, color: 'text-amber-500', bg: 'bg-amber-500/10', key: 'ai' }, { icon: History, color: 'text-blue-500', bg: 'bg-blue-500/10', key: 'version' }, { icon: Link2, color: 'text-rose-500', bg: 'bg-rose-500/10', key: 'links' }, { icon: GraduationCap, color: 'text-emerald-500',bg: 'bg-emerald-500/10',key: 'flashcards' }, ], }, '/revision': { storageKey: 'momento_hints_revision', hints: [ { icon: FlipVertical, color: 'text-violet-500', bg: 'bg-violet-500/10', key: 'flip' }, { icon: Keyboard, color: 'text-blue-500', bg: 'bg-blue-500/10', key: 'rate_keys' }, { icon: GraduationCap,color: 'text-emerald-500',bg: 'bg-emerald-500/10',key: 'generate_from_note' }, ], }, '/brainstorm': { storageKey: 'momento_hints_brainstorm', hints: [ { icon: Lightbulb, color: 'text-amber-500', bg: 'bg-amber-500/10', key: 'brainstorm_start' }, { icon: ArrowRight, color: 'text-violet-500',bg: 'bg-violet-500/10', key: 'brainstorm_deepen' }, { icon: FileDown, color: 'text-blue-500', bg: 'bg-blue-500/10', key: 'brainstorm_export' }, ], }, '/insights': { storageKey: 'momento_hints_insights', hints: [ { icon: Network, color: 'text-violet-500', bg: 'bg-violet-500/10', key: 'insights_clusters' }, { icon: Zap, color: 'text-amber-500', bg: 'bg-amber-500/10', key: 'insights_bridge' }, { icon: RefreshCw, color: 'text-blue-500', bg: 'bg-blue-500/10', key: 'insights_refresh' }, ], }, } function getRouteSet(pathname: string): RouteHintSet | null { // Exact match first if (ROUTE_HINTS[pathname]) return ROUTE_HINTS[pathname] // Prefix match (e.g. /brainstorm?session=xxx) for (const route of Object.keys(ROUTE_HINTS)) { if (pathname.startsWith(route)) return ROUTE_HINTS[route] } return null } // ── Component ────────────────────────────────────────────────────────────── export function OnboardingEditorHints() { const { data: session } = useSession() const pathname = usePathname() const { t } = useLanguage() const [visible, setVisible] = useState(false) const [index, setIndex] = useState(0) const [routeKey, setRouteKey] = useState(null) const user = session?.user as any // When route changes, check if we should show hints for the new page useEffect(() => { if (!session) return if (user?.onboardingCompleted !== false) return const routeSet = getRouteSet(pathname) if (!routeSet) { setVisible(false) return } if (typeof window !== 'undefined' && localStorage.getItem(routeSet.storageKey)) { setVisible(false) return } // Reset to first hint when page changes setIndex(0) setRouteKey(pathname) const timer = setTimeout(() => setVisible(true), 900) return () => clearTimeout(timer) }, [pathname, session, user?.onboardingCompleted]) // Hide when hints change (route switch) useEffect(() => { if (routeKey !== null && routeKey !== pathname) { setVisible(false) } }, [pathname, routeKey]) function dismiss() { const routeSet = getRouteSet(pathname) if (routeSet && typeof window !== 'undefined') { localStorage.setItem(routeSet.storageKey, '1') } setVisible(false) } const routeSet = getRouteSet(pathname) if (!routeSet) return null const hints = routeSet.hints const hint = hints[Math.min(index, hints.length - 1)] const Icon = hint.icon return ( {visible && ( {/* Header */}

{t('onboarding.editor_hints_title')}

{/* Hint content */}

{t(`onboarding.hint_${hint.key}_title`)}

{t(`onboarding.hint_${hint.key}_desc`)}

{/* Navigation */}
{/* Dots */}
{hints.map((_, i) => (
{/* Arrows + dismiss */}
{index < hints.length - 1 ? ( ) : ( )}
)}
) }