'use client'; import React, { useState, useEffect } from 'react'; import { useRecordMode } from './RecordModeContext'; import { Reorder, AnimatePresence, LazyMotion } from 'framer-motion'; import { Play, Square, MousePointer2, Scroll, Plus, Save, Trash2, Eye, Edit2, X, Check, Download, Settings2, GripVertical, Clock, Maximize2, Box, ExternalLink, } from 'lucide-react'; import { RecordEvent } from '@/types/record-mode'; import { PlaybackCursor } from './PlaybackCursor'; export function RecordModeOverlay() { const { isActive, setIsActive, events, addEvent, updateEvent, removeEvent, isPlaying, playEvents, saveSession, clearEvents, reorderEvents, setHoveredEventId, setEvents, // Added setEvents here } = useRecordMode(); const [pickingMode, setPickingMode] = useState<'mouse' | 'scroll' | null>(null); const [lastInteractionType, setLastInteractionType] = useState<'click' | 'hover'>('click'); const [hoveredElement, setHoveredElement] = useState(null); const [editingEventId, setEditingEventId] = useState(null); // Edit form state const [editForm, setEditForm] = useState>({}); const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); useEffect(() => { if (!mounted || !isActive) return; const handleMessage = (e: MessageEvent) => { if (e.data.type === 'ELEMENT_SELECTED') { const { selector, rect, tagName } = e.data; if (pickingMode === 'mouse') { addEvent({ type: 'mouse', interactionType: lastInteractionType, selector, duration: lastInteractionType === 'click' ? 1000 : 1500, zoom: 1, description: `Mouse ${lastInteractionType === 'click' ? '(Click)' : '(Hover)'} on ${tagName}`, motionBlur: false, realClick: false, rect, }); } else if (pickingMode === 'scroll') { addEvent({ type: 'scroll', selector, duration: 1500, zoom: 1, description: `Scroll to ${tagName}`, motionBlur: false, rect, }); } setPickingMode(null); } else if (e.data.type === 'PICKING_CANCELLED') { setPickingMode(null); } }; window.addEventListener('message', handleMessage); if (pickingMode) { // Find the iframe and signal start picking const iframe = document.querySelector('iframe'); if (iframe?.contentWindow) { iframe.contentWindow.postMessage({ type: 'START_PICKING', mode: pickingMode }, '*'); } } else { // Signal stop picking const iframe = document.querySelector('iframe'); if (iframe?.contentWindow) { iframe.contentWindow.postMessage({ type: 'STOP_PICKING' }, '*'); } } return () => { window.removeEventListener('message', handleMessage); }; }, [isActive, pickingMode, addEvent, mounted]); const saveEdit = () => { if (editingEventId) { updateEvent(editingEventId, editForm); setEditingEventId(null); } }; const [showEvents, setShowEvents] = useState(true); if (!mounted) return null; if (!isActive) { // Failsafe: Never render host toggle in embedded mode if ( typeof window !== 'undefined' && (window.self !== window.top || window.name === 'record-mode-iframe' || window.location.search.includes('embedded=true')) ) { return null; } return ( ); } return ( import('@/lib/framer-features').then(res => res.default)}>
{/* 1. Global Toolbar - Slim Industrial Bar */}
{/* Identity Tag */}
Event Builder Manual Mode
{/* Action Tools */}
{/* Sequence Controls */}
{/* 2. Event Timeline Popover */} {showEvents && (

Recording Track

{events.length} Actions Recorded

{events.length === 0 ? (

Timeline is empty

) : ( events.map((event, index) => ( setHoveredEventId(event.id)} onMouseLeave={() => setHoveredEventId(null)} >
{event.type === 'mouse' ? `Mouse (${event.interactionType})` : event.type} {event.clickOrigin && event.clickOrigin !== 'center' && event.interactionType === 'click' && ( {event.clickOrigin} )} {event.duration}ms

{event.selector || 'system:wait'}

)) )}
)} {/* Industrial Selector Highlighter - handled inside iframe via PickingHelper */} {/* Picking Tooltip */} {pickingMode && (
Assigning {pickingMode}
)} {/* 3. Event Options Panel (Sidebar-like) */} {editingEventId && (

Event Options

{/* Type Display */}
{/* Precise Click Origin */} {editForm.type === 'mouse' && editForm.interactionType === 'click' && (
{[ { id: 'top-left', label: 'TL' }, { id: 'top-right', label: 'TR' }, { id: 'center', label: 'CTR' }, { id: 'bottom-left', label: 'BL' }, { id: 'bottom-right', label: 'BR' }, ].map((origin) => ( ))}
)} {/* Timing */}
setEditForm((prev) => ({ ...prev, duration: parseInt(e.target.value) })) } className="w-full h-1 bg-white/10 rounded-lg appearance-none cursor-pointer accent-accent" />
{/* Zoom & Effects */}
Zoom Shift
setEditForm((prev) => ({ ...prev, zoom: parseFloat(e.target.value) })) } className="w-16 bg-white/10 border border-white/10 rounded-lg px-2 py-1 text-xs text-white text-center font-mono" />
{editForm.type === 'mouse' && editForm.interactionType === 'click' && ( )}
)}
); }