import { useEffect, useRef, useState } from 'react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { Switch } from '@/components/ui/switch'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; import { GripVertical, Undo, Move, Maximize2 } from 'lucide-react'; import { useMockupStore } from '@/contexts/MockupContext'; interface PositionScalePanelProps { onClose: () => void; } export const PositionScalePanel: React.FC = ({ onClose }) => { const { devicePosition, updateDevicePosition, fixedMargin, setFixedMargin, margin, setMargin, } = useMockupStore(); const [isDragging, setIsDragging] = useState(false); const [windowPosition, setWindowPosition] = useState({ x: 200, y: 100 }); const [scale, setScale] = useState(() => devicePosition.scale); const [activeTab, setActiveTab] = useState('position'); const [marginPreset, setMarginPreset] = useState('medium'); const windowRef = useRef(null); const dragStartRef = useRef({ x: 0, y: 0 }); const gridRef = useRef(null); 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]); const handleFixedMarginToggle = (checked) => { setFixedMargin(checked) handleMarginPresetChange('medium') } const handleBallClick = (e: React.MouseEvent, ballIndex: number) => { e.preventDefault(); if (!gridRef.current) return; const rect = gridRef.current.getBoundingClientRect(); const ballElement = e.currentTarget as HTMLElement; const ballRect = ballElement.getBoundingClientRect(); const ballCenterX = ballRect.left + ballRect.width / 2 - rect.left; const ballCenterY = ballRect.top + ballRect.height / 2 - rect.top; const ballRadius = 25; const gridWidth = rect.width; const gridHeight = rect.height; const deviceX = ((ballCenterX - ballRadius) / (gridWidth - ballRadius * 2)) * 400 - 200; const deviceY = ((ballCenterY - ballRadius) / (gridHeight - ballRadius * 2)) * 400 - 200; updateDevicePosition({ x: deviceX, y: deviceY }); }; const resetPosition = () => { setScale(1); updateDevicePosition({ x: 0, y: 0, scale: 1 }); setFixedMargin(false); setMargin({ top: 35, right: 35, bottom: 35, left: 35 }); setMarginPreset('medium'); }; const handleMarginPresetChange = (preset: string) => { if (!preset) return; setMarginPreset(preset); let marginValue; switch (preset) { case 'small': marginValue = 20; break; case 'medium': marginValue = 35; break; case 'large': marginValue = 50; break; default: marginValue = 35; } setMargin({ top: marginValue, right: marginValue, bottom: marginValue, left: marginValue }); }; const positionBalls = [ { style: { left: '25px', top: '25px' } }, { style: { right: '25px', top: '25px' } }, { style: { left: '25px', bottom: '25px' } }, { style: { right: '25px', bottom: '25px' } }, { style: { left: '50%', top: '25px', transform: 'translateX(-50%)' } }, { style: { left: '50%', bottom: '25px', transform: 'translateX(-50%)' } }, { style: { left: '25px', top: '50%', transform: 'translateY(-50%)' } }, { style: { right: '25px', top: '50%', transform: 'translateY(-50%)' } }, { style: { left: '50%', top: '50%', transform: 'translate(-50%, -50%)' } }, ]; return (
Position / Scale
Position Margins
{positionBalls.map((ball, index) => (
handleBallClick(e, index)} /> ))}
Scale {scale.toFixed(1)}x
{ setScale(value[0]); updateDevicePosition({ scale: value[0] }); }} min={0.1} max={3} step={0.1} />
Fixed Margin
{fixedMargin && (
Small Medium Large
Top Margin {Math.round(margin.top)}
{ setMargin({ ...margin, top: value[0] }); setMarginPreset(''); }} min={0} max={100} step={1} />
Right Margin {Math.round(margin.right)}
{ setMargin({ ...margin, right: value[0] }); setMarginPreset(''); }} min={0} max={100} step={1} />
Bottom Margin {Math.round(margin.bottom)}
{ setMargin({ ...margin, bottom: value[0] }); setMarginPreset(''); }} min={0} max={100} step={1} />
Left Margin {Math.round(margin.left)}
{ setMargin({ ...margin, left: value[0] }); setMarginPreset(''); }} min={0} max={100} step={1} />
)}
); };