-
+
{step === 2 && Ячеек: {parts.length}}
{step < 3 ? (
) : (
diff --git a/src/components/LayoutStep.tsx b/src/components/LayoutStep.tsx
index 8c396eb..d4b1fc8 100644
--- a/src/components/LayoutStep.tsx
+++ b/src/components/LayoutStep.tsx
@@ -1,7 +1,6 @@
import React, { useRef, useState, useMemo } from 'react';
import { AppConfig, LayoutSplits, Partition } from '../types';
-// ИСПОЛЬЗУЕМ ТОЛЬКО 4 БАЗОВЫЕ ИКОНКИ, ЧТОБЫ ИСКЛЮЧИТЬ ОШИБКИ
-import { Grid, Trash2, X, Plus } from 'lucide-react';
+import { Grid, MousePointer2, Trash2, RotateCcw, X, Plus } from 'lucide-react';
interface Props {
config: AppConfig;
@@ -13,28 +12,29 @@ type EditMode = 'lines' | 'cells';
type Axis = 'x' | 'y';
export const LayoutStep: React.FC
= ({ config, splits, onChange }) => {
+ // DEBUG LOGGING
+ console.log("LayoutStep Render. Config:", config, "Splits:", splits);
+
const svgRef = useRef(null);
-
- // Режим работы
const [mode, setMode] = useState('lines');
- // Состояния
const [phantomAxis, setPhantomAxis] = useState(null);
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
const [hoveredSplit, setHoveredSplit] = useState<{ axis: Axis; index: number } | null>(null);
const [dragging, setDragging] = useState<{ axis: Axis; index: number } | null>(null);
const [isButtonHovered, setIsButtonHovered] = useState(false);
-
- // Редактируемая ячейка
const [editingCell, setEditingCell] = useState<{ i: number, j: number } | null>(null);
- // --- ЗАЩИТА ДАННЫХ ---
- // Если что-то пришло undefined, подменяем на пустые значения
+ // DATA SAFETY CHECKS
+ if (!config || !config.drawer) {
+ console.error("LayoutStep: Config is missing!");
+ return Config Error: Missing configuration
;
+ }
+
const safeX = Array.isArray(splits?.x) ? splits.x : [];
const safeY = Array.isArray(splits?.y) ? splits.y : [];
const safePartitions = splits?.partitions || {};
- // Защита от деления на ноль при расчете пропорций
const width = Math.max(1, config.drawer.width || 300);
const depth = Math.max(1, config.drawer.depth || 400);
@@ -42,20 +42,23 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => {
const aspectRatio = depth / width;
const viewBoxH = viewBoxW * aspectRatio;
+ // LOG CALCULATIONS
+ if (isNaN(viewBoxH) || !isFinite(viewBoxH)) {
+ console.error("LayoutStep: Invalid Dimensions", { width, depth, aspectRatio });
+ return Error: Invalid Dimensions ({width}x{depth})
;
+ }
+
const sortedX = useMemo(() => [0, ...safeX, 1].sort((a, b) => a - b), [safeX]);
const sortedY = useMemo(() => [0, ...safeY, 1].sort((a, b) => a - b), [safeY]);
- // --- ЛОГИКА ---
+ // Handlers
const addPartition = (axis: 'x' | 'y') => {
if (!editingCell) return;
const key = `${editingCell.i}-${editingCell.j}`;
const current = safePartitions[key] || [];
const newPart: Partition = {
id: Math.random().toString(36).substr(2, 9),
- axis,
- offset: 0.5,
- height: config.drawer.height || 80,
- rounded: false
+ axis, offset: 0.5, height: config.drawer.height || 80, rounded: false
};
onChange({ ...splits, partitions: { ...safePartitions, [key]: [...current, newPart] } });
};
@@ -75,7 +78,6 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => {
onChange({ ...splits, partitions: { ...safePartitions, [key]: current.filter(p => p.id !== id) } });
};
- // --- MOUSE HANDLERS ---
const handleGlobalMouseMove = (e: React.MouseEvent) => {
if (!svgRef.current) return;
const rect = svgRef.current.getBoundingClientRect();
@@ -83,7 +85,6 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => {
const nx = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
const ny = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
-
setMousePos({ x: nx, y: ny });
if (mode === 'lines') {
@@ -96,20 +97,15 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => {
}
if (isButtonHovered) return;
setHoveredSplit(null);
-
- // Фантомная линия
+
const SNAP = 0.02;
if (nx > SNAP && nx < 1-SNAP && ny > SNAP && ny < 1-SNAP) {
- // Простая проверка, не слишком ли близко к другим линиям
const closeToX = safeX.some(val => Math.abs(nx - val) < SNAP);
const closeToY = safeY.some(val => Math.abs(ny - val) < SNAP);
-
if (!closeToX && !closeToY) {
const distRight = 1 - nx; const distBottom = 1 - ny;
setPhantomAxis(Math.min(nx, distRight) < Math.min(ny, distBottom) ? 'y' : 'x');
- } else {
- setPhantomAxis(null);
- }
+ } else { setPhantomAxis(null); }
}
}
};
@@ -142,58 +138,38 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => {
return (
-
- {/* HEADER */}
2. Макет
-
-
-
+
+
-
- {/* Кнопка сброса */}
-
+
- {/* DEBUG INFO (Если вдруг снова пусто - увидим это) */}
-
- {width}x{depth} | X:{safeX.length} Y:{safeY.length}
+
+
+ {mode === 'lines' ? 'Границы' : 'Ячейки'}
+
+
{mode === 'lines' ? 'Клик: создать. Драг: двигать.' : 'Кликни по ячейке для настройки.'}
- {/* Rulers */}
- 0
- {width} мм
+ 0{width} мм
- 0
- {depth} мм
+ 0{depth} мм
- {/* SVG */}
- {/* --- EDITOR PANEL --- */}
{mode === 'cells' && editingCell && (
Редактор ячейки
-
-
-
+
+
-
{(safePartitions[`${editingCell.i}-${editingCell.j}`] || []).map((p, idx) => (
-
- Стенка #{idx+1} ({p.axis === 'x' ? 'Верт' : 'Гориз'})
-
+ Стенка #{idx+1} ({p.axis === 'x' ? 'Верт' : 'Гориз'})