diff --git a/src/App.tsx b/src/App.tsx index 1e9fe41..43d89cb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -219,6 +219,17 @@ export default function App() { }, 1200); }; + const handleImportWorkspace = (importedBlocks: Block[]) => { + if (Array.isArray(importedBlocks) && importedBlocks.length > 0) { + setBlocks(importedBlocks); + setSelectedBlockId(importedBlocks[0].id); + setActiveParentId(null); + showToast('Workspace imported successfully!', 'success'); + } else { + showToast('Invalid workspace file format.', 'error'); + } + }; + const handleNewFlowchart = () => { setBlocks([]); setSelectedBlockId(null); @@ -249,6 +260,7 @@ export default function App() { onSave={handleSaveWorkspace} onLoad={handleLoadWorkspace} onExport={handleExportFile} + onImportWorkspace={handleImportWorkspace} onNewFlowchart={handleNewFlowchart} onAddFirstBlock={() => { setBlocks(initialDemoBlocks); diff --git a/src/components/CenterCanvas.tsx b/src/components/CenterCanvas.tsx index b975324..efa56ad 100644 --- a/src/components/CenterCanvas.tsx +++ b/src/components/CenterCanvas.tsx @@ -17,7 +17,8 @@ import { Database, ZoomIn, ZoomOut, - FilePlus + FilePlus, + Upload } from 'lucide-react'; import { toPng } from 'html-to-image'; import { jsPDF } from 'jspdf'; @@ -32,6 +33,7 @@ interface CenterCanvasProps { onSave: () => void; onLoad: () => void; onExport: (format: 'png' | 'pdf' | 'pptx') => void; + onImportWorkspace: (importedBlocks: Block[]) => void; onNewFlowchart: () => void; onAddFirstBlock: () => void; showToast?: (message: string, type?: 'success' | 'info' | 'error') => void; @@ -44,6 +46,7 @@ export default function CenterCanvas({ onSave, onLoad, onExport, + onImportWorkspace, onNewFlowchart, onAddFirstBlock, showToast, @@ -61,6 +64,35 @@ export default function CenterCanvas({ const [isPanning, setIsPanning] = useState(false); const [showConfirmModal, setShowConfirmModal] = useState(false); const panStart = useRef({ x: 0, y: 0 }); + const fileInputRef = useRef(null); + + const handleFileImportChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = (event) => { + try { + const text = event.target?.result as string; + const parsed = JSON.parse(text); + + let blocksToImport: Block[] = []; + if (Array.isArray(parsed)) { + blocksToImport = parsed; + } else if (parsed && Array.isArray(parsed.blueprint)) { + blocksToImport = parsed.blueprint; + } else { + throw new Error("Invalid structure"); + } + + onImportWorkspace(blocksToImport); + } catch (err) { + showToast?.('Error parsing file: ' + err, 'error'); + } + }; + reader.readAsText(file); + e.target.value = ''; + }; // Mouse pan event handlers const handleMouseDown = (e: React.MouseEvent) => { @@ -340,6 +372,13 @@ export default function CenterCanvas({ return (
+ {/* Top Toolbar */}
@@ -372,6 +411,16 @@ export default function CenterCanvas({ Load + +