import React, { useState, useRef, useEffect } from 'react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { GripVertical, Undo, FlipHorizontal, FlipVertical, RotateCw, Move3D, ArrowUp } from 'lucide-react'; import { useMockupStore } from '@/contexts/MockupContext'; interface RotationSkewPanelProps { onClose: () => void; } export const RotationSkewPanel: React.FC = ({ onClose }) => { // 2. Select only the state and actions this component needs from the store. // This is more performant than pulling the entire state. const rotation3D = useMockupStore((state) => state.rotation3D); const set3DRotation = useMockupStore((state) => state.set3DRotation); // Local component state remains the same const [isDragging, setIsDragging] = useState(false); const [windowPosition, setWindowPosition] = useState({ x: 100, y: 100 }); const windowRef = useRef(null); const dragStartRef = useRef({ x: 0, y: 0 }); // Window dragging logic remains unchanged const handleWindowDragStart = (e: React.MouseEvent) => { e.preventDefault(); setIsDragging(true); dragStartRef.current = { x: e.clientX - windowPosition.x, y: e.clientY - windowPosition.y }; }; const handleWindowDrag = (e: MouseEvent) => { if (!isDragging) return; setWindowPosition({ x: e.clientX - dragStartRef.current.x, y: e.clientY - dragStartRef.current.y }); }; const handleWindowDragEnd = () => { setIsDragging(false); }; useEffect(() => { if (isDragging) { window.addEventListener('mousemove', handleWindowDrag); window.addEventListener('mouseup', handleWindowDragEnd); return () => { window.removeEventListener('mousemove', handleWindowDrag); window.removeEventListener('mouseup', handleWindowDragEnd); }; } }, [isDragging]); // 3. Update action calls to use the new Zustand actions directly. const handleRotationChange = (type: 'rotateX' | 'rotateY' | 'rotateZ' | 'skew', value: number[]) => { // OLD: dispatch({ type: 'SET_3D_ROTATION', payload: { [type]: value[0] } }); set3DRotation({ [type]: value[0] }); }; const resetRotation = () => { // OLD: dispatch({ type: 'SET_3D_ROTATION', payload: { rotateX: 0, rotateY: 0, rotateZ: 0, skew: 0 } }); set3DRotation({ rotateX: 0, rotateY: 0, rotateZ: 0, skew: 0 }); }; const presets = [ { rotateX: 20, rotateY: 0, rotateZ: 0, skew: 0 }, { rotateX: 30, rotateY: -15, rotateZ: 25, skew: 0 }, { rotateX: 0, rotateY: 0, rotateZ: 15, skew: 0 }, { rotateX: -20, rotateY: 0, rotateZ: 0, skew: 0 }, { rotateX: 0, rotateY: -20, rotateZ: 0, skew: 0 }, { rotateX: 0, rotateY: 0, rotateZ: -15, skew: 0 }, ]; return (
Rotation & Skew
{/* 4. Update state access to use the selected state directly (no more 'state.' prefix) */}
handleRotationChange('rotateX', value)} min={-45} max={45} step={1} />
{rotation3D.rotateX}
handleRotationChange('rotateY', value)} min={-45} max={45} step={1} />
{rotation3D.rotateY}
handleRotationChange('rotateZ', value)} min={-180} max={180} step={1} />
{rotation3D.rotateZ}
handleRotationChange('skew', value)} min={0} max={45} step={1} />
{rotation3D.skew}
{presets.map((preset, index) => ( ))}
); };