From cf09961807098ffcc684e0e0736ba0e7945938fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=B0=D0=BB=D0=B8=D0=BC=D0=BE=D0=B2=20=D0=A0=D1=83?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BC?= Date: Sat, 10 Jan 2026 17:23:27 +0300 Subject: [PATCH] Add logs --- src/App.tsx | 98 ++++++++++++++++++------ src/components/LayoutStep.tsx | 138 +++++++++++----------------------- 2 files changed, 119 insertions(+), 117 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7212f18..fb01df7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,12 +5,50 @@ import { ConfigStep } from './components/ConfigStep'; import { LayoutStep } from './components/LayoutStep'; import { PreviewStep } from './components/PreviewStep'; import { parseShareUrl } from './utils/share'; -import { ChevronRight, ChevronLeft, Box } from 'lucide-react'; +import { ChevronRight, ChevronLeft, Box, AlertTriangle } from 'lucide-react'; + +// --- ERROR BOUNDARY (Ловец ошибок) --- +class ErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean, error: string}> { + constructor(props: any) { + super(props); + this.state = { hasError: false, error: '' }; + } + + static getDerivedStateFromError(error: any) { + return { hasError: true, error: error.toString() }; + } + + componentDidCatch(error: any, errorInfo: any) { + console.error("CRITICAL UI ERROR:", error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+

+ Что-то сломалось в этом компоненте +

+
+            {this.state.error}
+          
+ +
+ ); + } + return this.props.children; + } +} const App = () => { const [step, setStep] = useState(1); + const [isLoadedFromUrl, setIsLoadedFromUrl] = useState(false); - // Инициализация конфига const [config, setConfig] = useState({ drawer: { width: 300, depth: 400, height: 80 }, wallThickness: 1.2, @@ -18,34 +56,44 @@ const App = () => { cornerRadius: 4, }); - // Инициализация splits с пустой структурой const [splits, setSplits] = useState({ x: [], y: [], partitions: {} }); + // Логируем состояние при каждом изменении + useEffect(() => { + console.log("APP STATE UPDATE:", { step, splits, config }); + }, [step, splits, config]); + useEffect(() => { try { - const sharedData = parseShareUrl(); - if (sharedData) { - setConfig(sharedData.config); - // Жесткое приведение типов, чтобы избежать undefined - setSplits({ - x: Array.isArray(sharedData.splits.x) ? sharedData.splits.x : [], - y: Array.isArray(sharedData.splits.y) ? sharedData.splits.y : [], - partitions: sharedData.splits.partitions || {} - }); - setStep(3); - window.history.replaceState({}, '', window.location.pathname); - } - } catch(e) { - console.error("URL Error", e); + const sharedData = parseShareUrl(); + if (sharedData) { + console.log("Loaded from URL:", sharedData); + setConfig(sharedData.config); + setSplits({ + x: Array.isArray(sharedData.splits.x) ? sharedData.splits.x : [], + y: Array.isArray(sharedData.splits.y) ? sharedData.splits.y : [], + partitions: sharedData.splits.partitions || {} + }); + setStep(3); + setIsLoadedFromUrl(true); + window.history.replaceState({}, '', window.location.pathname); + } + } catch (e) { + console.error("Url Parse Error", e); } }, []); const parts: GeneratedPart[] = useMemo(() => { - return calculateParts(config, splits); + try { + return calculateParts(config, splits); + } catch(e) { + console.error("Geometry Calc Error:", e); + return []; + } }, [config, splits]); return ( @@ -61,7 +109,6 @@ const App = () => {

Генератор органайзеров

- {/* Step Indicator */}
{[1, 2, 3].map((num) => (
@@ -82,8 +129,15 @@ const App = () => { {step === 2 && (
- {/* Передаем key для принудительного пересоздания компонента */} - + {/* Оборачиваем LayoutStep в ErrorBoundary */} + + +
)} @@ -97,7 +151,7 @@ const App = () => {